Layered Lambdas: AWS SAM and Python

A bit of code reusability never hurts

Page content

These are the step-by-step instructions on how to add layers to AWS Lambdas - in Python. Will be using base code generated by standard HelloWorld template example.

letters-layers

And yes of course you need to have all Python and AWS SAM things preinstalled and configured.

Generating and running sample project

Now call sam init and answer to the questions the standard way, like this:

sam-init-answers

it will show the summary

sam-init-summary

and will create the project folder with structure and some files. template.yaml is pretty standard.

vs-code-template-yaml

and the function code too (I will clean out extra generated comments)

import json

def lambda_handler(event, context):

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
            # "location": ip.text.replace("\n", "")
        }),
    }

Now let’s build and call this function locally

sam validate && sam build --use-container && sam local invoke HelloWorldFunction --event events/event.json

The end of response should be close to the one below:

.....
START RequestId: 6da35464-7c6a-40b2-bcc0-60796994317a Version: $LATEST
END RequestId: 737ae28d-2b99-49e6-baae-40ab9bb99599
REPORT RequestId: 737ae28d-2b99-49e6-baae-40ab9bb99599  Init Duration: 0.04 ms  Duration: 28.40 ms      Billed Duration: 29 ms  Memory Size: 128 MB     Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}

Adding the layer

Add layer description to template.yaml

Two bits:

  • ApiSharedLayer - block describing it
  • Layers: … - !Ref ApiSharedLayer - in the function that uses it
.....
Resources:
# added code start
    ApiSharedLayer:
        Type: AWS::Serverless::LayerVersion
        Properties:
            ContentUri: api_shared_layer/
            LayerName: api-shared-layer
            Description: My api-shared-layer
            CompatibleRuntimes:
                - python3.9
            RetentionPolicy: Delete                
        Metadata:
            BuildMethod: python3.9   # Required to have AWS SAM build this layer
# added code end

  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
# added code start
      Layers:
        - !Ref ApiSharedLayer
# added code end
      Events:
.....

Add the layer code

into the folder api_shared_layer add some code

layer code

Update function to use this code

import json
from api_version import API_VERSION

def lambda_handler(event, context):

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
            "version": API_VERSION
        }),
    }

Test Run

Again:

sam validate && sam build --use-container && sam local invoke HelloWorldFunction --event events/event.json

The end of response should be close to the one below:

.....
START RequestId: 88eb1887-ae94-479d-a059-f87c4b71a282 Version: $LATEST
END RequestId: 927f7d05-4d13-44ba-9377-03e6d3e8bacf
REPORT RequestId: 927f7d05-4d13-44ba-9377-03e6d3e8bacf  Init Duration: 0.72 ms  Duration: 34.80 ms      Billed Duration: 35 ms  Memory Size: 128 MB     Max Memory Used: 128 MB
{"statusCode": 200, "body": "{\"message\": \"hello world\", \"version\": \"1.1.1\"}"}

Nice.