如何使用lambda版本和别名通过CloudFormation对API进行版本控制?

问题描述

我们有一个需要版本控制的API。我们在AWS上使用API​​ Gateway和Lambda。所有代码都使用CICD部署,我们在CloudFormation顶部使用SAM模板。

请注意,我们正在使用API​​网关阶段来处理不同的环境(例如,阶段“ dev1”指向lambda“ dev1-MyService”。

我们有如下定义的资源“ v1”:

  V1Resource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'v1'

# proxy traffic to a lambda:

  ProxyMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: ANY
...
      Integration:
        Type: AWS_PROXY
        Uri: arn:aws:apigateway:...:function:MyFunction:v1/invocations'

还有一个如下定义的lambda:

  ApiFunction:
    Type: AWS::Serverless::Function
    Properties:
      AutopublishAlias: "v1"
      FunctionName: MyFunction
...


我们想要做的是将v1 lambda保留在系统中,但是当对API进行重大更改时,我们可以定义一个/ v2 /资源,指向lambda的v2别名

我的计划是定义第二个资源(V2Resource)和第二个代理方法,引用lambda的v2别名,我可以通过在同一更改中将AutopublishAlias撞到v2来创建。

然后,v2别名仍然指向旧版本(理论上永远如此),并且从此以后每次部署,API的最新版本都将别名为v2(直到我们需要做一个重大更改并引入v3)。

不幸的是,当我这样做时,它会删除旧的别名v1。

那么我应该如何使用Lambda别名通过API Gateway进行API版本控制?使用CloudFormation和SAM模板吗?

解决方法

您可以使用documentation中的AWS::Lambda::Version资源:

根据当前代码和功能配置创建版本。使用版本来创建功能代码和配置不变的快照。

LambdaVersion:
  Type: AWS::Lambda::Version
    Properties: 
      FunctionName: !Ref ApiFunction
      Description: v1

固定Description属性的位置,因为它不接受更新。此外,您可以为这些版本创建一些别名,例如devstageprod。例如,对于dev版本,将是

DevAlias: 
  Type: AWS::Lambda::Alias 
  Properties: 
    Description: Dev Alias for Lambda function 
    FunctionName: !Ref ApiFunction
    FunctionVersion: !GetAtt LambdaVersion.Version
    Name: DEV