CDK is similar to AWS SAM and Serverless framework in a way that it uses CloudFormation to deploy resources and promotes a declarative approach for creating resources.
Without going any further, let’s look at a simple example that creates an SQS queue, SNS topic, and SNS subscription.
Note that there is no need to write policies and IAM statements explicitly — CDK provides high level abstraction that remove the need to write boilerplate code we would have to write using plain CloudFormation. This abstractions are called constructs.
The main components of CDK are apps, stacks and constructs. A stack is a unit of deployment which directly maps to CloudFromation stack. An app is a collections of stacks.
A construct represents a “cloud component”, such as queue or topic, and encapsulates everything CloudFormation needs to create the component. The AWS CDK includes constructs that represent all the resources available on AWS. For example, the
s3.Bucket construct class represents an Amazon S3 bucket, and the
dynamodb.Table class represents an Amazon DynamoDB table, the
sqs.Queue — SQS queue.
In CDK you don’t reason in terms of resources as you do in CloudFormation but cloud components or constructs.
There is two types of constructs: low level(L1), and high level(L2).
L1 constructs are directly mapped to CloudFormation resourses and prefixed with Cfn, e.g.
CfnBucket maps to
L2 constructs, on other hand, are high level concepts with intent-based API. They provide reasonable defaults, boilerplate, and logic to glue everything together. e.g.
sqs.Queue is L2 construct that creates SQS queue.
Usually, you want to use L2 constructs all the time, but you may want to gain more control over the resources created. In this case, opt for L1.
You can also write your L2 constructs to encapsulate some common logic into reusable modules or provide some common standards over your entire infrastructure. The AWS Solutions Constructs patterns is open source collection os such constructs maintained by the community.
Now, let’s look at more sophisticated example using AWS solutions construct — an open-source extension of the AWS Cloud Development Kit that provides multi-service, well-architected patterns for quickly defining solutions in code to create predictable and repeatable infrastructure.
You may think of this as L3 constructs — construct composed of other constructs.
The code will create API Gateway, Lambda, Roles, and CloudWatch logs using AWS provided solution construct aws-apigateway-lambda.
You can create more complex architecture with minimum effort by combining multiple L3 constructs. Lets say we want to build an HTTP API to store data in a DynamoDB table. To keep the content of the table small, we can use DynamoDB TTL to expire items after a few days. After the TTL expires, data is deleted from the table and sent, via DynamoDB Streams, to a AWS Lambda function to archive the expired data on S3. How can we achieve this with CDK? Easy!
- aws-apigateway-lambda, a Construct that implements an API Gateway REST API connected to a Lambda function.
- aws-dynamodb-stream-lambda, a Construct implementing a DynamoDB table streaming data changes to a Lambda function with the least privileged permissions.
Lets install the CDK cli by running npm install command.
npm install -g aws-cdk
CLI usage is pretty simple. Run run
cdk init to create a new project,
cdk synth to generate CloudFormation template, and
cdk deploy to deploy the app. There is one additional
cdk bootstrap step that must be executed once per environment.
Each stack instance in your AWS CDK app is explicitly or implicitly associated with an environment. An environment is the target AWS account and region into which the stack is intended to be deployed.
cdk init app --language python . This command will generate new app skeleton for us.
├── README.md ├── app ├── __init__.py └── app_stack.py ├── app.py ├── cdk.json ├── requirements.txt ├── setup.py └── source.bat
Heres how app.py will look like.
The app define stacks it will deploy. As we already know, each stack consists of constructs, a.k.a cloud components. In this example I also specified the implicit environment. Alternatively you could read this parameters from env variables.
import os env=core.Environment( account=os.environ["CDK_DEFAULT_ACCOUNT"], region=os.environ["CDK_DEFAULT_REGION"]) )
Run the bootstrap step and deploy the app. This will create CloudFormation stack with 1 resource — CDKMetadata, it contains come service information we don’t need to worry about.
Now it’s time to put some constructs into our empty stack.
Road so far
At this point we know:
- the purpose of CDK,
- how to install CDK,
- main components of CDK,
- and how to use the CDK.
As a next step I recommend you go and checkout CDK examples repo. This will give you nice overview of CDK abilities.