Publishing Lambda Layers using SAR

Gojko Adzic in Serverless 3 minutes

Lambda Layers are a convenient tool to share dependencies across Lambda functions. Many organisations publish utility layers for extending basic Lambda runtimes with tools such as monitoring or logging, but bare-bones layer publishing is problematic for several reasons. First, the layer versions are just incremental numeric sequences, so it’s difficult to know if an update is backwards compatible or not. The second issue is that linking a layer deployed by a third-party organisation effectively binds your code to something outside your control. The third big issue is that linking layers across AWS regions just doesn’t work. All these drawbacks can be solved very easily by publishing a layer through the Serverless Application Repository.

Publishing layers to SAR

The Serverless Application Repository is, as usual for AWS, a bit misnamed. The name suggests that people can find applications in that repository, but it’s effectively a public CloudFormation template store. You can publish many things to it, not just applications (whatever that means in the serverless ecosystem). For this particular topic, it’s important to know that you can publish a CloudFormation template containing just a Lambda Layer. There are several benefits of publishing a layer to SAR instead of directly making it available to other accounts:

  • SAR applications support semantic versioning, so you can signal major, minor and patch releases to clients
  • SAR applications are deployed to client accounts, so someone linking a SAR application will effectively create a copy in their own AWS account instead of depending on some third-party service availability
  • It’s easy to make SAR applications private, share them with individual AWS accounts or make them public and accessible to everyone
  • Public SAR applications are automatically replicated across all regions, so someone can just publish a layer in a single place and clients from all AWS regions can use it easily
  • The SAR web portal provides a way to discover published applications easily

To publish a layer to SAR, you’ll need a CloudFormation template that provides a Metadata section, with an AWS::ServerlessRepo::Application resource describing the thing you are publishing. Make sure to include the layer reference in the template outputs, so clients installing this application can use it.

Here is a simple example, from the ImageMagick layer compatible with AWS Linux 2.

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: >
  Static build of ImageMagick for Amazon Linux 2,
Resources:
  ImageMagickLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: image-magick
      Description: Static build of ImageMagick for AWS Linux 2,
      ContentUri: build/layer.zip
      CompatibleRuntimes:
        - nodejs10.x
      LicenseInfo: https://imagemagick.org/script/license.php
      RetentionPolicy: Retain

Outputs:
  LayerVersion:
    Description: Layer ARN Reference
    Value: !Ref ImageMagickLayer

Metadata:
  AWS::ServerlessRepo::Application:
    Name: image-magick-lambda-layer
    Description: >
      Static build of ImageMagick for Amazon Linux 2,
    Author: Gojko Adzic
    SpdxLicenseId: ImageMagick
    LicenseUrl: LICENSE.txt
    ReadmeUrl: README-SAR.md 
    Labels: ['layer', 'image', 'lambda', 'imagemagick']
    HomePageUrl: https://github.com/serverlesspub/imagemagick-aws-lambda-2
    SemanticVersion: 1.0.0
    SourceCodeUrl: https://github.com/serverlesspub/imagemagick-aws-lambda-2

For more information on the metadata section, check out the AWS SAM Template Metadata Section Properties.

With this template, using the SAM command-line tools, you can just run sam publish after sam package and the application will be uploaded to SAR. Note that the uploaded application is private by default, you can make it public and accessible to other AWS accounts using the following command line:

aws serverlessrepo put-application-policy 
  --application-id <APP_ARN>
  --statements Principals='*',Actions=Deploy

How to use layers in your applications

Using SAM, you can deploy the layer and a function from the same template, by including a resource of type AWS::Serverless::Application, and pointing to the application ARN and semantic version in the Location field. Because applications are just CloudFormation templates, you can read out any outputs directly from the Outputs property of the resulting resource. Here is a quick snippet that includes the ImageMagick layer as an application:

Resources:
  ImageMagick:
    Type: AWS::Serverless::Application
    Properties:
      Location:
        ApplicationId: arn:aws:serverlessrepo:us-east-1:145266761615:applications/image-magick-lambda-layer
        SemanticVersion: 1.0.0
  ConvertFileFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: image-conversion/
      Handler: index.handler
      Runtime: nodejs10.x
      Layers:
        - !GetAtt ImageMagick.Outputs.LayerVersion

For some nice examples of layers you can install this way, check out the layers we published for many common Linux file conversion utilities.

For more detailed examples and a walk-through, check out my book Running Serverless.