Deploy fixed IP lambda inside a VPC using AWS CDK

Deploy fixed IP lambda inside a VPC using AWS CDK

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 :

Lambda Inside VPC.png

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 :

l2TrNUvvZ.jpeg

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 :)

Did you find this article valuable?

Support Sonia Manoubi by becoming a sponsor. Any amount is appreciated!