GrantD71
GrantD71

Reputation: 1875

Creating a valid signed request to an AWS ES instance from node.js

I'm trying to find an example of how to connect to an AWS ES instance in node.js, and then hit the ES cluster with a simple request.

I'm attempting to use the elasticsearch node package, along with an open source addon called http-aws-es to do this.

I have configured my aws ES access policy to look like the following:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<account-id>:root"
      },
      "Action": "es:*",
      "Resource": "example-domain.us-east-1.es.amazonaws.com:<account-id>:domain/*"
    },
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Resource": "example-domain.us-east-1.es.amazonaws.com:<account-id>:domain/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "<my-ip>"
        }
      }
    }
  ]
} 

So, I would like to be able to issue put and get requests on the es instance from either an ip address or from an IAM user linked to my aws account.

I have the following code that attempts this in node.js:

var aws_access_key = 'example';
var aws_secret_key = 'key';

var es = require('elasticsearch').Client({
    hosts: 'example-domain.us-east-1.es.amazonaws.com',
    connectionClass: require('http-aws-es'),
    amazonES: {
        region: 'us-east-1',
        accessKey: aws_access_key,
        secretKey: aws_secret_key
    }
});

es.ping({
    // ping usually has a 3000ms timeout
    requestTimeout: Infinity,

    // undocumented params are appended to the query string
    hello: "elasticsearch!"
}, function (error) {
    if (error) {
        console.log(error);
        console.trace('elasticsearch cluster is down!');
    } else {
        console.log('All is well');
    }
});

Which currently returns an authorization error:

{ [Error: Authorization Exception]
  status: 403,
  displayName: 'AuthorizationException',
  message: 'Authorization Exception' }

I've yet to see a working example of using an aws ES instance by using a signed policy in node.js. Anyone have insights?

Upvotes: 4

Views: 2810

Answers (1)

GrantD71
GrantD71

Reputation: 1875

It turns out that I had done almost everything correctly in my question, except for one step.

The IAM user associated with the aws_access_key and aws_secret_key in the code above must have specific permissions to interact with the elastic search instances. So I logged in to the AWS console and added the following policy to the IAM users that would need to interact with the elasticsearch instance

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1480915344000",
            "Effect": "Allow",
            "Action": [
                "es:*"
            ],
            "Resource": [
                "arn:aws:es:us-east-1:<account-id>:domain/*"
            ]
        }
    ]
}

Upvotes: 2

Related Questions