Safe Deployments with API Gateway and Lambda AutoPublishAlias

Take advantage of the automatic versioning and aliasing of your Lambdas to instantly shift traffic to your new API deployments. Rollback by repointing the problematic Lambda’s alias to the previous version.

TL;DR

  1. Use the Serverless Application Model (SAM) AutoPublishAlias parameter to have CloudFormation automatically version and alias your Lambdas upon deployment
  2. Reference your Lambda Alias from your OpenAPI definition
  3. Deploy

Source Code

The source code and instructions to build and deploy this example to AWS can be found here: https://github.com/karlkyck/api-gateway-lambda-autopublishalias. Running this example on AWS will incur costs so be sure to delete the CloudFormation stacks when you are finished experimenting.

SAM (Serverless Application Model) Template

Begin by defining your SAM template. By specifying the AutoPublishAlias parameter in our Globals section applies the AutoPublishAlias parameter to each of the functions defined in the template.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Parameters:
  DeploymentBucket:
    Type: String

Globals:
  Function:
    Runtime: nodejs10.x
    Timeout: 180
    AutoPublishAlias: live

Resources:

  ApiGatewayApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: live
      EndpointConfiguration: REGIONAL
      DefinitionBody:
        'Fn::Transform':
          Name: AWS::Include
          Parameters:
            Location: !Sub s3://${DeploymentBucket}/openapi.yaml

  ListPostsFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: ListPostsHandler.handler
      CodeUri: ./dist
      Events:
        ApiGatewayApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref ApiGatewayApi
            Path: /api/posts
            Method: get

In the above CloudFormation, ‘live‘ is specified as the Alias name for our newly deployed Lambda. When CloudFormation deploys this Lambda for the first time it will automatically create a new Lambda Version of 1 and a Lambda Alias called ‘live’. CloudFormation will point the Lambda Alias ‘live’ to the newly created Lambda Version 1.

When there is an update to the Lambda code, upon deployment CloudFormation will create a new Lambda Version using the previous Lambda Version number incremented by 1. CloudFormation will then point the Lambda Alias ‘live’ to this new Lambda Version.

The SAM template defines the API Gateway resource that references an OpenAPI specification. The OpenAPI specification describes the API and also links API endpoints to Lambda resources within the SAM template. See how to use OpenAPI with API Gateway for more details.

OpenAPI Specification

The key here is to specify the Lambda Alias when making reference to a Lambda from the OpenAPI specification. If the Lambda Alias is left out when making reference to a Lambda function the API call will not work.

---
openapi: 3.0.0
info:
  title: API Gateway Lambda AutoPublishAlias Example
  version: 1.0.0

paths:
  /api/posts:
    get:
      summary: List Posts
      operationId: listPosts
      responses:
        '200':
          description: Retrieve the list of Posts
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/ListPostsResponseBody'
      x-amazon-apigateway-integration:
        uri:
          Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ListPostsFunction.Arn}:live/invocations
        httpMethod: POST
        type: aws_proxy

components:
  schemas:
    BasePost:
      type: object
      required:
        - title
        - description
        - publishedDate
        - content
      properties:
        title:
          type: string
        description:
          type: string
        publishedDate:
          type: string
          format: date-time
        content:
          type: string
    Post:
      allOf:
        - $ref: '#/components/schemas/BasePost'
        - type: object
          required:
            - id
            - createdDate
            - updatedDate
          properties:
            id:
              type: string
            createdDate:
              type: string
              format: date-time
            updatedDate:
              type: string
              format: date-time
    ListPostsResponseBody:
      type: array
      items:
        $ref: '#/components/schemas/Post'

The important line is:

Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ListPostsFunction.Arn}:live/invocations

Wrapping Up

Upon deployment the API Gateway endpoint will point to a Lambda Alias. If in an emergency a rollback is required the Lambda Alias can be repointed to a previous version. This can be done manually through the AWS Console. There is a way to automate this process which will be covered in a separate blog post.

References