Max Baldwin
Max Baldwin

Reputation: 3472

Elasticsearch npm: Passing AWS Credentials

So I am trying to use the Elasticsearch npm client, but I am having issues with authentication. I am currently using authentication based on an IAM user's identity. For obvious reasons I don't want to move to open security and I would also rather use IAM user's identity over IP-based authentication.

IAM gives a user a username and password that are used as credentials upon the request. I'm not really sure how to pass them and my Elasticsearch server keeps timing out. Here is what I have tried so far. The documentation says to pass it as the auth key in a Client config object. I can confirm that the username and password and correct, and that the endpoint is the one provided by AWS.

aws.js

const elasticsearch = require('elasticsearch');
const envs = require('dotenv').config();

module.exports = function () {
    return new elasticsearch.Client({
        host: [{
            apiVersion: '2.3',
            protocol: 'https',
            auth: `${envs.username}:${envs.password}`,
            host:`${envs.endpoint}`
        }]
    })
}

index.js

const client = require('./aws')();

client.ping({
    // ping usually has a 3000ms timeout
    requestTimeout: Infinity
}, function(error) {
    console.log('pass')
    if (error) {
        console.trace(error);
    } else {
        console.log('All is well');
    }
});

Any questions or comment would be greatly appreciated.

Thanks!

Upvotes: 2

Views: 2959

Answers (2)

Echo Alex
Echo Alex

Reputation: 70

this is the code that worked for me.

const elasticsearch = require('elasticsearch');
var AWS = require('aws-sdk');

var options = {
    host: 'host',
    port:443,
    protocol:'https',
    connectionClass: require('http-aws-es'),
    awsConfig:new AWS.Config({
        credentials: new AWS.Credentials('aws_access_key', 'aws_secret_key'),
        region: 'us-east-1'
    })
};
var client = require('elasticsearch').Client(options);


client.ping({
  // ping usually has a 3000ms timeout
  requestTimeout: 3000
}, function (error) {
  if (error) {
    console.trace('elasticsearch cluster is down!');
  } else {
    console.log('All is well');
  }
});

Upvotes: 1

Max Baldwin
Max Baldwin

Reputation: 3472

Figured this out. For future reference, elasticsearch JS does not have a method for signing for AWS. It only supports SSL signed and basic authentication. Therefore you can use this NPM called http-aws-es. It uses the AWS SDK to sign for Elasticsearch using your IAM access key id and secret access key. Here is what I ended up with for my Elasticsearch client

const elasticsearch = require('elasticsearch');
const AWSConnector = require('http-aws-es'),
const envs = require('dotenv').config();

module.exports = function () {
    return new elasticsearch.Client({
        connectionClass: AWSConnector,
        apiVersion: '2.3',
        port: 443,
        protocol: 'https',
        host:`${envs.endpoint}`,
        amazonES: {
            region: 'us-east-1',
            accessKey: envs.accessKeyId,
            secretKey: envs.secretAccessKey
        }
    })
}

One other thing to note is that I had to set the port to 443. It would be port 80 if the protocol were http. The Elasticsearch JS library defaults to port 9200 for obvious reasons. If you don't specify the port, it will always default to 9200 regardless of the host you add.

Upvotes: 3

Related Questions