带有 SAM 的 API 网关未正确更新

Posted

技术标签:

【中文标题】带有 SAM 的 API 网关未正确更新【英文标题】:API Gateway with SAM isn't updated correctly 【发布时间】:2018-06-02 04:00:22 【问题描述】:

我们使用 Cloud Formation 来定义一堆 Lambda 函数:

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

Resources:
  MyLambda:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: com.handler::MyLambda
      Runtime: java8
      CodeUri: .
      Description: Some desc
      MemorySize: 512
      Timeout: 15
      Role: !Ref LambdaRole
      FunctionName: MyLambda
      Events:
        MyLambdaEvt:
          Type: Api
          Properties:
            RestApiId: !Ref MyApiDef
            Path: /lambda/my
            Method: get

  MyApiDef:
    Type: AWS::Serverless::Api
    Properties:
      DefinitionUri: s3://a-bucket/api-gateway.yml
      StageName: prod

Outputs:
  ApiUrl:
    Description: URL of your API endpoint
    Value: !Join
      - ''
      - - https://
        - !Ref MyApiDef
        - '.execute-api.'
        - !Ref 'AWS::Region'
        - '.amazonaws.com/prod'

CodePipeline 生成一个变更集并执行它。

这样,所有的 Lambda 函数都正确更新了,但 API Gateway 端点没有正确更新,我们需要手动导入和部署 s3://a-bucket/api-gateway.yml 中的 YML。

【问题讨论】:

堆栈创建/更新过程中是否有任何错误? “API 网关端点未正确更新”是什么意思? 堆栈创建/更新期间没有错误。 Lambda 函数(在 CloudFormation 中定义)已更新,API 端点(在 Swagger 中定义,带有 API Gateway 扩展)根本没有更新。 【参考方案1】:

为什么 API 不更新(有根据的猜测)

为了将更改添加到 change set,CloudFormation 必须检测到更改。如果部署之间的唯一变化(对于MyApiDef)是 S3 上的 .yaml 文件的内容,则 CloudFormation 不会检测到需要添加到更改集中的更改。

如果此 API 定义存在于 CF 模板中,而不是 S3 上的文件中,那么 CF 将(显然)检测每一个更改并为您更新 API。

由于定义存在于 S3 中,并且文件名未更改,因此未检测到更改,因此没有任何更新。

可能的解决方法

您必须让 CloudFormation 相信您的 API 定义发生了一些变化。这两件事对我有用:

每次运行都更新MyApiDef 密钥本身有效。 (MyApiDefv2, MyApiDefv3等) 更新DefinitionUri 作品。 (即版本 S3 中的文件名)。

这些都不是很好,但在 S3 中将版本附加到文件名似乎比其他选项更合理。

可能还有其他方法可以说服 CloudFormation 发生了变化。值得注意的是,我不能Variables 为这个目的工作。

【讨论】:

我现在无法验证,但有根据的猜测似乎很合理,也许我会从 DefinitionUri 切换到 DefinitionBody,在 CodeBuild 阶段动态添加正文(以这种方式 CloudFormation 定义文件不会膨胀)...希望它会起作用:)

以上是关于带有 SAM 的 API 网关未正确更新的主要内容,如果未能解决你的问题,请参考以下文章

如何使用SAM通过API网关配置异步lambda调用?

AWS Cloudformation 将 API 密钥链接到 API 网关

未找到 AWS API 网关

带有 Cognito 的 AWS Lambda API 网关 - 如何使用 IdentityId 访问和更新 UserPool 属性?

在 Ocelot API 网关中间件中返回未授权

API网关和ESB的区别