How to Assign a Static IP to AWS Lambda for Free
- Published on
- Authors
- Name
- Binh Bui
- @bvbinh
How to Assign a Static IP to AWS Lambda for Free 💸
Quick Overview
In this guide, we will explore a method to assign a static IP to an AWS Lambda function at no cost by leveraging the AWS CDK.
Understanding the Challenge with Lambdas and Static IPs
Assigning a static IP to an AWS Lambda function can often be straightforward with the usual approach. However, the requirement of a NAT Gateway makes it pricey (approximately $30/month). Recently, I came across a fascinating technique that utilizes AWS's underlying resources.
Here's the strategy:
- When you create a Lambda function in a VPC, AWS automatically generates an Elastic Network Interface (ENI).
- We can programmatically retrieve the ENI ID.
- By attaching an Elastic IP to the ENI, we can effectively give the Lambda a static IP.
While this concept from a recent article is brilliant, implementing it through Infrastructure as Code can seem complex. Let’s break it down using the AWS CDK.
Steps for Deploying a Lambda with a Static IP Using ENIs
Step 1: Create a Lambda within a VPC
Begin by creating a Lambda function in a VPC, and ensure that it's located in a public subnet to permit internet access.
import * as cdk from 'aws-cdk-lib';
const vpc = new cdk.aws_ec2.Vpc(this, 'Vpc', { natGateways: 0 });
const securityGroup = new cdk.aws_ec2.SecurityGroup(this, 'SecurityGroup', { vpc });
const lambdaFunction = new cdk.aws_lambda_nodejs.NodejsFunction(this, 'TestFunc', {
vpc,
allowPublicSubnet: true,
vpcSubnets: { subnets: vpc.publicSubnets },
securityGroups: [securityGroup],
});
Make sure to relocate your Lambda to a public subnet if it already exists.
Step 2: Extract the ENI ID
Next, we will retrieve the ENI ID that AWS created automatically for our Lambda function.
const eni = lambdaFunction.connections.securityGroups[0].node.defaultChild as cdk.aws_ec2.CfnNetworkInterface;
This approach might not work directly since the ENI does not exist when the CDK runs. AWS CloudFormation is responsible for creating it during deployment. To work around this, we utilize a custom resource that allows us to execute a Lambda function during deployment to fetch the ENI ID using the AWS SDK. Here's how to set it up:
const customResource = new cdk.custom_resources.AwsCustomResource(this, 'CustomResource', {
onCreate: {
physicalResourceId: cdk.custom_resources.PhysicalResourceId.of(
`${securityGroup.securityGroupId}-${vpc.publicSubnets[0].subnetId}-CustomResource`,
),
service: 'EC2',
action: 'describeNetworkInterfaces',
parameters: {
Filters: [
{ Name: 'interface-type', Values: ['lambda'] },
{ Name: 'group-id', Values: [securityGroup.securityGroupId] },
{ Name: 'subnet-id', Values: [vpc.publicSubnets[0].subnetId] },
],
},
},
policy: cdk.custom_resources.AwsCustomResourcePolicy.fromSdkCalls({ resources: cdk.custom_resources.AwsCustomResourcePolicy.ANY_RESOURCE }),
});
customResource.node.addDependency(lambdaFunction);
const eniId = customResource.getResponseField('NetworkInterfaces.0.NetworkInterfaceId');
This code snippet extracts the ENI ID by filtering for ENIs attached to our Lambda, within the specified security group and public subnet.
Step 3: Attach an Elastic IP to the ENI
With the ENI ID obtained, the next step is to link an Elastic IP to the ENI.
const elasticIP = new cdk.aws_ec2.CfnEIP(this, 'EIP', { domain: 'vpc' });
new cdk.aws_ec2.CfnEIPAssociation(this, 'EIPAssociation', {
networkInterfaceId: eniId,
allocationId: elasticIP.attrAllocationId,
});
Step 4: Integrating Everything
Now that all components are in place, we can deploy a Lambda function with a static IP. This example illustrates the setup for just one public subnet; replicate these steps for any additional public subnets your Lambda may require.
You can access the complete code for further reference.
Key Points
- You can successfully assign a static IP to a Lambda at no cost using ENIs 💸
- Utilizing constructs allows for executing AWS SDK calls during deployment.
Enjoy your cost-free static IP while it lasts; however, keep in mind that starting January 2024, Elastic IPs will incur a fee of $3/month. While this method is excellent for reducing expenses, it's advisable not to use this for production systems, as AWS may change ENI management in the future, potentially disrupting your infrastructure. To avoid such issues, consider setting up a cron job to maintain the ENI.
Tags
freelance-web-development, aws-lambda, static-ip, cloud-infrastructure, cdk, productivity, serverless-architecture