简体   繁体   中英

Can't run ec2 method in AWS Lambda Function

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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM