Get Started with AWS CDK


Module 3: Create Your First AWS CDK Project

In this module, you will create infrastructure using the AWS Cloud Development Kit (CDK).


In this guide, we will be using the AWS CDK CLI to create a new infrastructure project using TypeScript. We will also learn how to write a simple resource, and how you can synthesize and deploy your CDK code. Synthesizing is how CDK turns your infrastructure code into AWS CloudFormation templates.

What You Will Learn

  • Creating a new CDK Project with TypeScript.
  • Writing a simple resource in CDK (VPC).
  • Synthesizing your CDK Code into a CloudFormation template.
  • Deploying the infrastructure into your AWS Account.

 Time to Complete

15 minutes

 Module Prereqs

  • AWS Account with administrator-level access**
  • Recommended browser: The latest version of Chrome or Firefox

[**]Accounts created within the past 24 hours might not yet have access to the services required for this tutorial.


Create a new CDK Project

To create a new CDK project, we will be using the CDK CLI. To get started, create an empty directory on your system and change into it. Now we will use cdk init to create a new TypeScript CDK project:

mkdir cdk-demo
cd cdk-demo
cdk init --language typescript

This will create the folder structure and install some of the necessary modules required for a TypeScript CDK project. The output should look something like this:

Applying project template app for typescript
# Welcome to your CDK TypeScript project!

