Skip to main content

cdk-vpc-module

cdk-vpc-module construct library is an open-source extension of the AWS Cloud Development Kit (AWS CDK) to deploy configurable aws vpc and its individual components in less than 50 lines of code and human readable configuration which can be managed by pull requests!

:sparkles: Features

  • :white_check_mark: Option to configure custom IPv4 CIDR(10.10.0.0/24)
  • :white_check_mark: VPC Peering with route table entry
  • :white_check_mark: Configurable NACL as per subnet group
  • :white_check_mark: NATGateway as per availabilityZones
  • :white_check_mark: Public/private Route 53 hosted zones with optional public ACM certificate

Using cdk a vpc can be deployed using the following sample code snippet:

import { Network } from "@smallcase/cdk-vpc-module/lib/constructs/network";
import { aws_ec2 as ec2, App, Stack, StackProps } from "aws-cdk-lib";
import { Construct } from "constructs";

export class VPCStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps = {}) {
    const s3EndpointIamPermission = new iam.PolicyStatement({
      actions: ["s3:*"],
      resources: ['arn:aws:s3:::*'],
      principals: [new iam.AnyPrincipal()],
    })
    const monitoringEndpointIamPermission = new iam.PolicyStatement({
      actions: ["*"],
      resources: ['*'],
      principals: [new iam.AnyPrincipal()],
    })
    super(scope, id, props);
    new Network(this, 'NETWORK', {
      vpc: {
        cidr: '10.10.0.0/16',
        subnetConfiguration: [],
      },
      peeringConfigs: {
        "TEST-PEERING": { // this key will be used as your peering id, which you will have to mention below when you configure a route table for your subnets
          peeringVpcId: "vpc-0000",
          tags: {
            "Name": "TEST-PEERING to CREATED-VPC",
            "Description": "Connect"
          }
        }
      },
      subnets: [
        {
          subnetGroupName: 'NATGateway',
          subnetType: ec2.SubnetType.PUBLIC,
          cidrBlock: ['10.10.0.0/28', '10.10.0.16/28', '10.10.0.32/28'],
          availabilityZones: ['ap-south-1a', 'ap-south-1b', 'ap-south-1c'],
          ingressNetworkACL: [
            {
              cidr: ec2.AclCidr.ipv4('0.0.0.0/0'),
              traffic: ec2.AclTraffic.allTraffic(),
            },
          ],
          routes: [
          ],
          egressNetworkACL: [
            {
              cidr: ec2.AclCidr.ipv4('0.0.0.0/0'),
              traffic: ec2.AclTraffic.allTraffic(),
            },
          ],
        },
        {
          subnetGroupName: 'Public',
          subnetType: ec2.SubnetType.PUBLIC,
          cidrBlock: ['10.10.2.0/24', '10.10.3.0/24', '10.10.4.0/24'],
          availabilityZones: ['ap-south-1a', 'ap-south-1b', 'ap-south-1c'],
          ingressNetworkACL: [
            {
              cidr: ec2.AclCidr.ipv4('0.0.0.0/0'),
              traffic: ec2.AclTraffic.allTraffic(),
            },
          ],
          egressNetworkACL: [
            {
              cidr: ec2.AclCidr.ipv4('0.0.0.0/0'),
              traffic: ec2.AclTraffic.allTraffic(),
            },
          ],
          routes: [
          ],
          tags: {
            // if you use this vpc for your eks cluster, you have to tag your subnets [read more](https://aws.amazon.com/premiumsupport/knowledge-center/eks-vpc-subnet-discovery/)
            'kubernetes.io/role/elb': '1',
            'kubernetes.io/cluster/TEST-CLUSTER': 'owned',
          },
        },
        {
          subnetGroupName: 'Private',
          subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
          cidrBlock: ['10.10.5.0/24', '10.10.6.0/24', '10.10.7.0/24'],
          availabilityZones: ['ap-south-1a', 'ap-south-1b', 'ap-south-1c'],
          ingressNetworkACL: [
            {
              cidr: ec2.AclCidr.ipv4('0.0.0.0/0'),
              traffic: ec2.AclTraffic.allTraffic(),
            },
          ],
          egressNetworkACL: [
            {
              cidr: ec2.AclCidr.ipv4('0.0.0.0/0'),
              traffic: ec2.AclTraffic.allTraffic(),
            },

          ],
          routes: [
            {
            // if you use this vpc for your eks cluster, you have to tag your subnets [read more](https://aws.amazon.com/premiumsupport/knowledge-center/eks-vpc-subnet-discovery/)
              routerType: ec2.RouterType.VPC_PEERING_CONNECTION,
              destinationCidrBlock: "<destinationCidrBlock>",
              //<Your VPC PeeringConfig KEY, in this example TEST-PEERING will be your ID>
              existingVpcPeeringRouteKey: "TEST-PEERING"
            }
          ],
          tags: {
            'kubernetes.io/role/internal-elb': '1',
            'kubernetes.io/cluster/TEST-CLUSTER': 'owned',
          },
        },
        {
          subnetGroupName: 'Database',
          subnetType: ec2.SubnetType.PRIVATE_WITH_NAT,
          cidrBlock: ['10.10.14.0/27', '10.10.14.32/27', '10.10.14.64/27'],
          availabilityZones: ['ap-south-1a', 'ap-south-1b', 'ap-south-1c'],
          ingressNetworkACL: [
            {
              cidr: ec2.AclCidr.ipv4('0.0.0.0/0'),
              traffic: ec2.AclTraffic.allTraffic(),
            },
          ],
          egressNetworkACL: [
            {
              cidr: ec2.AclCidr.ipv4('0.0.0.0/0'),
              traffic: ec2.AclTraffic.allTraffic(),
            },
          ],
          routes: [
          ],
          tags: {
          },
        },
      ],
      vpcEndpoints: [
        {
          name: "s3-gw",
          service: ec2.GatewayVpcEndpointAwsService.S3,
          subnetGroupNames: ["Private","Database"],
          externalSubnets: [
            {
              id: "subnet-<id>",
              availabilityZone: "ap-south-1a",
              routeTableId: "rtb-<id>"
            },
            {
              id: "subnet-<id>",
              availabilityZone: "ap-south-1b",
              routeTableId: "rtb-<id>"
            }
          ],
          iamPolicyStatements: [s3EndpointIamPermission]
        },
        {
          name: "da-stag-monitoring-vpe",
          service: ec2.InterfaceVpcEndpointAwsService.CLOUDWATCH_MONITORING,
          subnetGroupNames: ["ManageServicePrivate"],
          iamPolicyStatements: [monitoringEndpointIamPermission],
          securityGroupRules: [
            {
              peer: ec2.Peer.ipv4("10.10.0.0/16"),
              port:  ec2.Port.tcp(443),
              description: "From Test VPC"
            }
          ],
        },
      ]
    });
  }
}
const envDef = {
  account: '<AWS-ID>',
  region: '<AWS-REGION>',
};

