In this tutorial, i am going to show you how to deploy a lambda inside a VPC with a fixed IP using AWS CDK.
The final result will look like this :
Create the project
Let's create a new project :
mkdir lambda-inside-vpc-with-cdk
cd lambda-inside-vpc-with-cdk
npm init -y
CDK part
Let's install AWS CDK
npm install -g aws-cdk
cdk init app --language typescript
We need to use a lambda and a VPC, so let's install the dependencies for that
npm i @aws-cdk/aws-lambda @aws-cdk/aws-ec2
Then, open lib/infra-stack.ts : that file contains your stack
import * as cdk from '@aws-cdk/core';
import * as ec2 from '@aws-cdk/aws-ec2';
import * as lambda from '@aws-cdk/aws-lambda';
import * as path from 'path';
export class InfraStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
const vpc = new ec2.Vpc(this, 'my-lambda-vpc', {
cidr: '100.0.0.0/16',
natGateways: 1,
maxAzs: 1,
});
const lambdaFunction = new lambda.Function(this, 'my-lambda', {
runtime: lambda.Runtime.NODEJS_14_X,
vpc,
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE,
},
memorySize: 1024,
timeout: cdk.Duration.seconds(5),
handler: 'index.main',
code: lambda.Code.fromAsset(path.join(__dirname, '/../app/my-lambda')),
});
}
}
Explanations about the code
First, we declare our VPC and give it some props :
- Cidr : we specify a range of IPv4 addresses for the VPC in the form of a Classless Inter-Domain Routing (CIDR) block
- Nat gateway : A NAT gateway is a Network Address Translation (NAT) service. You need a NAT gateway so that instances in a private subnet can connect to services outside your VPC
- Max availability zones : Each NAT gateway is created in a specific Availability Zone
Then we declare our lambda and place it inside the VPC, in the private subnet.
(Lambda functions provisioned in a public subnet don't get assigned a public IP address and don't have access to the internet.)
Lambda part
We are going to create a folder for the lambda at the root (next to lib) :
Let's create our lambda
mkdir app/my-lambda
cd app/my-lambda
npm init -y
npm i axios
touch index.js
Here is the code for the lambda using axios to fetch an url on internet.
const axios = require('axios');
export async function main(event) {
try {
const res = await axios.get('https://httpbin.org/get')
console.log(res.data)
} catch (error) {
console.log(error)
}
}
Deploy and see what we have
Let's bootstrap first
cdk bootstrap
⏳ Bootstrapping environment aws://XXXXXXXXXXXXX/us-east-1...
✅ Environment aws://XXXXXXXXXXXXXX/us-east-1 bootstrapped (no changes).
Second command, to create the Cloudformation template for our app :
cdk synth
And now, let's deploy !
cdk deploy
Let's go to the AWS management console
Go to the lambda part and create an event to test it.
You should see a log like this :
START RequestId: 1acde48b-cf6b-4e0c-b7ea-e121a96554f0 Version: $LATEST
2021-06-13T15:29:08.870Z 1acde48b-cf6b-4e0c-b7ea-e121a96554f0 INFO {
args: {},
headers: {
Accept: 'application/json, text/plain, */*',
Host: 'httpbin.org',
'User-Agent': 'axios/0.21.1',
'X-Amzn-Trace-Id': 'Root=1-60c62444-43c03f375613c0290a5a8c18'
},
origin: 'X.XX.XXX.XXX',
url: 'https://httpbin.org/get'
}
You see the origin ? -> it's your Elastic IP.
If you go to the console -> VPC -> Elastic IP, you should see this :
Destroy to save money
To avoid spending money for nothing, don't forget to destroy everything !
cdk destroy
If you want to go further , here are some useful links :
Let me know if you have any questions in the comments :)