I have an AWS OpenSearch serverless collection setup and a Node.js 18 Lambda using a Lambda Layer to interact with OpenSearch.
I think I am connecting successfully – I can see my client object returning. However, when I attempt to send a document I get a generic response error. Any assistance would be awesome, been wrestling with this for awhile.
layer
const { defaultProvider } = require('@aws-sdk/credential-provider-node');
const { Client } = require('@opensearch-project/opensearch');
const { AwsSigv4Signer } = require('@opensearch-project/opensearch/aws');
const getClient = async (host) => {
const client = new Client({
...AwsSigv4Signer({
region: 'us-west-2',
service: 'aoss',
getCredentials: () => {
const credentialsProvider = defaultProvider();
return credentialsProvider();
}
}),
node: host
});
console.log('layer: getClient: '+JSON.stringify(client));
return client;
};
const addDocToIndex = async function (document, index, host) {
try {
// Get policy number for index
let doc = JSON.parse(document);
doc.id_normalized = doc.id.replace(/\W+/g, "");
// Index document
const client = await getClient(host);
console.log('layer - you are here? '+JSON.stringify(client));
const response = await client.index({
id: doc.id.replace(/\W+/g, ""),
index: index,
body: JSON.stringify(doc),
refresh: true,
});
return Promise.resolve(response);
} catch (err) {
console.error("addDocToIndexError", err);
return Promise.reject(new Error(err.message));
}
};
call from lambda
const payload = await omi_opensearch.addDocToIndex(JSON.stringify(OpenSearchDocument), index, host);
error
2023-09-13T23:10:59.309Z 500603fe-af1f-4131-b79e-002f495bfbc4 ERROR addDocToIndexError ResponseError: Response Error
at onBody (/opt/nodejs/node_modules/opensearch-omi/node_modules/@opensearch-project/opensearch/lib/Transport.js:374:23)
at IncomingMessage.onEnd (/opt/nodejs/node_modules/opensearch-omi/node_modules/@opensearch-project/opensearch/lib/Transport.js:293:11)
at IncomingMessage.emit (node:events:526:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
meta: {
body: '',
statusCode: 401,
headers: {
'x-request-id': '68b079ec-099e-93b0-90c5-cbca21441573',
'x-amzn-aoss-test-account-id': '[AWS ACCOUNT ID]',
'x-amzn-aoss-test-collection-id': '[OPENSEARCH SERVERLESS COLLECTION ID]',
'x-aoss-response-hint': 'X01:network-policy-deny',
date: 'Wed, 13 Sep 2023 23:10:59 GMT',
server: 'aoss-amazon',
'content-length': '0'
},
meta: {
context: null,
request: [Object],
name: 'opensearch-js',
connection: [Object],
attempts: 0,
aborted: false
}
}
}
Update: Since 401 is Unauthorized, here is some of my Terraform creating these resources. I build the encryption, network, & data access policy. Here is the data access resource:
resource "aws_opensearchserverless_access_policy" "cloud_formslibrary_data_pol" {
name = "cloudformslibrarydatapol"
type = "data"
description = "allow index and collection access"
policy = jsonencode([
{
Rules = [
{
ResourceType = "index",
Resource = [
"index/${var.opensearch_serverless_collection}/*"
],
Permission = [
"aoss:*"
]
},
{
ResourceType = "collection",
Resource = [
"collection/${var.opensearch_serverless_collection}"
],
Permission = [
"aoss:*"
]
}
],
Principal = [
data.aws_caller_identity.current.arn,
aws_iam_user.opensearch_user.arn,
module.roles_n_policies.output_roleid, # <--- Lambda's user role
]
}
])
}
section of policy statement related to role->user for Lambda
sid = "ServerlessOpenSearchStatement"
effect = "Allow"
actions = ["aoss:*"]
resources = ["*"]
}