Dennis O'Keeffe
8 min readSep 8, 2021

--

Heading image

This post is #1 of a multi-part series on the AWS CDK with TypeScript written during Melbourne lockdown #6.

This post will be an introduction to working with the AWS CDK in TypeScript.

It will lay the foundations for future posts in this series by introducing a simply example of a simple CDK application and speaking to some useful resources and definitions. This is a series where I will write one post for each day of our current lockdown in Melbourne (lockdown #6 that is expected to last seven days).

Source code can be found here.

Prerequisites

  1. An AWS account is required to run this example.
  2. AWS credentials will need to be set up on your local machine.

Getting started

We will follow the AWS CDK Getting Started with TypeScript Guide to get started.

This will kick off the initial setup of the project.

At this stage, a working TypeScript application is ready for us to use.

Upgrading the CDK packages to the latest version

The package npm-check-updates allows us to check and upgrade AWS CDK packages.

It is very useful when working with different AWS CDK modules to ensure version parity and to avoid version conflicts.

Within package.json, let's add a helper script to check and upgrade the CDK packages.

Some scripts omitted for brevity. The script names are also up to your discretion, but I will work with check and upgrade in this example.

Now, we can run npm run check to check for updates and npm run upgrade to upgrade the packages.

An example output from my console when running the commands:

At this point, your AWS CDK projects will be up to date.

An overview of the base project structure

Using the tree command (which I installed via Brew for MacOS), I can print out the base project structure for us to explore:

Here is an overview of the most import folders:

| Folder | Description | | — — — | — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — | | bin | The bin folder contains the TypeScript entry point for the application. | | lib | The lib folder contains the TypeScript source code for the application. | | test | The test folder contains the TypeScript source code for the tests. |

As for the important files (not included package.json):

| File | Description | | — — — — — — — — | — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — | | cdk.json | The cdk.json file contains the configuration for the app and tells the CDK CLI how to execute the code. | | jest.config.js | The configuration file for the Jest test runner. | | tsconfig.json | The TypeScript configuration file. |

Exploring the cdk.json file

If we look at the cdk.json file, we can see (at the time of writing) that it contains the following information:

The app key contains the command that the AWS CDK CLI will execute to start the application.

For example, if we run npm run cdk synth to generate the application, it will use ts-node to enable us to run the bin/aws-cdk-with-typescript-foundations.ts without the need to transpile the file to JavaScript first.

The context key contains an object that toggles AWS CDK feature flags.

An overview of commands

The AWS CDK project comes with a list of useful commands to help you get started.

| Command | Description | | — — — — — — — — | — — — — — — — — — — — — — — — — — — — — — — — — — — | | npm run build | Compile TypeScript to JavaScript | | npm run watch | Watch for changes and compile | | npm run test | Perform the Jest unit tests | | cdk deploy | Deploy this stack to your default AWS account/region | | cdk diff | Compare deployed stack with current state | | cdk synth | Emits the synthesized CloudFormation template | | cdk destroy | Tear down your deployed stack |

When we work through all of our applications throughout this series, we will make significant use of these commands.

Creating our first stack

In our first example, we are simply going to create a simple stack that creates an S3 bucket.

To do so, we will need to install the @aws-cdk/aws-s3 package.

It is important that all package versions for the @aws-cdk packages are at parity. If you run into any issues moving forward, ensure they are all at the latest.

To create our example bucket, we will update the lib/aws-cdk-with-typescript-foundations-stack.ts file to the following:

This example is contrived, but it will allow us to create our first S3 bucket hello-aws-cdk-my-first-bucket.

For each CDK module, the documentation is your best friend. The AWS CDK S3 documentation can help us to explain our new s3.bucket invocation.

The overview documentation shows that new Bucket(this, 'MyFirstBucket'); is the basic example of creating an unencrypted s3 bucket. The pattern for all constructs is that you pass the scope as the first argument (this in our case), the name reference for this construct and, depending on the construct, the props object.

If we move to explore the Bucket construct documentation, we can see that all construct props are optional.

In our code, we have added the optional prop bucketName to the new s3.Bucket(this, "MyFirstBucket", { ... }); invocation in order to control the naming of our bucket.

We are also explicitly adding a removalPolicy to be the enum value cdk.RemovalPolicy.DESTROY which will cause the bucket to be deleted when the stack is destroyed.

At this stage, we are ready to deploy our CDK stack. First, however, we will update our first test to reflect our new code.

Updating our first test

Within test/aws-cdk-with-typescript-foundations.test.ts, we have a test file that will test the empty stack created when we initialized the project.

We can run tests by running npm run test or the shorthand npm t. Doing so will lead to a failed test (thanks to our change):

The output tells us that the test failed and gives an output of the Resources object that was created. Given that we have confirmed that this is the expected output, we can copy that value and modify our test file:

Rerunning the test now gives us the following output:

Success! Our stack now has tests for the expected output resources.

Deploying the stack

To deploy the stack, we need to synthesize and deploy the stack. In order to do this, it is assumed that your environment is setup with the correct AWS credentials.

To synthesize and deploy, let’s run the following:

The will be a new cdk.out folder created at the root of the project with the synthesized output. I won't go into that folder, but feel free to explore the output files.

We can now deploy our project with npm run cdk deploy.

Depending on your stack, you may get a section requiring approval for a change to identity and access management rules based on your constructs and permissions required for them.

Validating our stack that deployed

We can use the AWS CLI to confirm that our bucket was created.

Assuming, you have the CLI installed, run the following to list your buckets and grep for the specified name:

Success! We now have a bucket that we can use to store our data.

Destroying the stack

To ensure we are not paying for unused resources, it is important that we tear down our stack after usage.

We can do so with the cdk destory command.

Run the following and select y to confirm the tear down:

We can confirm the bucket was destroyed with the AWS CLI:

Awesome! We have gone through an entire lifecycle of a stack deployment using the AWS CDK with TypeScript.

Understanding the constructs

We have breezed through the basic concepts of the AWS CDK. However, it would be remiss not to link to some resources to better understand some of the concepts that we have skimmed over.

The kevinslin/open-cdk is a great guide for AWS CDK best practices.

I highly recommend having a read, but for now I will speak to the three types of constructs:

| Construct | Description | | — — — — — — — — — — — | — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — | | Low level | Constructs which are automatically generated from and map 1:1 to all CloudFormation resources and properties — they have a CfnXXX prefix. | | High level | High Level constructs that initialize CFN resources with sane defaults and provide a high level interface to said resource. | | CDK pattern constructs | Constructs which stitch together multiple resources together, for example the LambdaRestApi construct which creates an api gateway that's backed by Lambda. |

In our example above, we used a high level construct to initialize our S3 bucket. In future posts, we will work with custom constructs and building out CDK pattern constructs.

Summary

Today’s post demonstrated how to get started with an new project on the AWS CDK with TypeScript.

We went over the project structure, the basic commands, construct definitions as well as going through an entire lifecycle of a stack deployment using the AWS CDK with TypeScript to deploy our first S3 bucket.

This is just the start of the series and over the coming days we will work through local development as well as more complex examples on deploying CDNs and lambda functions.

Resources and further reading

  1. AWS CDK for TypeScript
  2. AWS CDK feature flags
  3. kevinslin/open-cdk
  4. AWS CLI
  5. AWS CDK S3 documentation
  6. AWS CDK feature flags
  7. Jest
  8. Project code okeeffed/aws-cdk-with-typescript-foundations
  9. AWS credentials
  10. Create an AWS account

Photo credit: fellowferdi

Originally posted on my blog. To see new posts without delay, read the posts there and subscribe to my newsletter.

I write content for AWS, Kubernetes, Python, JavaScript and more. To view all the latest content, be sure to visit my blog and subscribe to my newsletter. Follow me on Twitter.

--

--