In this post i want to show you my best practices while developing and deploying infrastructure using CDK. Let's start with a short intro about CDK. CDK - AWS Cloud Development Kit is a tool to manage AWS resources in a fully programmatic way. It is available in different popular programming languages like TypeScript, JavaScript, Python, C#/.NET and Java.
In the following picture you can see the anatomy of CDK.
If you want to learn more about how to get started with CDK take a look at the AWS CDK Developer Guide or take a look at the CDK workshop.
Now let's jump into my Best Practices i am using on daily bases to build my automations with CDK. Just as a side note i am using CDK with Typescript.
Whenever you want your user to pass information to your CDK app ensure to validate the variables. I want my users to pass the information via JSON files always so I can use typescript-json-schema
for my app. Here is an example how my config-validator looks like.
import Ajv, {JSONSchemaType} from "ajv";
import {Config} from "../types/config";
import { resolve } from "path";
import * as TJS from "typescript-json-schema";
const settings: TJS.PartialArgs = {
required: true,
noExtraProps: true
};
const compilerOptions: TJS.CompilerOptions = {
strictNullChecks: true,
};
const program = TJS.getProgramFromFiles(
[resolve("lib/types/config.ts")],
compilerOptions
);
const schema = TJS.generateSchema(program, "Config", settings);
const ajv = new Ajv();
export const validate = ajv.compile(schema as JSONSchemaType<Config>);
Whenever you need specific information in a variable like an AWS AccountId or VPCId you should use annotations with regex to validate the content of your variable before the deployment. Here is an example how your types could look like.
interface CrossAccountVpc{
/**
* @TJS-pattern "^vpc-[0-9A-Za-z]{13}$"
*/
readonly VPCId: string,
/**
* @TJS-pattern "^[0-9]{12}$"
*/
readonly AccountId: string,
}
If the content of the variable is not correct the following error can be shown if you are using the schema validation:
When ever you want to deploy your cdk app to a new account or stage i can recommend you to clean your cdk.out
directory before the next deployment. I am using taskfiles
for deployment so I created a small clean task which will be invoked before my deployment task.
tasks:
deploy:
desc: Deploy Stack
cmds:
- task: clean
- task: cdkdeploy
clean:
desc: Clean CDK Out
cmds:
- rm -rf ./cdk.out
silent: true
cdkdeploy:
desc: CDK Deploy
cmds:
- cdk deploy --require-approval never {{.TAGS}} --strict
vars:
ACCOUNT:
sh: aws sts get-caller-identity |jq -r .Account
TAGS:
sh: cat tags/tags.json | jq -j '.[]|"--tags " + (.Key)+"="+(.Value)+" "'
silent: true
interactive: true
When building a CDK App which contains a lot of constructs it make sense to structurize your project and set up multiple stacks when creating the Infrastructure. Therefore it's good to know how you can reference resources across stacks in AWS CDK. If you want to learn how to do this - look at this blogpost.
AWS CDK help you to easily manage roles and security groups. The construct library grant()
allows you to quick and simple create AWS Identity and Access Management roles granting access to one resource by another using minimally-scoped permissions. If you want to learn more about grants look at the aws cdk documentation<