The AWS CDK for software-defined deployments

Dreaming of Clouds


Getting started with the CDK is pretty simple. In this article, I make a few assumptions:

  • You have some familiarity with AWS – enough to install, set up, and understand how to use its CLI.
  • You have used a tool like CloudFormation or Terraform (or maybe the SDK or CLI) before.
  • You have some programming background and are comfortable with language tool chains (e.g., Node.js npm [16] and Yarn [17]). During the rest of this article, I use TypeScript [18] as the CDK language and leverage Node.js ecosystem utilities.

Assuming you have an up-to-date node and npm installed, installing the AWS CDK base libraries is as simple as

$ npm install -g aws-cdk

which installs the CDK Node.js libraries. With Node set up accordingly, it places the cdk executable in your $PATH, allowing you to run cdk commands from your command line. If you are curious to explore the multitude of subcommands and options now available, type cdk help. Alternatively, you can head over to the GitHub pages [19] set up by AWS for documentation.

The CDK makes starting a new project a cinch. To begin, I'll create a new project called hello-cdk in three simple steps from the terminal:

$ mkdir hello-cdk
$ cd hello-cdk
$ cdk init app --language=typescript

These commands create a new local directory named hello-cdk, descends into that directory, and then asks the CDK to create a new application there. The CDK looks at the name of the directory it is run from with the init command and uses that as the name of the app before setting up the base files and directories you need to get started and initializing a Git repo in the directory. In the end, you can see in Listing 1 what resides in your hello-cdk directory after the init.

Listing 1

Project Root Directory

drwxr-xr-x   - bradmatic  8 Jan 23:52 .
drwxr-xr-x   - bradmatic  8 Jan 23:52 |---- bin
.rw-r--r-- 194 bradmatic  8 Jan 23:52 |    |---- hello-cdk.ts
.rw-r--r--  37 bradmatic  8 Jan 23:52 |---- cdk.json
drwxr-xr-x   - bradmatic  8 Jan 23:52 |---- lib
.rw-r--r-- 246 bradmatic  8 Jan 23:52 |    |---- hello-cdk-stack.ts
drwxr-xr-x   - bradmatic  8 Jan 23:52 |---- node_modules
drwxr-xr-x   - bradmatic  8 Jan 23:52 |    |---- @aws-cdk
drwxr-xr-x   - bradmatic  8 Jan 23:52 |    |---- @types
...                                   |    |---- ...
drwxr-xr-x   - bradmatic  8 Jan 23:52 |    |---- zip-stream
.rw-r--r-- 79k bradmatic  8 Jan 23:52 |---- package-lock.json
.rw-r--r-- 345 bradmatic  8 Jan 23:52 |---- package.json
.rw-r--r-- 320 bradmatic 20 Dec  2018 |----
.rw-r--r-- 558 bradmatic 20 Dec  2018 |---- tsconfig.json

With many subdirectories under node_modules, I truncated the output. Primarily, I'll be focusing on the contents of the bin and lib directories.

What's in the Box?

The CDK just created a ton of files, so I'll unpack things a bit. First, the node_modules folder contains dependent libraries, plain and simple. As well, you will see quite a few config files. For right now, focus on the bin and lib directories and their contents. Listing 2 shows the content of bin/hello-cdk.ts.

Listing 2


#!/usr/bin/env node
import cdk = require('@aws-cdk/cdk');
import { HelloCdkStack } from '../lib/hello-cdk-stack';
const app = new cdk.App();
new HelloCdkStack(app, 'HelloCdkStack');;

The import lines import the base CDK library and a stack-specific file from lib. Next, you define a new CDK app and instantiate a new instance of HelloCdkStack.

Listing 3 shows lib/hello-cdk-stack.ts, which has a clearly defined point to hook into the framework and define your resources. Although you could just throw code into this file and define resources, it's worthwhile to sit back, pause, and think about a few things before you do so – namely, reusability and modularity. I'll address these concerns individually.

Listing 3


import cdk = require('@aws-cdk/cdk');
export class HelloCdkStack extends cdk.Stack {
  constructor(parent: cdk.App, name: string, props?: cdk.StackProps) {
    super(parent, name, props);
    // The code that defines your stack goes here


Imagine that you are tasked with defining the entire stack for the application, from the base network infrastructure up, with whatever method you use to define your deployment (in this case, the CDK). In the case of AWS, that means you will very likely start with a virtual private cloud (VPC), subnets, security groups, route tables, route table associations, network address translation (NAT) gateway(s), and so on – just for networking.

A somewhat common pattern in most organizations when starting from scratch is to reuse a single VPC to host multiple applications (oftentimes grouped by type of environment, e.g., development, QA, test, production, etc.). In light of this, bundling the base networking infrastructure together with the application stack would greatly limit the possibility of reuse and means it would not be possible to deploy a new instance of the application – perhaps for development or testing purposes – apart from its backing resources. This arrangement also bears cost implications, because resources such as NAT gateways (and perhaps other necessary infrastructure elements) incur cost the moment they are provisioned.

Your first takeaway to keep in mind as you structure your code, then, is that you'd like somehow to keep shared resources separate from the resources that are specific to your application so that those shared resources aren't coupled to instances of your application stack.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs

Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.