Module 3: Create Your First AWS CDK Project


Create Your First AWS CDK Project

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

What you will accomplish

  • Create a new CDK project with TypeScript.
  • Write a simple resource in CDK (VPC).
  • Synthesize your CDK code into a CloudFormation template.
  • Deploy the infrastructure into your AWS account.


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

 Time to complete

25 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 use the CDK CLI setup in the previous module. 

To get started, we create an empty directory using the mkdir command and change the working directory using the cd command:
mkdir cdk-demo
cd cdk-demo
Now, we use the cdk init command and specify that we want to create a new TypeScript CDK project:
cdk init --language typescript
The cdk init command creates the folder structure and installs some of the necessary modules required for a TypeScript CDK project. The output looks something like this:
Applying project template app for typescript
# Welcome to your CDK TypeScript project

This is a blank project for CDK development with TypeScript.

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...
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:   git config --global init.defaultBranch <name>
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:   git branch -m <name>
Executing npm install...
✅ All done!
As you can see, the output provides you with commands that are needed to help you get started with your CDK project. 
Now let's review the files that the  cdk init command created:
├── bin
│   └── cdk-demo.ts
├── lib
│   └── cdk-demo-stack.ts
├── node_modules
│   └── //list of modules
├── test
│   └── cdk-demo.test.ts
├── .gitignore
├── .npmignore
├── cdk.json
├── jest.config.js
├── package.json
├── package-lock.json
└── tsconfig.json

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

  • bin/cdk-demo.ts - This is the entry point to your CDK application. This will load/create all the stacks we define under lib/*
  • lib/cdk-demo-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 and also contains some additional settings and parameters related to CDK and your project.

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

Create the 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 (Amazon VPC)

Before we define our VPC in the main stack, we need to ensure we deploy to the correct account and region. While the CDK pulls 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 configuration changes. 

For this tutorial, this step 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:

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

const app = new cdk.App();
new CdkDemoStack(app, 'CdkDemoStack', {

  env: { account: 'ACCOUNT-NUMBER', region: 'us-east-1' },


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 tutorial.

Now you are ready to write your first resource.

For this tutorial, we will create 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 AWS CDK construct library modules. A construct can represent a single AWS resource, such as an Amazon Simple Storage Service (Amazon S3) bucket, or it can be a higher-level abstraction consisting of multiple AWS related resources. The AWS Construct Library is organized into several modules. For this tutorial, we need the Amazon EC2 module, which also includes support for Amazon VPCs.

To install the Amazon EC2 module, we will use npm. Run the following command while in your project directory:

npm install @aws-cdk/aws-ec2

This command installs all the necessary modules. If you look in your package.json file, 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-stack.ts. When first opening up the file, you should see something like this:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';

export class CdkDemoStack extends cdk.Stack {
  constructor(scope: 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 ran 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 EC2 module we just installed:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// Importing the EC2 Module
import * as ec2 from 'aws-cdk-lib/aws-ec2';

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

    // The code that defines your stack goes here


When creating a VPC, we can set a number of properties to tailor it to our needs. By default, it creates a VPC across three availability zones (AZs), with public and private subnets (with a single Internet gateway and three NAT gateways). 

For this tutorial, we want to create a very simple setup spanning two 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 in the following code:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
// import * as sqs from 'aws-cdk-lib/aws-sqs';

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

    // The code that defines your stack goes here
    // We have created the VPC object from the VPC class
    new ec2.Vpc(this, 'mainVPC', {
      // This is where you can define how many AZs you want to use
      maxAzs: 2,
      // This is where you can define the subnet configuration per AZ
      subnetConfiguration: [
           cidrMask: 24,
           name: 'public-subnet',
           subnetType: ec2.SubnetType.PUBLIC,

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

Deploy your code

Now it's time to test and deploy your code.

To see if your code is valid, you can run npm build which will compile TypeScript into JavaScript:

npm run build

If you don't get any errors, you can run the cdk deploy command:

cdk deploy

The cdk deploy command compiles your TypeScript into JavaScript and creates 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. 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.

cdk deploy

✨  Synthesis time: 9.36s

CdkDemoStack: deploying...
[0%] start: Publishing CDK-METADATA-ID:ACCOUNT-us-east-1
[100%] success: Published CDK-METADATA-ID:ACCOUNT-us-east-1
CdkDemoStack: creating CloudFormation changeset...

 ✅  CdkDemoStack

✨  Deployment time: 75.49s

Stack ARN:

✨  Total time: 84.84s

The VPC created in this tutorial does not cost anything per month, but there is a quota that limits each region in an account to only allow five VPCs. If you need to increase this quota, contact AWS Support. 

Clean up resources (optional)

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 following prompt. Press y and then Enter (or Return) to start removing all the infrastructure. Once completed, you will see the green check mark and confirmation message:

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

 ✅  CdkDemoStack: destroyed


Congratulations! You have completed the Get Started with AWS CDK tutorial. In this tutorial, 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.

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

Was this page helpful?