AWS Lambda: shared libraries (and SAM)

Frederique Retsema

In June I wrote a blog series about the AWS Shop Example. In this series, I also wrote about X-Ray [1]. I like X-Ray: you can see how much time each step in a whole concattenation of AWS services takes and how much time it costs to send the response back to the caller.

One of the disadvantages of AWS X-Ray is the size of the library: my zip-files with Lambda functions grew to about 9.5 MB per Lambda function. I used three functions, so I also used 3 x 9.5 MB of libraries. Fortunately, there is a better solution: we can use up to five layers with libraries per Lambda function.

Serverless Application Model

The best way to show you how this works, is using SAM (Serverless Application Model) [2][3]. SAM is a transformation of CloudFormation. CloudFormation will first translate SAM into CloudFormation and then deploy the CloudFormation template.

You can start SAM by creating an empty directory and then entering the command:

sam init

This will ask you some questions. For this blog, choose AWS Quick Start Templates and Python 3.8. The default project name sam-app is fine. Use the “Hello World Example”. The command will create a directory sam-app with different files and directories.

Go into the sam-app directory, and type:

sam build

The first time deployment can be done using

sam deploy --guided --profile amis

The profile part is only necessary when you have multiple accounts in your environment and want to use a specific account. You will be asked some questions and one of those questions is if the configuration should be stored in a file (yes, of course!). After you answered the questions and then deployed the application you will have this hello world application running in minutes.

After the sam init command, you will have a directory with a file called template.yaml. Look into this file. If you ever created a CloudFormation template (or a Terraform configuration file) for an API gateway that calls a Lambda function, then you know that you need about 6 resources to get this working. In SAM, this is just one resource.

Adding a layer

To add a layer to this Lambda function, you can copy and paste the Globals part and Resources part of the template.yaml from below into your own file. This will make some minor changes to the original template file:

  • In the Globals settings the default 3 seconds timeout for a Lambda function is changed into 30 seconds: the first time the Lambda function will start, it will need more than 3 seconds because it also has to load the layer into memory.
  • The Tracing in the Lambda function resource is set to “Active”. This will add an IAM role for X-Ray and it will also switch on the use of X-Ray in the Lambda function.
  • The layer is added as a parameter to the Lambda function and it is also added as a resource, called Libs:
Globals:
  Function:
    Timeout: 30

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Tracing: Active
      Layers:
        - !Ref Libs
      Events:
        HelloWorld:
          Type: Api 
          Properties:
            Path: /hello
            Method: get
  Libs:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: xray-layer
      Description: xray library
      ContentUri: xray-layer
      CompatibleRuntimes:
        - python3.8
    Metadata:
      BuildMethod: makefile

In the layer, you see BuildMethod makefile. The makefile is in the xray-layer directory (“ContentUri”). Create the xray-layer directory and create a makefile in it:

build-Libs:
    mkdir "$(ARTIFACTS_DIR)/python"
    python -m pip install -r requirements.txt -t "$(ARTIFACTS_DIR)/python"

You need to install GNU-Make [4] and Python version 3.8 [5] to let this work. Please mind, that the characters before mkdir and python are tabs, not spaces.

Create in the xray-layer directory also a file requirements.txt, with the content:

aws-xray-sdk

When you build (sam build) and deploy (sam deploy, no –guided or –profile parameters is needed this second time) and then go to the Lambda function in the GUI, you can see that this Lambda function is using your new layer:

In the Lambda function, you can use the Xray library, f.e. by using the following lambda_handler function instead of the original one:

def lambda_handler(event, context):
    from aws_xray_sdk.core import patch
    patch(['botocore'])

    # Do whatever with the boto3 library and X-Ray will connect those services with this Lambda function in the images

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

You will see that the aws_xray_sdk library is not used in the zip file from the Lambda function itself (it is not visible in the folder structure on the left) and despite that, you still can use the library in your code.

When you want to change the code in the SAM directory on your local PC, look in the hello_world directory, the name of the Python file is app.py.

More information about Layers can be found here: https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html .

Links

[1] Blog about X-Ray: https://technology.amis.nl/2020/06/06/aws-shop-example-x-ray/

[2] If you didn’t do so, download and install the AWS CLI ( https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html ). Use the command aws configure to configure your access key and the secret access key.

After that, download and install SAM: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html .

[3] When you prefer to use a github repository to look at the code for Lambda with one layer, then you can use https://github.com/FrederiqueRetsema/AMIS-Blog-AWS, directory Lambda-shared-libraries. You still have to use the commands sam build and sam deploy –guided to deploy the Lambda functions in your own environment.

[4] Download Make: http://gnuwin32.sourceforge.net/packages/make.htm

[5] Download Python version 3.8: https://www.python.org/downloads/release/python-380/

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Next Post

First code and cli free steps with Oracle Database 21c in Oracle Cloud

Oracle Database 21c has been released – for now only in the cloud. Starting to explore – that is what we call playing with it – it easy and free of any charge in the OCI Always Free Tier that includes two Oracle Database instances that now can be 21c […]