Creating A Scheduled Lambda Function Using AWS CDK

Article by:
Date Published:
Last Modified:
WARNING
This page is in notes format, and may not be of the same quality as other pages on this site.

Overview

We will use Python in this example. Most of the example would be the same for a different language, however the dependency inclusion into the lambda is different for every language. This example shows how the CDK can automatically bundle Python lambda dependencies defined in a requirements.txt.

This tutorial assumes you are running Windows. However, most of the instructions are compatible with Linux, aside from some tweaks needed in this installation step.

Installation Of Dependencies

Let’s install the required development dependencies using choco (replace choco with apt or similar for Linux distros). This will have to be done with administrator privileges:

1
choco install -y awscli nodejs docker-desktop python

Then install the AWS CDK using npm. AWS CDK provides the cdk command to perform CDK specific actions, and uses the AWS CLI (aws command) under the hood.

1
npm install -g aws-cdk

General Config

If you haven’t done already, the AWS CLI (not the AWS CDK, but CLI) needs configuring:

1
aws configure

Enter in your AWS key ID and secret when prompted (if you don’t have one of these, create one via the AWS Web Console).

Now “bootstrap” the CDK. Bootstrapping creates some buckets in S3 that the CDK needs to deploy infrastructure. This step only needs to be done once:

1
cdk bootstrap aws://<account ID>/<region>

The output should look something like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 ⏳  Bootstrapping environment aws://<account ID>/<region>...
CDKToolkit: creating CloudFormation changeset...
  0/3 |2:20:54 pm | REVIEW_IN_PROGRESS   | AWS::CloudFormation::Stack | CDKToolkit User Initiated
  0/3 |2:20:59 pm | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack | CDKToolkit User Initiated
  0/3 |2:21:02 pm | CREATE_IN_PROGRESS   | AWS::S3::Bucket       | StagingBucket
  0/3 |2:21:06 pm | CREATE_IN_PROGRESS   | AWS::S3::Bucket       | StagingBucket Resource creation Initiated
  1/3 |2:21:27 pm | CREATE_COMPLETE      | AWS::S3::Bucket       | StagingBucket 
  1/3 |2:21:29 pm | CREATE_IN_PROGRESS   | AWS::S3::BucketPolicy | StagingBucketPolicy 
  1/3 |2:21:30 pm | CREATE_IN_PROGRESS   | AWS::S3::BucketPolicy | StagingBucketPolicy Resource creation Initiated
  2/3 |2:21:30 pm | CREATE_COMPLETE      | AWS::S3::BucketPolicy | StagingBucketPolicy 
  3/3 |2:21:31 pm | CREATE_COMPLETE      | AWS::CloudFormation::Stack | CDKToolkit
 ✅  Environment aws://<account ID>/<region> bootstrapped.

Creating A New CDK Project

Let’s create a new CDK project. Make a new directory called cdk_example (it can’t have anything in it). We’ll use python for this example, so we provide the flag --language python.

NOTE: The language specified here is not the language which the lambda runs, but the language used to describe the cloud infrastructure. Similarly with the dependencies, these are build time dependencies required to build/deploy the stack, but not the runtime dependencies. This is an important distinction to remember! We’ll get to the runtime language and dependencies later (which we also used Python for in this example).

1
2
3
cdk init --language python
.venv/Scripts/activate
pip install -r ./requirements.txt

Notice how it has automatically created a virtual environment for us, which we activate on Windows with .venv/Scripts/activate (on Linux, use source .venv/bin/activate instead). We then installed the requirements that cdk init automatically created in the requirements.txt file with pip.

cdk init automatically provides basic build-time dependencies, but we still have to define addition build-time dependencies for making a lambda (and indeed, a specific Python lambda). All of the AWS CDK pip libraries start with aws_cdk.

1
2
pip install aws_cdk.aws_lambda
pip install aws_cdk.aws_lambda_python

Rather than just using aws_lambda, I’m using aws_lambda_python. This is a special library for lambda’s which run in a Python environment, and provides extra functionality to bundle up all the dependencies required automatically. Without this you’d have to work out how to do that yourself, so I definitely recommend using this feature!

Define The Infrastructure

There is a folder called cdk_example inside your cdk_example root directory. Inside this is a cdk_example_stack.py file. This file describes your stack. Replace the contents with what is listed below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from aws_cdk import core as cdk

from aws_cdk import (    
    aws_lambda as _lambda,
    aws_lambda_python,
)

class CdkExampleStack(cdk.Stack):

    def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your stack goes here
        my_lambda = aws_lambda_python.PythonFunction(
            self,
            'LambdaHandler',         
            runtime=_lambda.Runtime.PYTHON_3_8,
            entry='./lambda/',
            index='main.py',
            handler='handler',
        )

Notice how we are using aws_lambda_python.PythonFunction to create the lambda, rather than the aws_lambda.Function, which is a popular example online (for instance, on https://docs.aws.amazon.com/cdk/latest/guide/serverless_example.html). The PythonFunction is much better if your lambda is running Python, as it handles bundling of the dependencies for you.

Add In The Lambda Code

So great, we’ve defined that our stack is going to contain an lambda. But we haven’t actually created any code for the lambda to run. Let’s do this now. We’ll use Python again for this, although it doesn’t have to be the same language as what you’ve defined the stack with above.

Make a new directory called lambda in the root directory of your project. Inside this, create a file called main.py. Paste the below contents into this file.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'text/plain'
        },
        'body': 'Hello, CDK!',
    }


if __name__ == '__main__':
    handler(None, None)

Adding Dependencies

The above lambda code is really basic, and does’t rely on any 3rd party libraries. However, you’ll soon run into the need to add dependencies to your project. Thankfully this is easy, all you need to do is create a requirements.txt in the lambda/ directory and add in the lambda dependencies as usual (pip freeze > requirements.txt can do this).

Deploying

We can now deploy the stack into the cloud. All you need to do is type:

1
cdk deploy

cdk will automatically bundle the dependencies (by invoking Docker, and installing the dependencies in lambda/requirements.txt into a Docker container that matches what will be running in the cloud). It will then upload the bundle to S3 (I think, at least it’s somewhere in the cloud!), ready to run!

You can test the lambda by going to the Lambda page in the Web Console and running the “Test” command.


Authors

Geoffrey Hunter

Dude making stuff.

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License .

Related Content:

Tags

comments powered by Disqus