Skip to main content

CDK Setup

AWS Cloud Development Kit (CDK) allows TypeScript code (and other programming languages) to manage the AWS infrastructure for the website.

Installing and configuring CDK

First, follow the official CDK Getting started guide (including the "Create your first AWS CDK app" tutorial) to install CDK and use it to confirm that resources can be created in the AWS cloud.

Authentication

The CDK getting started guide doesn't clearly explain how to authenticate with the AWS CLI and CDK. If you run a business on AWS you should already have a standard way to do this. Otherwise, the easiest way (which is the least secure way, but acceptable for a personal project) is using an access key from your AWS account:

  1. Log into the AWS console web UI, click your username in the upper right, and select "Security Credentials"

  2. Scroll down to "Access Keys" and click "Create access key". Follow the instructions.

  3. While on the screen that shows you the key's "Access key" and "Secret access key" values, run:

    aws configure

    Enter the two keys when prompted. Also set your default region as desired. For the output format, text is suitable for manually running commands.

  4. Run:

    aws sts get-caller-identity

    to confirm your access keys are setup correctly. It should return some info about your AWS user.

if aws sts get-caller-identity succeeds and your account has the needed permissions, the cdk command should be ready to manage your AWS infrastructure.

tip

Access keys are permanent, so it's a good idea to rotate them (delete and recreate them) periodically. Or look into alternate ways of authenticating, such as IAM Identity Center if you are running a business on AWS.

warning

If you are logged into the AWS console using your main account (AKA the "root user"), you'll see warnings that creating access keys for the root user is a bad security practice.

You could ignore these warnings to get started, but before long you should look into creating a dedicated user account for CDK access with IAM. It's pretty self-explanatory to setup an IAM user in the AWS console. The tricky part is deciding permissions. The easiest (and again, least secure) way is to give access to everything with the AdministratorAccess policy, which looks like:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}

From a security perspective, this is only slightly better than generating access keys for the root user because this user can do (almost) anything if the account / access key is compromised. Ideally, you should research how to give the bare minimum permissions to manage cloud infra with CDK and set up a more restrictive policy. This topic is currently out of scope for this tutorial.

Once an IAM user is created, you can log into the AWS console as that user and generate access keys as described above.

danger

Once you've setup an IAM user, don't forget to delete access keys from the root user account if you created any!

Setting up CDK for the website project

Create a CDK sub-project inside this website's repository. It has its own package.json, so putting it in a subdirectory will avoid clashes with the Docusaurus website project at the top level. As a convention I'm naming this folder aws-infra. From the project's root folder, run:

mkdir aws-infra
cd aws-infra
cdk init app --language typescript

This will generate a bunch of files. First let's look at aws-infra/bin/aws-infra.ts, which should look something like this:

aws-infra/bin/aws-infra.ts
#!/usr/bin/env node
import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { AwsInfraStack } from "../lib/aws-infra-stack";

const app = new cdk.App();
new AwsInfraStack(app, "AwsInfraStack", {
/* If you don't specify 'env', this stack will be environment-agnostic.
* Account/Region-dependent features and context lookups will not work,
* but a single synthesized template can be deployed anywhere. */
/* Uncomment the next line to specialize this stack for the AWS Account
* and Region that are implied by the current CLI configuration. */
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
/* Uncomment the next line if you know exactly what Account and Region you
* want to deploy the stack to. */
// env: { account: '123456789012', region: 'us-east-1' },
/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
});

Let's make a couple changes to this file:

  1. Set the name of the CDK stack. The CDK stack is a collection of cloud resources and their configurations used to manage infrastructure with AWS CloudFormation. I recommend using your website/project name (for example: "SiteOnAws"):

    new AwsInfraStack(app, "YOUR_SITE_NAME", {
  2. Uncomment this line to use the account and region specified on the command line:

    env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },

You can delete the other comments. Now the file should look like this:

aws-infra/bin/aws-infra.ts
#!/usr/bin/env node
import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { AwsInfraStack } from "../lib/aws-infra-stack";

const app = new cdk.App();
new AwsInfraStack(app, "YOUR_SITE_NAME", {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION,
},
});

That's it for a basic CDK setup!

info

CDK_DEFAULT_ACCOUNT is the account set by the cdk command's --profile option, or it defaults to the default AWS CLI account (see docs). This is the same as all AWS CLI commands and should work as expected when managing multiple AWS accounts.

tip

If you have reason to deploy to a specific region that's different from your AWS CLI profile's region, you can hard-code it in aws-infra/bin/aws-infra.ts (for example: region: "us-east-1").

Note that the first time you deploy to an AWS region with CDK, you need to run cdk bootstrap. If you forget, error messages should make this clear. If you went through the first CDK app tutorial, you should have already bootstrapped in your default region.