const app = new App();

new VPCStack(app, 'TEST', {
  env: envDef,
  terminationProtection: true,
  tags: {
});
app.synth();

Please refer here to check how to use individual resource constructs.

Route 53 hosted zones

Hosted zones are modeled separately from the Network construct. For private hosted zones, pass the VPC from the network stack and the zone is associated with that VPC automatically. ACM certificate creation is supported only for public hosted zones and creates a certificate for both <host> and *.<host>.

import { HostedZoneStack } from '@smallcase/cdk-vpc-module/lib/constructs/hosted-zone';

const hostedZones = new HostedZoneStack(this, 'HostedZones', {
  vpc: network.vpc,
  hostedZones: [
    {
      zoneName: 'example.smallcase.com',
      publicZone: true,
      createAcmCertificate: true,
    },
    {
      zoneName: 'internal.example.smallcase.com',
      publicZone: false,
    },
  ],
});

:clapper: Quick Start

The quick start shows you how to create an AWS-VPC using this module.

Prerequisites

  • A working aws CLI installation with access to an account and administrator privileges
  • You'll need a recent NodeJS installation

To get going you'll need a CDK project. For details please refer to the detailed guide for CDK.

Create an empty directory on your system.

mkdir aws-quick-start-vpc && cd aws-quick-start-vpc

Bootstrap your CDK project, we will use TypeScript, but you can switch to any other supported language.

npx cdk init sample-vpc  --language typescript
npx cdk bootstrap

Install using NPM:

npm install @smallcase/cdk-vpc-module

Using yarn

yarn add @smallcase/cdk-vpc-module

Check the changed which are to be deployed

~ -> npx cdk diff

Deploy using

~ -> npx cdk deploy

Features Multiple VPC Endpoints: Define and manage multiple VPC Endpoints in one configuration. Flexible Subnet Selection: Attach VPC Endpoints to multiple subnet groups or external subnets. Custom Security Groups: Configure security groups for Interface VPC Endpoints. IAM Policies: Attach custom IAM policies to control access to the VPC Endpoints. Tagging: Apply custom tags to each VPC Endpoint.

Defining VPC Endpoints Configuration You can define multiple VPC Endpoints in the vpcEndpoints: [] configuration array. Each VPC Endpoint can be customized with different subnet groups, IAM policies, security group rules, and tags.

vpcEndpoints: [
  {
    name: "test-s3-gw",
    service: ec2.GatewayVpcEndpointAwsService.S3,
    subnetGroupNames: ["ManageServicePrivate", "ToolPrivate", "Database"],  // Subnet groups for the endpoint
    externalSubnets: [
      {
        id: "subnet-<id>",
        availabilityZone: "ap-south-1a",
        routeTableId: "rtb-<id>",
      },
      {
        id: "subnet-<id>",
        availabilityZone: "ap-south-1b",
        routeTableId: "rtb-<id>",
      }
    ],
    iamPolicyStatements: [s3EndpointIamPermission],  // Custom IAM policy for the endpoint
  },
  {
    name: "DynamoDbGatewayEndpoint",
    service: ec2.GatewayVpcEndpointAwsService.DYNAMODB,
    subnetGroupNames: ["private-subnet"],
    additionalTags: {
      Environment: "Staging",
    },
  },
],

In this example:

The S3 Gateway Endpoint is created in three subnet groups: ManageServicePrivate, ToolPrivate, and Database. External subnets are specified with their IDs, availability zones, and route table IDs for the S3 endpoint. A custom IAM policy (s3EndpointIamPermission) is attached to control access to the S3 endpoint. A DynamoDB Gateway Endpoint is created in the private-subnet with additional tags specifying the environment and ownership.

Configuration Options Here’s a breakdown of the configuration options available:

  1. name: A unique name for the VPC Endpoint.
  2. service: The AWS service the VPC Endpoint connects to (e.g., S3, DynamoDB, Secrets Manager)
  3. subnetGroupNames: The subnet group names where the VPC Endpoint will be deployed.
  4. externalSubnets: Specify external subnets if you need to define subnets manually (each with an id, availabilityZone, and routeTableId).
  5. iamPolicyStatements: (Optional) Attach IAM policy statements to control access to the endpoint.
  6. additionalTags: (Optional) Add custom tags to the VPC Endpoint for easier identification and tracking.
  • :white_check_mark: Configurable route table entry naming for subnet routes via routeTableStringFormat

Release files for cdk-vpc-module 0.0.23

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cdk-vpc-module 0.0.23
File Size Uploaded
cdk_vpc_module-0.0.23.tar.gz 111.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cdk-vpc-module 0.0.23
File Interpreter ABI Platform
cdk_vpc_module-0.0.23-py3-none-any.whl Python 3 none any Details

Total release size: 220.7 kB

Release files / cdk_vpc_module-0.0.23.tar.gz

Download URL cdk_vpc_module-0.0.23.tar.gz
Size 111.3 kB
Tags Source
SHA-256 checksum
How to use checksums
76bf09ffae858d2ffe2ef824a5db07ad0b0e84e3ef2c898fbdbb93259d4b7774
BLAKE2b-256 checksum
How to use checksums
5c287fffcc4688e6ece96d4214582508acec548876cc221c374c22ce549469a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.14.6

Release files / cdk_vpc_module-0.0.23-py3-none-any.whl

Download URL cdk_vpc_module-0.0.23-py3-none-any.whl
Size 109.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3b4889cca8a7ebc9092afd10afae5e5b998674777032145292ae8899fe99d06d
BLAKE2b-256 checksum
How to use checksums
12962555c9585fd27f714b2e1806c2a2a3375e504148e80077d3e1496eb42eb2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

0.0.23 This release

2 release files

0.0.22

2 release files

0.0.20

2 release files

0.0.17

2 release files

0.0.16

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page