Phillip Ninan
Phillip Ninan's Blog

Phillip Ninan's Blog

Insider Secrets Of AWS CDK - The Base Stack

Insider Secrets Of AWS CDK - The Base Stack

Phillip Ninan

Published on Apr 9, 2021

4 min read

Subscribe to my newsletter and never miss my upcoming articles

I just finished my No-Nonsense Guide To AWS Cloud Development Kit (CDK). Today, I am going to show you one of the essential AWS CDK building blocks: the Base Stack. So, grab your favorite cup of joe, and let me give you a quick overview.

TLDR: Checkout my GitHub Repo. There are only two classes you need to be worried about, cdk-base-stack.ts and cdk-app.ts.

Table of Contents

🐦 Follow me on Twitter if you would like to see more content like this! 🐦

Base Stack

The base stack of a CDK app is where you should put resources that are not going to change, they are stateless. Using this pattern, you can keep your stateful resources (VPC, RDS, DDB, etc) intact while being able to tear down and recreate your stateless (EC2, ECS, S3, etc) resources. Stateless resources can be replaced without the risk of data loss.

In this example, we will be adding a Virtual Private Cloud (VPC) to our base stack. We will be extending a Stack in this class. A Stack should be used to deploy resources independently from the rest of the app resources. Conversely, Constructs all get deployed together.

Finally, we are going to make our VPC public. Here is a reference to the VPC construct. You can create a public VPC to save costs. Private VPC's contain private subnets which require a NAT Gateway. These incur costs on an hourly basis.

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

export interface CdkBaseStackProps extends cdk.StackProps {
  stage: string;
}

export class CdkBaseStack extends cdk.Stack {
  private readonly vpc:ec2.Vpc;
  constructor(scope: cdk.Construct, id: string, 
                              props?: CdkBaseStackProps) {
    super(scope, id, props);

    // create a VPC with no private subnets. 
    // this is for our demo purpose as this will be 
    // cheaper since you do not need a nat gateway
    const vpc = new ec2.Vpc(this, `VPC-${props?.stage}`, {
      natGateways:0,
      maxAzs: 2,
    });    

    this.vpc = vpc;
  }
  get stackVpc() : ec2.Vpc{
    return this.vpc;
  }  
}

A couple of notes:

  • CdkBaseStackProps is a pattern you can follow to pass parameters your Stack or Construct. I added a stage field to distinguish environments.
  • natGateways:0 - this option ensures there are no private subnets

CDK App

To bring everything together, you can look at our app. I have created a DemoApp class Construct. This will be composed of our CdkBaseStack. You will ultimately end up adding more Constructs here to provision resources for your cloud application.

import * as cdk from '@aws-cdk/core';
import { Construct } from '@aws-cdk/core';
import { CdkBaseStack, CdkBaseStackProps } from '../lib/cdk-base-stack/cdk-base-stack';

class DemoApp extends Construct{
    constructor(scope: cdk.App, id:string){
        super(scope,id);
        // create a small vpc for the demo
        const vpcProps: CdkBaseStackProps = {
            stage: id, 
            description: "Base VPC for AWS Cloud Application",
            tags: {env: id},
            stackName: `PublicVpcStack-${id}` // used in cloudformation for naming stack
        }        

        const base:CdkBaseStack 
                  = new CdkBaseStack(this, `CdkVpcStack-${id}`,
            vpcProps);
    }
}
const app = new cdk.App();
new DemoApp(app, 'dev');

A couple of notes here:

  • const app = new cdk.App(); - this is what initializes our app.
  • new DemoApp(app, 'dev'); - this creates a Construct for our app. I am using dev as an environment. Once you are happy with this Construct you can simply instantiate a DemoApp for each environment! This will save you time and money.
  • tags: {env: id} - tags are very useful and can help you distinguish resources in diff environments. This can come in handy when looking at your billing.

Conclusion

You now have a base class to use when deploying any infrastructure that requires a VPC by using the AWS CDK! As stated before, keep stateful resources (VPC, RDS, DDB, etc) in your base stack since you cannot easily recreate these. Stateless resources (EC2, ECS, S3, etc) can be encapsulated in constructs of their own. Stay tuned! More CDK tutorials to come!

TLDR: Checkout my GitHub Repo. There are only two classes you need to be worried about, cdk-base-stack.ts and cdk-app.ts.

🐦 Follow me on Twitter if you would like to see more content like this! 🐦

Did you find this article valuable?

Support Phillip Ninan by becoming a sponsor. Any amount is appreciated!

See recent sponsors Learn more about Hashnode Sponsors
 
Share this