# Insider Secrets Of AWS CDK - The Base Stack

I just finished my [No-Nonsense Guide To AWS Cloud Development Kit (CDK)](https://blog.phillipninan.com/a-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](https://github.com/fourgates/aws-cdk-base). There are only two classes you need to be worried about, `cdk-base-stack.ts` and `cdk-app.ts`.

## Table of Contents
- [Base Stack](#base-stack)
- [CDK App](#cdk-app)
- [Conclusion](#conclusion)

🐦 Follow me on [Twitter](https://twitter.com/ninan_phillip) 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](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.Vpc.html). You can create a public VPC to save costs. Private VPC's contain private subnets which require a [NAT Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html). 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 `Construct`s 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](https://github.com/fourgates/aws-cdk-base). There are only two classes you need to be worried about, `cdk-base-stack.ts` and `cdk-app.ts`.

🐦 Follow me on [Twitter](https://twitter.com/ninan_phillip) if you would like to see more content like this! 🐦
