This post provides some basic information on the CDK as well as some code examples to get you started.
The first step is to get the CDK installed. This requires
The two main commands for the CDK cli are cdk synth
and cdk deploy
. synth
will output a template. deploy
will generate the template and deploy it.
The AWS docs do a pretty good job of explaining how to get off the ground. The focus of this guide is providing a backend for simple CRUD operations.
The amplify-base-cdk.py describes a base level stack for supporting CRUD operations. Comments are included to explain what's going on.
There are a few reasons why the CDK is awesome!
YAML/JSON can be challenging to work with. There are tools like cfn-lint, but it can only go so far in linting a YAML file.
Using a language of your choice makes life easier for you and you get extensive type checking, linting, and
validation. synth
and deploy
ensure that you have a valid template.
The CDK is highly declarative. Related to higher level constructs, rather than having to explicitly define a policy and attach it to a role, you can do something like
python
table.grant_read_write_data(function)
The CDK defines all sorts of interfaces to make this possible. All that's required is the argument passed to
grant_read_write_table
adheres to an interface that exposes a IAM principal.
You can also make use of programming language features such as if/else and looping. If you know all of your Lambda functions will use the Python 3.8 runtime, have the same handler function definition, and make use of a table you could create
def create_python_function(function_name, function_path):
parent_path = Path(__file__).parent.absolute()
return function = lambda_.Function(self, function_name,
code=lambda_.Code.from_asset(str(Path(parent_path, function_path))),
runtime=lambda_.Runtime.PYTHON_3_8,
handler='handler.handler',
environment={'TABLE': table.table_name})
Bye bye boilerplate!
The CDK represents CloudFormation resources as constructs. Raw CloudFormation is quite verbose. For the resources that make use of higher level constructs, things are quieted down. For example in the CDK a table may look like
table = dynamodb.Table(self, 'Table',partition_key=dynamodb.Attribute(name='pk', type=dynamodb.AttributeType.STRING), sort_key=dynamodb.Attribute(name='sk', type=dynamodb.AttributeType.STRING))
table.add_global_secondary_index(partition_key=dynamodb.Attribute(name='sk', type=dynamodb.AttributeType.STRING), sort_key=dynamodb.Attribute(name='gsi1sk', type=dynamodb.AttributeType.STRING), index_name='gsi1')
and a corresponding YAML file may look like
myDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
-
AttributeName: "Album"
AttributeType: "S"
-
AttributeName: "Artist"
AttributeType: "S"
-
AttributeName: "Sales"
AttributeType: "N"
-
AttributeName: "NumberOfSongs"
AttributeType: "N"
KeySchema:
-
AttributeName: "Album"
KeyType: "HASH"
-
AttributeName: "Artist"
KeyType: "RANGE"
ProvisionedThroughput:
ReadCapacityUnits: "5"
WriteCapacityUnits: "5"
TableName: "myTableName"
GlobalSecondaryIndexes:
-
IndexName: "myGSI"
KeySchema:
-
AttributeName: "Sales"
KeyType: "HASH"
-
AttributeName: "Artist"
KeyType: "RANGE"
Projection:
NonKeyAttributes:
- "Album"
- "NumberOfSongs"
ProjectionType: "INCLUDE"
ProvisionedThroughput:
ReadCapacityUnits: "5"
WriteCapacityUnits: "5"