How do I connect a Lambda function to a dedicated VPC?

Last updated: 2021-04-28

I want to connect an AWS Lambda function to resources in a dedicated virtual private cloud (VPC). How do I set that up?

Short description

Lambda doesn't support running functions in dedicated tenancy VPCs. To connect a Lambda function to a dedicated VPC, first peer the dedicated VPC to a default tenancy VPC that contains the function.

The solution requires using an Amazon Elastic Compute Cloud (Amazon EC2) Dedicated Instance. Note that your AWS account incurs charges for this instance. For more information on Amazon EC2 instance tenancy and VPCs, see Dedicated Instance basics.

Resolution

Note: The following procedure requires you to understand Node.js and how to create a Lambda function.

Create and configure a default tenancy VPC and a dedicated tenancy VPC

Note: If you choose to use different CIDR blocks than the ones provided, make sure that the two VPCs have different, non-overlapping blocks.

1.    In the Amazon VPC console, create a default tenancy VPC that has the following settings:
For IPv4 CIDR block, enter 12.0.0.0/16.
For Tenancy, choose Default.

2.    Create a dedicated tenancy VPC that has the following settings:
For IPv4 CIDR block, enter 11.0.0.0/16.
For Tenancy, choose Dedicated.

3.    Create an internet gateway and attach it to your dedicated tenancy VPC.
Note: The internet gateway is required for the HTTP server that you'll create later, in the Test connectivity section. For more information, see Enabling internet access.

4.    Create subnets in each of your VPCs. For your default tenancy VPC, create two or more subnets across different Availability Zones.
Note: Creating more than one subnet across different Availability Zones is a best practice for redundancy. Doing this also allows Lambda to provide high availability for your function. For multiple subnets in each VPC, use a subset of the VPC's CIDR block. If you create one subnet only in a VPC, then you can use the same CIDR block as the VPC. For more information, see VPC and subnet sizing for IPv4.

5.    Create a VPC peering connection between the two VPCs that you created. On the Create Peering Connection page, do the following:
(Optional) For Peering connection name tag, enter a name for the VPC peering connection.
For VPC (Requester), choose the default tenancy VPC that you created.
For Account, make sure that My account is selected.
For Region, make sure that This region is selected.
For VPC (Accepter), choose the dedicated tenancy VPC that you created.
Choose Create Peering Connection.

6.    Accept the VPC peering connection.

7.    Add routes to each of your new VPCs' route tables as shown in the following examples. When creating the route tables, make sure that you do the following:
For the Target values starting with pcx-..., choose Peering Connection. Then, choose the peering connection that you created.
For the Target value starting with igw-..., choose Internet Gateway. Then, choose the internet gateway that you created.

For more information, see Adding and removing routes from a route table.

Example default tenancy VPC route table

Destination

Target

Status

Propagated

12.0.0.0/16

Local Active No

11.0.0.0/16

pcx-1a2b3c4d5e6f7g8h9

Active

No

Example dedicated tenancy VPC route table

Destination

Target

Status

Propagated

11.0.0.0/16

Local

Active

No

12.0.0.0/16

pcx-1a2b3c4d5e6f7g8h9

Active

No

0.0.0.0/0 igw-12345678a90b12c34 Active No

Create a Lambda execution role for Amazon VPC

Note: If you already have a Lambda execution role for Amazon VPC access, skip this section.

1.    In the AWS Identity and Access Management (IAM) console, in the left navigation pane, choose Roles.

2.    In the Roles pane, choose Create role.

3.    On the Create role page, do the following:
For Select type of trusted entity, choose AWS service.
For Choose the service that will use this role, choose Lambda.
Choose Next: Permissions.

4.    For Attach permissions policies, search for AWSLambdaVPCAccessExecutionRole. Choose the policy with that name, and then choose Next: Tags.

5.    (Optional) Add tags that allow you to identify and organize the new resource.

6.    For Review, enter the following:
For Role name, enter a name for the Lambda execution role. For example, lambda_vpc_basic_execution.
(Optional) For Role description, edit the description.
Choose Create role.

Create a new Lambda function for testing

Create a new function using the Lambda console or by building and uploading your own deployment package. When you create the new function, make sure that you do the following:

  • Create the function in the same AWS Region as your default tenancy VPC.
  • Attach the execution role that you created (for example, lambda_vpc_basic_execution) to the function.

Example function code that uses the native HTTP interface in Node.js

var http = require('http')
     
exports.handler = (event, context, callback) => {
    const options = {
        hostname: event.Host,
        port: event.Port
    }
    
    const response = {};
    
   http.get(options, (res) => {
        response.httpStatus = res.statusCode
        callback(null, response)
    }).on('error', (err) =>{
        callback(null, err.message);
    })
   
};

Connect your Lambda function to your VPC

1.    In the Lambda console, on the Configuration tab, choose VPC. Then, choose Edit and do the following:
For Virtual Private Cloud (VPC), choose the default tenancy VPC that you created.
For Subnets, choose two or more subnets in your VPC.
For Security groups, choose a security group.
Note: The default security group is sufficient for most use cases. For more information, see Security groups for your VPC.

2.    Choose Save.

Test connectivity

1.    Launch an EC2 instance in your dedicated tenancy VPC.
Note: To connect to the EC2 instance later, you'll need a public IPv4 address that you can assign during setup. Or, you can associate an elastic IP address with your instance after setup. You must choose an EC2 instance type that's supported as a Dedicated Instance. Note that your AWS account incurs charges for this instance.

2.    Verify that the network access control lists (ACLs) for both VPCs allow traffic for the following:
The port that you're testing (80).
Your dedicated EC2 instance's security group.

3.    Connect to your EC2 instance.

4.    Run the following command to launch an HTTP server on your EC2 instance:

# If python version is 2.x:
$ sudo python -m SimpleHTTPServer 80
# If python version is 3.x
$ sudo python -m http.server 80

5.    In the Lambda console, configure a test event for your function. Use the following example JSON code snippet for your event:

Note: Replace yourHost with the local IP address of your EC2 instance.

{
  "Host": "yourHost",
  "Port": 80
}

6.    In the Lambda console, choose Test.

7.    Choose Details to check the execution result for a 200 response code to confirm that the connection was successful.

Example 200 response code

{
  "statusCode": 200
}

If the function output shows non-nil values for average, max, and min latency, then your VPC peering connection is set up correctly.

Note: If Lambda times out, make sure that your security groups are configured correctly. If you get an ECONNREFUSED error, make sure that your HTTP server is running.