Andy Desmarais

A code ninja and all around tech geek

AWS CDK - Gotchas, Tips, and Tricks

2020-02-09 Andy DesmaraisAWS

Cover photo credit: Anna Gru

Before we get started you should know this is all drawn from personal experience working with the CDK. I love the AWS CDK and the power it provides me. I am thrilled with how easily I’ve been able to pick it up. That being said, nothing is perfect and I want to help my fellow DevOpsians be a bit more successful with these tips and tricks.

It all started with bootstrapping my account

The first time you try to deploy a lambda that relies on assets (a build, or third part dependency of some kind), you’ll get prompted to “bootstrap” the account you are deploying into. You’ll do that by running:

cdk bootstrap aws://${ACCOUNT_ID}/${AWS_REGION}

Currently this simply puts an s3 bucket in the account with a prefix of cdktoolkit-stagingbucket. This is great! Now I can deploy my lambda function right!? Wrong.

If you’re following the recommended best practices from AWS then you will have restricted the role doing your deployment to the tightest possible permissions.

What you’ll get now is this beauty of an error message:

lambda-stack: deploying...

 ❌  lambda-stack failed: Forbidden: null

What? What is that!? It’s a terrible error message that already has an open issue. This is a result of not having permissions to work with the CDK S3 bucket that was created during the bootstrap command.

The issue also gives an example policy that will give the required permissions:

new PolicyStatement({
    resources: [
        'arn:aws:s3:::cdktoolkit-stagingbucket-*',
    ],
    actions: ['s3:*'],
})

Now this policy is probably a little too lenient, and we could go as far as listing everything in the S3 permission set, but excluding s3:DeleteBucket. That’s completely up to you. The CDK will actively be putting and removing items to/from the bucket so you can tune and tweak these permissions further if you desire.

Catching mistakes with the synth command

Just like with cloud formation, there’s a lot of moving parts with the CDK. Testing things locally before a deploy is a great way to shorten the dev cycle when creating new stacks. This is especially true when working with unfamiliar resources.

The CDK provides a command to ensure that all of the javascript classes are coming together correctly.

cdk synth

This allows you to do a “dry run” of your stack without deploying anything. If you’re like me and coming from a CloudFormation background you can also check out the CloudFormation generated by looking in the cdk.out folder for the json output. It’s a great way to learn how all of the different resources tie together.

Type definitions are your friend

I personally use VS Code for my development environment. The main benefit of doing this with the CDK is “clicking through” to the Type Definitions for each resource. On a mac Command Click (⌘ + Click), on Windows Ctrl Click (Ctrl + Click), and you will be whisked away to the magical kingdom of knowledge!

I’ve found it most fruitful to look for the constructor of the resource I’m creating. Then click through again to the Props for the resource. As an example:

⌘ + Click on lamda.Function:

const cdk = require('@aws-cdk/core');
const lambda = require('@aws-cdk/aws-lambda');

class LambdaStack extends cdk.Stack {
  new lambda.Function(this, 'lambda-function', { ... };
  //CLICK HERE ^^^^
}

And you’ll be brought to this line. Then ⌘ + Click the FunctionProps:

constructor(scope: Construct, id: string, props: FunctionProps);
//                                        CLICK HERE ^^^^

And now you can see all of the available options with descriptions! Like this:

export interface FunctionProps extends EventInvokeConfigOptions {
    /**
     * The source code of your Lambda function. You can point to a file in an
     * Amazon Simple Storage Service (Amazon S3) bucket or specify your source
     * code as inline text.
     */
    readonly code: Code;
    /**
     * A description of the function.
     *
     * @default - No description.
     */
    readonly description?: string;
............ AND MORE! ...............

It’s a really great way to figure out how names have been mapped from CloudFormation.

Deploying multiple stacks

The CDK starts out configured to deploy a single stack, but you may find yourself in a position where having multiple stacks makes more sense. The command for cdk deploy has an option allowing you to specify the stack you want to deploy by file.

cdk deploy --app ./your/file/here.js

I hope this helps

I hope this helps you progress through working with the CDK. These things have helped me a lot on my journey toward having an entirely CDK driven infrastructure.