This is a blank project for TypeScript development with CDK.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Useful commands

 * `npm run build`   compile typescript to js
 * `npm run watch`   watch for changes and compile
 * `npm run test`    perform the jest unit tests
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk synth`       emits the synthesized CloudFormation template

Initializing a new git repository...
Executing npm install...
npm WARN deprecated urix@0.1.0: Please see
npm WARN deprecated resolve-url@0.2.1:
npm WARN deprecated sane@4.1.0: some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added
npm notice
npm notice New minor version of npm available! 7.19.0 -> 7.20.1
npm notice Changelog:
npm notice Run npm install -g npm@7.20.1 to update!
npm notice
✅ All done!

It also provides you with commands that are needed to help you get started with your CDK project. We are now ready to write our first CDK code to create infrastructure.

Creating infrastructure

To start building out a project, a common starting point is to create a logically isolated virtual network that you define, called an Amazon Virtual Private Cloud (VPC). Before we create our first VPC, we need to understand the files that the cdk init command created.

Build and deploy your CDK application

├── bin
│   └── cdk-demo.ts
├── cdk.json
├── jest.config.js
├── lib
│   └── cdk-demo-stack.ts
├── package.json
├── package-lock.json
├── test
│   └── cdk-demo.test.ts
└── tsconfig.json

Here are some of the important files and what they are used for:

  • bin/cdk-project.ts - This is the entry point to your CDK application. This will load/create all the stacks we define under lib/*
  • lib/cdk-project-stack.ts - This is where your main CDK application stack is defined. Your resources and its properties can go here.
  • package.json - This is where you define your project dependencies, as well as some additional information and build scripts (npm buildnpm testnpm watch).
  • cdk.json - This file tells the toolkit how to run your application as well as some additional settings and parameters related to CDK and your project.

For this guide, we will be focusing on lib/cdk-demo.ts and bin/cdk-demo.ts files to create our infrastructure. Let's add some code.

Defining a few things in our application

Before we define our VPC in the main stack, we need to ensure we deploy to the correct account and region. While the CDK will pull this information from your local aws cli configuration, it is best to configure this manually in your CDK code to avoid incorrect values when that config changes. For this guide, it is required due to settings we will be defining in our VPC. If you do not specify this, the stack will be environment-agnostic, but some features and contexts lookups will not work. For more information, see environments in the documentation.

Modify your bin/cdk-demo.ts stack to look something like this. Make sure to replace your AWS account ID with the correct number, and pick the correct region. We suggest picking either us-east-1 or eu-west-1 for this guide.

#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from '@aws-cdk/core';
import { CdkDemoStack } from '../lib/cdk-demo-stack';

const app = new cdk.App();
new CdkDemoStack(app, 'CdkDemoStack', {
  env: { account: '123456789012', region: 'eu-west-1' },


Now you are ready to write your first resource.

Code for the VPC

We will be creating a VPC, with two public-facing subnets, spread across two Availability Zones. Before we can dive into writing the code, we need to explain and install construct library modules. Different services are packaged into modules to allow you to only add the dependencies you require for the infrastructure you are provisioning. Modules can either be for a single service, e.g. AWS Amplify, or for multiple services, e.g. Amazon EC2. For this guide, we will need the Amazon EC2 module, which also includes support for AWS VPCs.

To install your module, we will be using npm. Run the following command while in your project directory:

npm install @aws-cdk/aws-ec2

This will install all the necessary modules for us to work with. If you look in your package.json, you will see that it was also added there.

Now, we are ready to create our VPC. Open up your stack definition in lib/cdk-demo.ts. When first opening up the file you should see something like this:

import * as cdk from '@aws-cdk/core';

export class CdkDemoStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

This is the skeleton of our project. If you would run CDK now, no resources would be created as we don't have any defined yet. To get started with the VPC we need to import the module installed, and reference the code modules inside them - we will be importing the Vpc and the SubnetType class.

import * as cdk from '@aws-cdk/core';

// CHANGE: This is where you import the classes from the module:
import { Vpc, SubnetType } from '@aws-cdk/aws-ec2';

export class CdkDemoStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

When creating a VPC, there are a number of properties we can set to tailor it to our needs. By default, it will create a VPC across 3 availability zones (AZs), with public and private subnets (with a single Internet Gateway and 3 NAT Gateways). For this guide, we only want to create a very simple setup spanning 2 AZs, and with a public subnet for each. Please read this document for a more detailed explanation of the differences. 

To create our VPC, we will specify two AZs and the details to create a public subnet as shown below:

import * as cdk from '@aws-cdk/core';
import { Vpc, SubnetType } from '@aws-cdk/aws-ec2';

export class CdkDemoStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here
    // CHANGE: We have created the vpc object from the Vpc class.
    const vpc = new Vpc(this, 'MainVpc',{
    // CHANGE: this is where we define how many AZs to use
    maxAzs: 2,
   // CHANGE: We define a single subnet configuration per AZ.
      subnetConfiguration:  [
          // CHANGE: this is it's CIDR mask so
          cidrMask: 24,

          // CHANGE: a name for each of these subnets
          name: 'public-subnet',

          // CHANGE: and the subnet type to be used - here we will have
          // a public subnet. There are other options available here.
          subnetType: SubnetType.PUBLIC

We are now ready to deploy this infrastructure change to our account.

Deployment time

Time to test our deployment. To see if your code is valid, you can run npm build which will compile TypeScript into JavaScript. If that is successful, you can run the deploy command:

cdk deploy

This will compile your TypeScript into JavaScript and create a CloudFormation change set to deploy this change. CDK manages all of this for you, along with uploading the template file to S3 and using CloudFormation to run it. You should see output similar to below:

# cdk deploy
CdkDemoStack: deploying...
CdkDemoStack: creating CloudFormation changeset...
[··························································] (0/13)

3:50:17 PM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack            | CdkDemoStack
3:50:21 PM | CREATE_IN_PROGRESS   | AWS::EC2::InternetGateway             | MainVpc/IGW
3:50:21 PM | CREATE_IN_PROGRESS   | AWS::EC2::VPC                         | MainVpc
3:50:22 PM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata                    | CDKMetadata/Default

After a few minutes you should get a green check mark along with an ARN (Amazon  Resource Name) of your newly created CloudFormation stack. Your new VPC has now been deployed and is ready to be used.

Clean Up Resources (optional)

The VPC created in this guide will not cost anything per month, but there is a quota that limits each region in an account to only allow 5 VPCs - you can increase this limit if you need to via a support ticket. If you wish to remove your newly created resources, you can run the cdk destroy command and it will remove all the resources via the CloudFormation stack it created earlier.

cdk destroy

You should receive the below prompt. After pressing y and enter, it will start removing all the infrastructure and provide updates. Once completed, you will see the following:

Are you sure you want to delete: CdkEcsInfraStack (y/n)? y
CdkEcsInfraStack: destroying...

✅  CdkEcsInfraStack: destroyed


Congratulations! You have completed the Getting Started with AWS CDK guide. In this guide we created our first AWS CDK project in TypeScript by creating a VPC. We covered how to initialize a new CDK project, and use it to create this infrastructure. This CDK code and VPC will be used in future guides, we recommend you look at guide on how to deploy your first web application. 

If you wish to dive deeper on concepts like folder structures, constructs, stacks, and apps, we recommend you read the documentation

Let us know how we did.

Thank you for your feedback
We're glad this page helped you. Would you like to share additional details to help us continue to improve?
Thank you for your feedback
We're sorry this page didn't help you. Would you like to share additional details to help us continue to improve?