Describing the AWS CDK Application

AWS CDK Serverless Cookbook: Chapter 2

Miguel A. Calles · Serverless CISO
Chapter by Chapter
7 min readMay 26, 2023

--

“AWS CDK Serverless Cookbook: A Step-by-Step Guide to Build a Serverless App in the Cloud” by Miguel A. Calles
AWS CDK Serverless Cookbook book cover

In the last chapter, we created our CDK app and bootstrapped our AWS account. In this chapter, we will review and modify the CDK app structure.

The CDK Folder Structure

Open your favorite text editor, integrated development environment (IDE) application, or Microsoft Visual Studio Code[1] (vscode). (Note: We will use the IDE or vscode terms throughout the book.)

We will inspect the CDK app code and configuration files in the “cookbook/cdk-app” folder.

Top-Level Directory

The top-level directory has the necessary files for the npm[2] packages to run out application and configuration files. These files allow us to run the “npm run cdk” command.

The “bin” Folder

The “cookbook/ckd-app/bin” folder has the “cdk-app.ts” file. This “executable” file runs when we run the “npm run cdk” command.

The file’s code creates a CDK app object and adds stacks.

#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { CdkAppStack } from '../lib/cdk-app-stack';

const app = new cdk.App();
new CdkAppStack(app, 'CdkAppStack', {});

The app has a “CdkAppStack” file that was auto-generated when we ran the “npx cdk init” command.

The “lib” folder

The “cookbook/cdk-app/lib” folder has the “cdk-app-stack.ts” file which was auto-generated. This file defines the “CdkAppStack” class.

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

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

A stack is where we will add our resources. The CdkAppStack has no resources at the moment.

The “test” Folder

The “cookbook/cdk-app/test” folder has the “cdk-app.test.ts” file which was auto-generated. This file defines the unit tests that will test our CdkAppStack class.

test('SQS Queue Created', () => {});

The file has one test which does nothing.

The “cdk.out” Folder

CDK automatically creates this folder when running the “npm run cdk” command. This folder contains the files to deploy our CDK app using the CloudFormation service.

The “node_modules” Folder

This file contains all the npm dependencies.

Deploying the Auto-Generated CDK App

We will deploy this auto-generated CDK app to see what it will look like in CloudFormation.

In the container’s terminal, run the following command to synthesize the CDK app:

# paste the AWS access key information
cd ~/cdk-app
npm run cdk synth

The synthesize command tells CDK to create the CloudFormation files. If the synthesis fails, we cannot deploy the CDK app.

Next, we will deploy the CDK app. The deploy command will use CloudFormation to create the resources in our AWS account. Sometimes we might encounter a deployment error even when synthesis was successful. The synthesis checks that the CDK app produces valid CloudFormation templates but does not check whether the deployment will succeed. We will troubleshoot deployment errors based on the CloudFormation error. We should not encounter a deployment error since the CDK app has no resources.

In the container’s terminal, run the following command to deploy the CDK app:

npm run cdk deploy

We will see a new stack in CloudFormation; see Figure 2–1.

Figure 2–1. The CdkAppStack CloudFormation stack.
Figure 2–1. The CdkAppStack CloudFormation stack.

We will notice that the stack has no cloud resources besides the CDK metadata. We can check this by clicking the stack and viewing the resources tab; see Figure 2–2.

Figure 2–2. The CdkAppStack stack’s cloud resources.
Figure 2–2. The CdkAppStack stack’s cloud resources.

Destroying the Auto-Generated CDK App

We are going to be re-organizing the CDK stack to meet our needs. We are going to destroy it (or delete it) since we do not need it.

In the container’s terminal, run the following command to destroy the CDK app:

npm run cdk destroy

We will answer “y” to the prompt and see the “CdkAppStack: destroyed” output. The stack is now missing in CloudFormation after refreshing the page.

Re-Organizing the CDK Files

We will make some changes to help with our CDK app development.

Ignoring the Context File

CDK will automatically create “cdk.context.json” which contains lookup values about our AWS account. This file contains our AWS account ID and may contain secret information. We do not want to commit this file to git, which will appear in GitHub. We are going to tell git to ignore this file.

