VPC-enabled Lambda function cannot launch/access E

2019-09-19 12:39发布

问题:

I have a VPC enabled Lambda function which attempts to launch an EC2 using a launch template. The EC2 launch step (run_instances) fails with the below generic network error.

Calling the invoke API action failed with this message: Network Error

I can launch an instance successfully directly from the launch template, so I think everything is fine with the launch template. I have configured the following in the launch template

  • Amazon Machine Image ID
  • Instance type
  • Key Pair
  • A network interface (ENI) which I had created before using a specific (VPC, Subnet, Secutity Group) combo.
  • IAM role

The Lambda function includes the below code-

import json
import boto3
import time

def lambda_handler(event, context):
    ec2_cl = boto3.client('ec2')
    launch_temp = {"LaunchTemplateId": "<<Launch Template ID>>"}
    resp_ec2_launch = ec2_cl.run_instances(MaxCount=1, MinCount=1, LaunchTemplate=launch_temp, SubnetId="<<Subnet ID>>")

Few things on the Lambda function-

  • I have used the subnet in the run_instances() call because this is not the default vpc/subnet.
  • The function is setup with the same (VPC, Subnet, Secutity Group) combo as used in the launch template
  • The execution role is setup to be the same IAM role as used in the launch template
  • The function as you see needs access only to the EC2, internet access is not needed
  • I replaced the run_instances() with describe_instance_status (using the instance id created directly from the launch template) and got the same error.

The error is a network error, so I assume all is fine (atleast as of now) with the privileges granted to the IAM role. I'm sure there would be a different error, if the IAM role missed any policies.

Can someone indicate what I might be missing?

回答1:

It appears that the problem is with your AWS Lambda function being able to reach the Internet, since the Amazon EC2 API endpoint is on the Internet.

If a Lambda function is not attached to a VPC, it has automatic access to the Internet.

If a Lambda function is attached to a VPC and requires Internet access, then the configuration should be:

  • Attach the Lambda function only to private subnet(s)
  • Launch a NAT Gateway in a public subnet
  • Configure the Route Table on the private subnets to send Internet-bound traffic (0.0.0.0/0) through the NAT Gateway


回答2:

It appears that your VPC does not have an Internet Gateway, but it does have a VPC Endpoint for EC2.

Therefore, to try and reproduce your situation, I did the following:

  • Created a new VPC with one subnet but no Internet Gateway
  • Added a VPC Endpoint for EC2 to the subnet
  • Created a Lambda function that would call DescribeInstances() and attached the Lambda function to the subnet
  • Opened the security group on the VPC Endpoint and Lambda function to allow all traffic from anywhere (hey, it's just a test!)

My Lambda function:

import json
import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2',region_name='ap-southeast-2')
    print(ec2.describe_instances())

The result: The Lambda function successfully received a response from EC2, with a list of instances in the region. No code or changes were required.