Lambda

Lambda handler code

We’ll start with the AWS Lambda handler code.

  1. Create a directory lambda in the root of your project tree (next to the sls-app directory).
  2. Add a file called lambda/index.py with the following contents:
import json
import os

import boto3

ddb = boto3.resource('dynamodb')
table = ddb.Table(os.environ['TABLE_NAME'])
_lambda = boto3.client('lambda')


def handler(event, context):
    print('request: {}'.format(json.dumps(event)))
    response = table.update_item(
        Key={'path': event['path']},
        UpdateExpression='ADD hits :incr',
        ExpressionAttributeValues={':incr': 1},
        ReturnValues='UPDATED_NEW'
    )
    hit_count = int(response['Attributes']['hits'])
    
    return {
        'statusCode': 200,
        'headers': {'Content-Type': 'text/plain'},
        'body': f"You've hit {event['path']}: {hit_count} time(s)"
    }

The function’s output includes the HTTP status code and HTTP headers. These are used by API Gateway to formulate the HTTP response to the user.

This lambda is provided in Python. For more information on writing lambda functions in your language of choice, please refer to the AWS Lambda documentation here .

Add an AWS Lambda Function to your stack

Add an import statement at the beginning of sls-app/sls_app_stack.py, and a lambda.Function to your stack.

from aws_cdk import (
    core,
    aws_dynamodb,
    aws_lambda
)


class SlsAppStack(core.Stack):

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

        ## 1. Define the table that maps short codes to URLs.
        table = aws_dynamodb.Table(
            self, 
            "counter",
            partition_key={
                'name': 'path',
                'type': aws_dynamodb.AttributeType.STRING
            }
        )
        
        ## 2.1. Defines Lambda resource & API-Gateway request handler
        ## All API requests will go to the same function.
        handler = aws_lambda.Function(self, "CounterFunction",
            code=aws_lambda.Code.asset("./lambda"),
            handler="index.handler",
            timeout=core.Duration.seconds(5),
            runtime=aws_lambda.Runtime.PYTHON_3_8
        )

        ## 2.2. Pass the table name to the handler through an env variable 
        ## and grant the handler read/write permissions on the table.
        table.grant_read_write_data(handler)
        handler.add_environment('TABLE_NAME', table.table_name)
A few things to notice.

  • Our function uses the Python 3.8 runtime
  • The handler code is loaded from the lambda directory which we created earlier. Path is relative to where you execute cdk from, which is the project’s root directory
  • The name of the handler function is index.handler (“index” is the name of the file and “handler” is the function name)

CDK diff

Save your code, and let’s take a quick look at the cdk diff before we deploy:

cdk diff sls-app

CDK deploy

cdk deploy sls-app

You’ll notice that cdk deploy not only deployed your CloudFormation stack, but also archived and uploaded the lambda directory from your disk to the bootstrap bucket.