Reputation: 3472
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
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
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