1

I am using serverless framework to implement a serverless project. I added some config in my serverless.yml file to create instance for aws elasticsearch service, which is successfully created. Then i created a elasticsearch client in my handler and ping it for testing. So when i ping the elastic search client from serverless offline on my local system, It worked fine and got a 'true' response, but when i deployed the same code on aws lambda than it gets timed out after getting no response till 30 sec.

Have given all policies that can be required but getting no luck.

Serverless.yml:-

ElasticSearchInstance:
  Type: AWS::Elasticsearch::Domain
  Properties:
    EBSOptions:
      EBSEnabled: true
      VolumeType: gp2
      VolumeSize: 10
    ElasticsearchClusterConfig:
      InstanceType: t2.small.elasticsearch
      InstanceCount: 1
      DedicatedMasterEnabled: false
      ZoneAwarenessEnabled: false
    ElasticsearchVersion: 7.1

Handler.js:-

var {Client} = require('elasticsearch');
var client = new Client({
 host: 'Aws elasticsearch endpoint',
 log: 'trace'
});

module.exports.elasticSearchPing = async () => {
  try {
  console.log('Inside elasticSearchPing function!!!!');
  const res = await client.ping({requestTimeout: 900000});
  console.log('Res: ', res);
  return {
  statusCode: 200,
  body: JSON.stringify({ message: 'Connection successful with elasticSearch.' })
 }
} catch (err) {
  console.log('err: ', err);
  return {
    statusCode: err.statusCode || 500,
    headers: { 'Content-Type': 'text/plain' },
    body: 'Error connecting elasticsearch.'
    }
 }
}

1 Answer 1

0

This way there is no way for aws elasticsearch to know who you are. You need to sign your request before sending it to aws elasticsearch. You can use a package called http-aws-es which basicsally reads the aws credentials from your ec2/lambda and signs the request for you. Your code will look like this

const {Client} = require("elasticsearch");
const esConnectionClass = require("http-aws-es");

const client = new Client({
  "host": "Aws elasticsearch endpoint",
  "log": "trace",
  "connectionClass": esConnectionClass
});

module.exports.elasticSearchPing = async () => {
  try {
    console.log("Inside elasticSearchPing function!!!!");
    const res = await client.ping({"requestTimeout": 900000});
    console.log("Res: ", res);
    return {
      "statusCode": 200,
      "body": JSON.stringify({"message": "Connection successful with elasticSearch."})
    };
  } catch (err) {
    console.log("err: ", err);
    return {
      "statusCode": err.statusCode || 500,
      "headers": {"Content-Type": "text/plain"},
      "body": "Error connecting elasticsearch."
    };
  }
};

Sign up to request clarification or add additional context in comments.

3 Comments

I have also tried with the http-aws-es module but it does'nt solves the issue. Actually the problem was with the VPC subnetIds, I am providing the securityGroupIds and subnetIds but when i comment out the subnetIds, it starts working fine, though all my subnetIds are public. Still wonders why this is happenning. Following are the vpc details:- vpc: securityGroupIds: - ${self:custom.secrets.SECURITY_GROUP_ID} # subnetIds: # - ${self:custom.secrets.SUBNET1_ID} # - ${self:custom.secrets.SUBNET2_ID} # - ${self:custom.secrets.SUBNET3_ID}
Is ur es in vpc or available outside vpc as well?
Using VPC for ES

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.