Open the “cookbook/.gitignore” file and add “cdk.context.json” to the list.

*.js
!jest.config.js
*.d.ts
node_modules

# CDK asset staging directory
.cdk.staging
cdk.out

# other CDK files
cdk.context.json

GitHub Desktop (and any git program) will ignore the file when CDK creates it.

Speeding Up CDK Synthesis and Deployments

CDK uses the “ts-node” package to run the code when we use the “npm run cdk” command. The package has to compile the TypeScript code into JavaScript. This process takes time. We can speed up this process by changing the compiler. For more information, read the post below.

In the container’s terminal, run the following command to install npm packages:

npm i -D @swc/core @swc/helpers regenerator-runtime

Open the “cookbook/tsconfig.json” file and add the “ts-node” property.

{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": [
"es2020",
"dom"
],
"declaration": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": false,
"inlineSourceMap": true,
"inlineSources": true,
"experimentalDecorators": true,
"strictPropertyInitialization": false,
"typeRoots": [
"./node_modules/@types"
]
},
"exclude": [
"node_modules",
"cdk.out"
],
"ts-node": {
"swc": true
}
}

Renaming the “CdkAppStack” Stack

We want our stacks to have meaningful names. We will rename the “CdkAppStack” to “WebsiteStack” since we will create a serverless website. (Note: We can use the refactoring tools in vscode to simplify this task.)

We will rename the “cookbook/cdk-app/lib/cdk-app-stack.ts” file to “cookbook/cdk-app/lib/website-stack.ts” and update the code to rename the “CdkAppStack” class to “WebsiteStack” class.

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class WebsiteStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
}
}

We will update references to the “CdkAppStack” and “cdk-app-stack” in the “cookbook/cdk-app/bin/cdk-app.ts” file.

#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { WebsiteStack } from '../lib/website-stack';

const app = new cdk.App();
new WebsiteStack(app, 'WebsiteStack', {
});

Moving the Unit Tests

We will move the “cookbook/cdk-app/test/cdk-app.test.ts” file to “cookbook/cdk-app/bin/cdk-app.test.ts” so that unit tests reside in the same folder as the code it is testing. Having test files with the code improves Developer Experience (DX) for these reasons:

  • Easier to find tests
  • Easier to remember to update unit tests
  • Better organization (no need to have a complicated “tests” folder)

We will need to update the Jest test configuration file so it knows to find test files elsewhere. We will modify the “roots” property to remove the “tests” folder and have it check the entire “cdk-app” folder.

module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.tsx?$': 'ts-jest'
}
};

We can now delete the “tests” folder.

Checking Our Updates

Let’s check our updates.

We will run the “npm test” command.

npm test

We will see the “Ran all test suites.” output.

Let’s synthesize the CDK app.

npm run cdk synth

We see the CDK template in the output.

Let’s deploy the CDK app.

npm run cdk deploy

The deployment was successful, and we will see the “WebsiteStack” in CloudFormation; see Figure 2–3.

Figure 2–3. The WebsiteStack CloudFormation stack.
Figure 2–3. The WebsiteStack CloudFormation stack.

Other Clean Up

Our container generated some hidden files. We do not want them saved in our git repository. We are going to tell git to ignore them.

We will create a “cookbook/.gitignore” file and add the following text:

.bash_history
.cdk
.npm

Git will now ignore these files and directories.

Chapter Review

We reviewed the auto-generated CDK app’s structure, deployed it, and destroyed it. We updated the configuration files and app code to prepare them for developing our serverless website.

Next, we will describe the serverless website we will build using CDK and the cloud resources needed to make it functional and practical. The following section is coming soon.

Before you go

Subscribe to my mailing list to get new chapters delivered to your email.

Is your dream to write a book, but you are worried you do not have what it takes? You can start writing one chapter at a time. Submit your drafts to the Chapter by Chapter publication and start realizing your dream.

Go to the “AWS CDK Serverless Cookbook” table of contents.

--

--

Miguel A. Calles · Serverless CISO
Chapter by Chapter

Author of Mastering AWS Serverless · AWS Community Builder · Specializing in CMMC, SOC 2, serverless & engineering.