How to Create a VPC with AWS CDK

How to Create a VPC with AWS CDK

A Virtual Private Cloud (VPC) is a virtual network that is isolated from other AWS customers, providing a secure environment for your resources. In this guide, I'll walk you through how to create and configure a VPC using AWS Cloud Development Kit (CDK), including default settings and important considerations.

💡
We are going to provision 1 NAT Gateway. NAT Gateways have an hourly billing rate of about $0.045 in the us-east-1 region.

Creating a VPC in AWS CDK

To create a VPC in AWS CDK, we need to instantiate and configure the Vpc class. Here’s an example:

import { Vpc, IpAddresses, SubnetType } from 'aws-cdk-lib/aws-ec2';
import { Stack, StackProps, App } from 'aws-cdk-lib';

export class CdkStarterStack extends Stack {
  constructor(scope: App, id: string, props?: StackProps) {
    super(scope, id, props);

    const vpc = new Vpc(this, 'cdk-vpc', {
      ipAddresses: IpAddresses.cidr('10.0.0.0/16'),
      natGateways: 1,
      maxAzs: 3,
      subnetConfiguration: [
        {
          name: 'private-subnet-1',
          subnetType: SubnetType.PRIVATE_WITH_EGRESS,
          cidrMask: 24,
        },
        {
          name: 'public-subnet-1',
          subnetType: SubnetType.PUBLIC,
          cidrMask: 24,
        },
        {
          name: 'isolated-subnet-1',
          subnetType: SubnetType.PRIVATE_ISOLATED,
          cidrMask: 28,
        },
      ],
    });
  }
}

Configuration

Here’s a breakdown of the configuration properties we used:

  • ipAddresses: Defines the CIDR block of the VPC. It must be between /16 (65,536 IP Addresses) and /28 (16 IP addresses). The default value is 10.0.0.0/16.

  • natGateways: Specifies the number of NAT gateways to create. By default, one NAT Gateway is created per availability zone. For testing, it's wise to set this to 1 to avoid unnecessary costs.

    💡
    To use NAT instances instead of NAT gateways, we can set thenatGatewayProvider prop to NatProvider.instance.

    nat-instance-example:

      import { Vpc, NatProvider, SubnetType } from 'aws-cdk-lib/aws-ec2';
    
      const vpc = new Vpc(this, 'cdk-vpc', {
          natGatewayProvider: NatProvider.instance({
          instanceType: new InstanceType('t3.micro'),
        })
      })
    
  • maxAzs: The maximum number of availability zones to use. By default, it uses 3 availability zones if the environment is explicitly set (account and region) and 2 if it's environment-agnostic.

  • subnetConfiguration: Specifies the subnets to create in each availability zone. In this example, we have 3 types: private, public, and isolated subnets.

Types of Subnets

Let's dive into the different subnet types:

  • PRIVATE_WITH_EGRESS: Resources in these subnets can access the internet via a NAT Gateway but cannot be accessed from the internet. Suitable for backend servers that need internet access for updates but shouldn't be exposed.

  • PUBLIC: Resources here have internet access through an Internet Gateway and can be accessed from the internet if they have a public IP. Ideal for web servers.

  • PRIVATE_ISOLATED: Resources here have no internet access and can't be accessed from the internet. They can only communicate with other instances in the same VPC. Often used for databases.

Deployment

To deploy the resources, run:

cdk deploy

or

npx aws-cdk deploy

What Gets Provisioned

After deployment, check the CloudFormation management console. You’ll see we’ve provisioned 39 resources with our VPC definition.

VPC

The naming convention includes the stack name. You can update the name by changing the tag of the VPC.

Subnets

We created 9 subnets across 3 availability zones: public, private, and isolated subnets in each zone.

Route Tables

Public Subnets: Routes traffic to the internet via an Internet Gateway.

DestinationTargetStatusPropagated
10.0.0.0/16localactiveNo
0.0.0.0/0IGW-IDactiveNo

Private Subnets: Routes traffic to the internet through a NAT Gateway.

DestinationTargetStatusPropagated
10.0.0.0/16localactiveNo
0.0.0.0/0NATGW-IDactiveNo

Isolated Subnets: Routes traffic only within the VPC.

DestinationTargetStatusPropagated
10.0.0.0/16localactiveNo

Internet Gateway

Provisioned for public subnets and attached to the VPC.

NAT Gateway

Provisioned with an elastic IP to route traffic from private subnets.

Network Access Control Lists (NACLs)

Default NACLs associated with all subnets allow all inbound and outbound traffic.

Security Groups

Inbound Rules: Allow all traffic from resources within the same security group.

TypeProtocolPort rangeSource
All trafficAllAllSG-ID

Outbound Rules: Allow all traffic to all destinations.

TypeProtocolPort rangeDestination
All trafficAllAll0.0.0.0/0
💡
Don't forget to destroy the stack because we provisioned a NAT Gateway which has an hourly billing rate.
cdk destroy

or

npx aws-cdk destroy

By following this guide, you can set up and configure a VPC using AWS CDK efficiently.

Did you find this article valuable?

Support Mikaeel Khalid by becoming a sponsor. Any amount is appreciated!