What is a CDK App - Complete Guide

avatar

Borislav Hadzhiev

Thu Apr 22 20212 min read

banner

Photo by Sam Beasley

Updated on Thu Apr 22 2021

The App construct is the entry point in our CDK applications and it is composed of one or more Stacks.

What is a CDK App? #

The App in CDK represents the entry point for the entire CDK application. The CDK application is composed of one or more Stacks (same as a CloudFormation stack).

Since AWS CDK gets compiled down to CloudFormation we have to define our constructs within the scope of a Stack. The Stack represents a single CloudFormation stack (a unit of deployment).

Inside of the root stack we make use of constructs, which are cloud components used to encapsulate logic and provide higher level of abstraction (than CloudFormation) for provisioning AWS Resources.

Complete CDK App example #

Let's look at a complete example of the components of a CDK application.

The code for this article is available on GitHub

First we will define our CDK stack.

lib/cdk-starter-stack.ts
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';

// ๐Ÿ‘‡ Stack definition
export class CdkStarterStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // ๐Ÿ‘‡ using a Construct
    const bucket = new s3.Bucket(this, 'uploads-bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });
  }
}

The stack has to be instantiated in the scope of our CDK App.

bin/cdk-starter.ts
import * as cdk from '@aws-cdk/core';
import {CdkStarterStack} from '../lib/cdk-starter-stack';

// ๐Ÿ‘‡ creating our CDK App
const app = new cdk.App();

// ๐Ÿ‘‡ instantiating the Stack in the scope of the CDK App
new CdkStarterStack(app, 'cdk-stack-dev', {
  stackName: 'cdk-stack-dev',
  env: {
    region: process.env.CDK_DEFAULT_REGION,
    account: process.env.CDK_DEFAULT_ACCOUNT,
  },
});

The CDK App is the entry point of a CDK project. We have to instantiate the App by calling new cdk.App() and pass the result as the first argument to the class defining our Stack.

In this case we only have one Stack inside of our CDK App - cdk-stack-dev, however we could provision a second prod stack inside of our App, like so:

bin/cdk-starter.ts
// ๐Ÿ‘‡ App instantiation
const app = new cdk.App();

// ๐Ÿ‘‡ DEV Stack created in the scope of our App
new CdkStarterStack(app, 'cdk-stack-dev', {
  stackName: 'cdk-stack-dev',
  env: {
    region: process.env.CDK_DEFAULT_REGION,
    account: process.env.CDK_DEFAULT_ACCOUNT,
  },
});

// ๐Ÿ‘‡ PROD Stack created in the scope of our App
new CdkStarterStack(app, 'cdk-stack-prod', {
  stackName: 'cdk-stack-prod',
  env: {
    region: process.env.CDK_DEFAULT_REGION,
    account: process.env.CDK_DEFAULT_ACCOUNT,
  },
});

Inside of our Stack we can make use of constructs. Constructs help us define the resources, which make up our infrastructure.

This is the entire CDK construct tree:

  1. We start with the App Construct
  2. We define and instantiate our Stack construct
  3. We nest all our other constructs inside of the Stack

Note that the App construct is the only construct that doesn't require any arguments.

All of the other constructs, including the CDK stack require 2 arguments - the scope and id, with an optional 3rd argument - the props (config object).

When we initialize our App, by calling its constructor method all of the constructs we have defined in our applications get instantiated and the chain of constructor functions is ran.

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