Using the AWS CDK to build scheduled Lambda Functions

Complete sample for creating Lambda Functions including a CI/CD pipeline using infrastructure as code

Maarten Thoelen
HatchSoftware
7 min readNov 25, 2019

--

At Hatch we typically use Terraform, Serverless or AWS SAM to script our cloud infrastructure. You’re probably familiar with at least one of these tools but since one year there’s a new kid on the block, the AWS Cloud Development Kit.

The AWS CDK developer preview got released at AWS re:Invent 2018. We experimented a bit with it in the early days and back then it was clearly not a mature product. However, in July 2019 it has become generally available for both TypeScript and Python. Since then it’s gaining traction.

UPDATE: On November 25th 2019, the CDK became generally available for Java and .NET as well.

As I was hearing more and more positive things about the CDK lately, I thought the time was right to give it another try and share my findings with you. As a use case I’ll recreate the functionality described in previous blog posts.

In the next steps I will explain how to build an automated way to shut down an RDS database, together with a complete CI/CD Pipeline. This time we won’t use any yaml files or manual AWS actions, only pure TypeScript code.

Prerequisites

Setup

Database

To test our code we will use the AWS CLI to setup a MySQL database on a db.t2.micro instance.

Project

Create a new directory

Change your working directory to the newly created one

Initialize a new CDK project using TypeScript

Install all the CDK modules we will need and save them as dependencies

For the sake of simplicity, you can remove the ‘test’ folder. Your project should now look like this.

We will be mainly editing two files:

  • bin/automatic-aws-db-shutdown-cdk.ts => This file is the entry point of our application. It will reference the stacks we are going to build. The CDK will start from this file to synthesize CloudFormation templates.
  • lib/automatic-aws-db-shutdown-cdk-stack.ts => This file describes one of the infrastructure stacks.

Stacks

Lamda Stack

To recreate all functionality we will build 2 stacks, one for the lambda functions and one for the CI/CD pipeline. We’ll start with the stack for our lambda functions, so let’s rename the ‘automatic-aws-db-shutdown-cdk-stack.ts’ file to ‘lambda-stack.ts.’

We won’t change the actual lambda function code, so we can reuse the files we created earlier.

Create a ‘lambda’ folder and copy the files from my previous blog post.

For the sake of completeness, I’ve added them below.

shut-down/app.js
shut-down/stop.js
start-up/app.js
start-up/start.js

It’s time to build our actual lambda stack. We create some specific StackProps to pass in the variables to reference the target RDS instance. We also create some helper methods to easily build our two lambda functions, the events that will trigger them and the necessary access policies.

lambda-stack.ts

If you paid close attention, you probably noticed that there is something missing. The SNS dead letter queue we scripted in our previous AWS SAM setup, is not included in the current stack. This is because the AWS CDK currently only supports SQS dead letter queues.

I reached out to the CDK team about this (see github issue). They were very reactive and created a pull request to add the functionality. However until today, it hasn’t been merged and released. I guess they are too busy preparing for this year’s edition of re:Invent.

Pipeline Stack

Now let’s create the stack for the CI/CD pipeline that will build and deploy our lambda functions automatically on every code update.

Create a new file ‘pipeline-stack.ts’ in the lib folder.

Once this is done, we can write the pipeline stack code.

pipeline-stack.ts

In this piece of code you’ll see we create one pipeline with 3 stages:

Source stage

In this stage we create a source action that will need to go and fetch the code from a Github repository. In order to know where to get the code from, we will store the repository owner and name in the AWS Systems Manager Parameter Store.

Our source action also needs the correct permissions to download the source code from the repository. We will give these permissions by specifying a newly created personal access token and storing this one in the AWS SecretsManager.

Build stage

The build stage will have 3 build actions.

  • One action will install and use the AWS CDK to synthesize the CloudFormation template of our lambda stack.
  • The other two actions will take the code of our lambda functions, create output artifacts from them and store them in an S3 bucket. This bucket needs to be referenced by the lambda stack.

Deploy stage

This stage contains a CloudFormation deploy action that uses the synthesized template of our lambda stack to build the infrastructure. It will also use parameter overrides to specify the S3 location where our lambda function code was published to during the build stage.

Deploy

We’re almost there, but before we can deploy we still need to modify the ‘bin/automatic-aws-db-shutdown-cdk.ts’ file.

automatic-aws-db-shutdown-cdk.ts

In this file we create our two stacks and pass in the correct stack properties. Be aware that you will need to change the variables on top of the file with the values that match your AWS account and database instance.

We can now start the actual deployment of our pipeline stack.

This command will compile our TypeScript code to javascript.

This will synthesize CloudFormation templates from our code. You can have a look at the templates in the ‘cdk.out’ folder that has been created. You’ll see that our 200 lines of TypeScript have been translated into around 1800 lines of JSON.

This command lists all resources that are about to be created.

You should type ‘y’ and hit enter. In the next minutes the infrastructure specified in our pipeline stack will be created. You can follow the progress in the terminal window.

If you log in to the AWS Management Console and go to CloudFormation, you can also see that our Pipeline stack is being created.

After a few minutes our pipeline infrastructure creation will be finished.

The created CodePipeline will be triggered automatically upon a code update. The deploy step of our pipeline will create the lambda stack.

When you check CloudFormation again, you will see the newly created stack called ‘LambdaDeploymentStack’.

When you check the lambda functions, you’ll see that they have successfully been created.

Clean up

Never forget to clean up resources you aren’t using anymore if you don’t want any surprises on your monthly AWS bill.

In order to delete the CloudFormation stack that was created automatically from the deployment pipeline, just run the command below.

Afterwards, destroy the pipeline stack we created using the CDK.

Also don’t forget to delete the test database.

Final code

The final code of this project can be found on Github. If you want to use it directly or as a baseline to start from, don’t forget to specify the correct AWS account, region and RDS database instance ID and ARN.

Conclusion

However the AWS CDK is not completely where it should be, it already came a long way since the developer preview.

The advantages of being able to use patterns and practices we are all familiar with (conditions, loops, methods, classes, …), together with your favorite programming language and IDE (providing you code-completion and refactoring capabilities) make me think the CDK has a bright future ahead.

Thanks for reading!

Maarten

--

--