What am I doing wrong trying to add document to OpenSearch index?

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 = ["*"]
    
  }

Leave a Comment