3
votes

I'm invoking the following lambda function to describe an instance information:

'use strict'

var aws = require('aws-sdk');

exports.handler = function(event, context) {
    var instanceID = JSON.parse(event.Records[0].Sns.Message).Trigger.Dimensions[0].value;

    aws.config.region = 'us-east-1';

    var ec2 = new aws.EC2;

    var params = {InstanceIds: [instanceID]};

    ec2.describeInstances(params, function(e, data) {
        if (e)
            console.log(e, e.stack);
        else
            console.log(data);
    }
};

In CloudWatch Logs I can see that function runs until the end, but doesn't log nothing inside ec2.describeInstances method:

END RequestId: xxxxxxxxxxxxxx REPORT RequestId: xxxxxxxxxxxxxx Duration: xx ms Billed Duration: xx ms Memory Size: xx MB Max Memory Used: xx MB

My lambda function has VPC access and IAM Role of AdministratorAccess (full access). For some reason, it can't run ec2.describeInstances method. What is wrong and how can I fix it?

2
Is your EC2 instance in a Private subnet in a VPC?error2007s
Yes, and my lambda function has this subnet in its configuration.Danilo
Did you ever get this resolved? I have the same issue, and none of the answers helpedSlav
Hello. Check @error2007s answer. I resolved this by creating a subnet to NAT and a security group with outbound connections (0.0.0.0/0 and ::/0). Both configured in the lambda.Danilo

2 Answers

3
votes

When you add VPC configuration to a Lambda function, it can only access resources in that VPC. If a Lambda function needs to access both VPC resources and the public Internet, the VPC needs to have a Network Address Translation (NAT) instance inside the VPC. So for that EC2 instance to send logs to cloud watch it needs internet connection through the NAT instance.

AWS Lambda uses the VPC information you provide to set up ENIs that allow your Lambda function to access VPC resources. Each ENI is assigned a private IP address from the IP address range within the Subnets you specify, but is not assigned any public IP addresses. Therefore, if your Lambda function requires Internet access (for example, to access AWS services that don't have VPC endpoints, such as Amazon Cloudwatch), you can configure a NAT instance inside your VPC or you can use the Amazon VPC NAT gateway. For more information, see NAT Gateways in the Amazon VPC User Guide. You cannot use an Internet gateway attached to your VPC, since that requires the ENI to have public IP addresses.

2
votes

First, try giving this role to your Lambda

{
        "Effect": "Allow",
        "Resource": "*",
        "Action": [
            "ec2:DescribeInstances",
            "ec2:CreateNetworkInterface",
            "ec2:AttachNetworkInterface",
            "ec2:DescribeNetworkInterfaces",
            "ec2:DeleteNetworkInterface",
            "ec2:DetachNetworkInterface",
            "ec2:ModifyNetworkInterfaceAttribute",
            "ec2:ResetNetworkInterfaceAttribute",
            "autoscaling:CompleteLifecycleAction"
        ]
    }

If that doesn't make a difference then,

  • you need to create an ENI. Go to the 'Network Interfaces' page https://console.aws.amazon.com/ec2/v2/home#NIC:sort=securityGroup and 'Create Network Interface'. Select the appropriate security groups and the subnet (say s0bn3t).
  • Now, in the "Advanced Settings" of your Lambda, when you select the VPC, you will see a list of subnets. Now, select the subnet that the above ENI is associated with ('s0bn3t').

I believe this should do it.