Subnet Selection Example in AWS CDK

avatar

Borislav Hadzhiev

Wed May 05 20213 min read

banner

Photo by Elena Popova

In order to explicitly select a subnet to launch our instances in, we have to use the `subnetSelection` prop.

Table of Contents #

  1. Selecting a Subnet by Type in AWS CDK
  2. Selecting a Subnet by Group Name in AWS CDK
  3. Selecting a Subnet by Availability Zones in AWS CDK

Selecting a Subnet by Type in AWS CDK #

In order to specify what subnet we want to provision our resources in, we have to use one of the following 3 props, that achieve the same goal:

  • subnetSelection
  • subnets
  • vpcSubnets

If we don't explicitly select a subnet to launch our instances in, the default behavior is for them to be launched in private subnets.

The code for this article is available on GitHub

Let's look at a complete example where we create:

  • a VPC
  • a security group
  • an EC2 instance, for which we explicitly select a subnet
lib/cdk-starter-stack.ts
import * as ec2 from '@aws-cdk/aws-ec2';
import * as cdk from '@aws-cdk/core';

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

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

    const securityGroup = new ec2.SecurityGroup(this, 'security-group-id', {
      vpc,
    });

    const webServer = new ec2.Instance(this, 'web-server', {
      instanceType: ec2.InstanceType.of(
        ec2.InstanceClass.T2,
        ec2.InstanceSize.MICRO,
      ),
      machineImage: ec2.MachineImage.latestAmazonLinux(),
      vpc,
      securityGroup,
      // ๐Ÿ‘‡ set the subnet type to PUBLIC
      vpcSubnets: {subnetType: ec2.SubnetType.PUBLIC},
    });
  }
}

Let's go over what we did in the code snippet.

  1. we created a VPC, that has a PUBLIC and an ISOLATED subnet groups. This subnetConfiguration will create a total of 6 subnets, because we've set the maxAzs prop to 3. Each subnet group creates a subnet in every availability zone.

  2. we created a security group, which we will associate with our EC2 instance

  3. we created an EC2 instance, for which we explicitly selected a subnet type, by passing the vpcSubnets prop. The EC2 instance will be launched in one of the 3 PUBLIC subnets we created (because maxAzs of the VPC is 3).

    The subnetType prop selects all subnets of the given type, in our case all PUBLIC subnets.

I'll deploy the stack by running:

shell
npx cdk deploy

If we take a look at the provisioned EC2 instance in the EC2 management console, we can see that it was provisioned in one of the PUBLIC subnets:

subnet selection type public

Selecting a Subnet by Group Name in AWS CDK #

If we had more than 1 subnet group of type PUBLIC, we would have to narrow them down using the subnetGroupName property, for example:

lib/cdk-starter-stack.ts
const webServer = new ec2.Instance(this, 'web-server', {
  instanceType: ec2.InstanceType.of(
    ec2.InstanceClass.T2,
    ec2.InstanceSize.MICRO,
  ),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  vpc,
  securityGroup,
  // ๐Ÿ‘‡ launch in subnet with a specific Group Name
  vpcSubnets: {subnetGroupName: 'public-subnet-1'},
}

By using the subnetGroupName property, we are able to select a specific subnet group by name, in case we have provisioned a VPC with multiple subnet groups of the same type.

Selecting a Subnet by Availability Zones in AWS CDK #

We are also able to select a subnet in a specific availability zone.

Subnets groups create the specific subnet type in multiple availability zones, so we also have the option to select a specific subnet in a specific availability zone:

lib/cdk-starter-stack.ts
const webServer = new ec2.Instance(this, 'web-server', {
  instanceType: ec2.InstanceType.of(
    ec2.InstanceClass.T2,
    ec2.InstanceSize.MICRO,
  ),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  vpc,
  securityGroup,
  // ๐Ÿ‘‡ explicitly pick availability zones of the subnet
  vpcSubnets: {
    subnetType: ec2.SubnetType.PUBLIC,
    availabilityZones: [cdk.Stack.of(this).availabilityZones[0]],
  },
});

In the code snippet we have selected a PUBLIC subnet in one particular availability zone for our EC2 instance to be launched in.

Selecting the specific availability zone of the subnet only works for stacks that environment-agnostic (account and region are explicitly set).

Clean up #

To delete the provisioned resources, execute the destroy command:

shell
npx cdk destroy

Further Reading #

Join my newsletter

I'll send you 1 email a week with links to all of the articles I've written that week

Buy Me A Coffee