Borislav Hadzhiev
Fri Apr 15 2022·3 min read
Photo by Patrick Mueller
Updated - Fri Apr 15 2022
In this article we are going to look at an example of how to share a VPC between 2 CDK stacks in the same CDK app.
In order to share a VPC between stacks in CDK, we have to:
stackA
props
object of stackB
with the VPC typestackA
, so we get access to the VPC resourcestackB
and pass it the VPC resource as a propprops
object in stackB
Let's start by defining the following 2 stacks:
VPCStack
creates a VPCLambdaStack
creates a lambda function and places it in the shared VPCimport * as ec2 from 'aws-cdk-lib/aws-ec2'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as cdk from 'aws-cdk-lib'; import * as path from 'path'; export class VPCStack extends cdk.Stack { // 👇 set a property for the vpc public readonly vpc: ec2.Vpc; constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); this.vpc = new ec2.Vpc(this, 'my-vpc', { cidr: '10.0.0.0/16', natGateways: 0, subnetConfiguration: [ { name: 'public-subnet-1', subnetType: ec2.SubnetType.PUBLIC, cidrMask: 24, }, ], }); } } // 👇 extend the props interface of LambdaStack interface LambdaStackProps extends cdk.StackProps { vpc: ec2.Vpc; } export class LambdaStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props: LambdaStackProps) { super(scope, id, props); const {vpc} = props; cdk.Tags.of(vpc).add('environment', 'development'); cdk.Tags.of(vpc).add('department', 'dpt123'); // 👇 lambda function definition const lambdaFunction = new lambda.Function(this, 'lambda-function', { // 👇 place lambda in shared VPC vpc, allowPublicSubnet: true, runtime: lambda.Runtime.NODEJS_14_X, handler: 'index.main', code: lambda.Code.fromAsset(path.join(__dirname, '/../src/my-lambda')), environment: { // 👇 pass the VPC ID as an environment variable VPC_ID: vpc.vpcId, }, }); } }
Let's go over what we did in the code snippet.
VPCStack
, which creates a VPC. The important part here is
that we created a vpc
class property and assigned the VPC resource to it.
The property can now be accessed on instances of the class.StackProps
object with the VPC typeLambdaStack
, which references the shared VPC and provisions
a lambda function in itLet's look at how the classes are instantiated:
import * as cdk from 'aws-cdk-lib'; import {LambdaStack, VPCStack} from '../lib/cdk-starter-stack'; const app = new cdk.App(); const vpcStack = new VPCStack(app, 'vpc-stack', { stackName: 'vpc-stack', env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, }); const lambdaStack = new LambdaStack(app, 'lambda-stack', { // 👇 pass the VPC from the other stack vpc: vpcStack.vpc, stackName: 'lambda-stack', env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, });
We first instantiated the VPCStack
and assigned the result to a variable.
We then instantiated our LambdaStack
, passing it the VPC resource as a
prop.
Finally, let's add the code for the lambda function at src/my-lambda/index.js
:
async function main(event) { console.log('VPC_ID 👉', process.env.VPC_ID); return { body: JSON.stringify({message: `${process.env.VPC_ID} 🎉`}), statusCode: 200, }; } module.exports = {main};
The function simply references and returns the id of the shared VPC.
The order of deployment matters because our LambdaStack
references the VPC
resource from the VPCStack
so it has to exist before the LambdaStack
is
deployed.
Let's run the deploy
commands:
npx aws-cdk deploy vpc-stack npx aws-cdk deploy lambda-stack
By looking at the Outputs
section of our VPCStack
, we can see that CDK has
automatically created outputs for the components of the VPC, which will allow us
to access it in our second stack:
If we look at VPC section of the lambda function, we can see that it was provisioned in the shared VPC:
Finally, if we run the lambda function via the management console, it returns the ID of the shared VPC:
We have to delete the lambda-stack
first because it references an output in
the vpc-stack
.
npx aws-cdk destroy lambda-stack npx aws-cdk destroy vpc-stack