API 带有 SAM 的网关未正确更新
API Gateway with SAM isn't updated correctly
我们使用 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 网关端点未正确更新,我们需要在 s3://a-bucket/api-gateway.yml
中手动导入和部署 YML。
为什么 API 不更新(有根据的猜测)
为了将更改添加到 change set,CloudFormation 必须检测更改。如果部署之间唯一发生变化的(MyApiDef
)是 S3 上的 .yaml 文件的内容,CloudFormation 将不会检测到它需要添加到更改集中的更改。
如果此 API 定义存在于 CF 模板中,而不是 S3 上的文件中,CF 将(显然)检测到每个更改并为您更新 API。
由于定义存在于 S3 中,并且文件名未更改,因此未检测到任何更改,因此不会更新任何内容。
可能的解决方法
您必须让 CloudFormation 相信您的 API 定义发生了一些变化。这两件事对我有用:
- 更新
MyApiDef
密钥本身每个 运行 有效。 (MyApiDefv2
,
MyApiDefv3
,等等)
- 更新
DefinitionUri
有效。 (即版本
S3 中的文件名).
这两个都不是很好,但在 S3 中将版本附加到文件名似乎比其他选项更合理。
可能还有其他方法可以让 CloudFormation 相信发生了变化。值得注意的是,我可以 not 让 Variables
为此目的工作。
我们使用 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 网关端点未正确更新,我们需要在 s3://a-bucket/api-gateway.yml
中手动导入和部署 YML。
为什么 API 不更新(有根据的猜测)
为了将更改添加到 change set,CloudFormation 必须检测更改。如果部署之间唯一发生变化的(MyApiDef
)是 S3 上的 .yaml 文件的内容,CloudFormation 将不会检测到它需要添加到更改集中的更改。
如果此 API 定义存在于 CF 模板中,而不是 S3 上的文件中,CF 将(显然)检测到每个更改并为您更新 API。
由于定义存在于 S3 中,并且文件名未更改,因此未检测到任何更改,因此不会更新任何内容。
可能的解决方法
您必须让 CloudFormation 相信您的 API 定义发生了一些变化。这两件事对我有用:
- 更新
MyApiDef
密钥本身每个 运行 有效。 (MyApiDefv2
,MyApiDefv3
,等等) - 更新
DefinitionUri
有效。 (即版本 S3 中的文件名).
这两个都不是很好,但在 S3 中将版本附加到文件名似乎比其他选项更合理。
可能还有其他方法可以让 CloudFormation 相信发生了变化。值得注意的是,我可以 not 让 Variables
为此目的工作。