阻止 CloudFormation 从 CloudFront 中删除 Lambda 边缘关联
Posted
技术标签:
【中文标题】阻止 CloudFormation 从 CloudFront 中删除 Lambda 边缘关联【英文标题】:Prevent CloudFormation to remove Lambda Edge associations from CloudFront 【发布时间】:2018-07-29 20:01:27 【问题描述】:我正在使用 CloudFormation 来管理 CloudFront 分配。
在这个 CloudFront 分布上,我关联了一个 Lambda Edge 函数(不使用 CloudFormation)。
问题出在后面,当我使用相同的 CloudFormation 堆栈更新 CloudFront 分配时,它删除了所有 Lambda Edge 关联。
如何预防?
真是可惜了。。
PS:有时 CloudFormation 会删除 Lambda 关联(例如在更新证书 ARN 时),有时不会。
编辑:我可以尝试使用https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html,但有没有更简单的方法?不..
编辑:AWS 论坛 https://forums.aws.amazon.com/thread.jspa?threadID=274111 上的相同问题(需要登录)
【问题讨论】:
我怀疑问题的核心在于 CloudFormation 可以说是在做正确的事情 - CloudFrontUpdateDistribution
API action 是一个整体操作,其中必须指定分发的所有属性,而不仅仅是更改.控制台隐藏了这种复杂性。 CloudFormation 可能只是将其更改为“应该”的样子。
@michael-sqlbot 是的.. 但是我应该如何添加 Lambda 关联?.. 看起来像 AWS“错误”。我认为将 Lambda 关联与 CloudFront 分配本身去关联是有意义的。也许 AWS 认为 Lambda Edge 和 CloudFront 高度耦合(但这太糟糕了)
它们非常高度耦合。事实上,这是一种轻描淡写的说法。 Lambda@Edge 是 CloudFront 的一部分——该部分能够挂钩请求和响应并调用 Lambda 函数。触发器(时间和功能)是缓存行为的属性。如果 CloudFormation 控制您的分配,您似乎应该从那里添加 Lambda 触发器,而不是直接添加。
是的,它们看起来高度耦合。问题是我有 3 Lambda@Edge 用于具有自己生命周期的不同事件(源响应、源请求、查看器响应)......还有 那些相同的 3 Lambda@Edge b> 用于 5 个不同的 CloudFront 分配。我被困住了。也许我的架构违背了 AWS 对 Lambda@Edge 的愿景:-/
【参考方案1】:
可以使用 CloudFormation 为 CloudFront“部署”新的 Lambda@Edge 函数。
CloudFront 和 Lambda@Edge 需要版本化的 Lambda 函数。因此,您需要确保您的 CloudFront 模板发布有关 Lambda 代码更改的新版本,并且您的 Distribution 使用版本别名。
查看我的boilerplate Go/Lambda 应用程序中的CloudFormation template 以获取工作示例:
WebAuthFunction:
Properties:
AutoPublishAlias: Live
CodeUri: ./web/handlers/auth/index.zip
Environment: !Ref AWS::NoValue
FunctionName: !Sub $AWS::StackName-WebAuthFunction
Handler: index.handler
Role: !GetAtt WebAuthFunctionRole.Arn
Runtime: nodejs6.10
Type: AWS::Serverless::Function
WebDistribution:
Condition: WebDomainNameSpecified
Properties:
DistributionConfig:
Aliases:
- !Ref WebDomainName
Comment: !Sub Distribution for $WebBucket
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
Compress: true
ForwardedValues:
Cookies:
Forward: none
QueryString: true
LambdaFunctionAssociations:
- !If
- OAuthClientIdSpecified
- EventType: viewer-request
LambdaFunctionARN: !Ref WebAuthFunction.Version
- !Ref AWS::NoValue
TargetOriginId: !Ref WebBucket
ViewerProtocolPolicy: redirect-to-https
DefaultRootObject: index.html
Enabled: true
HttpVersion: http2
Origins:
- DomainName: !Sub $WebBucket.s3.amazonaws.com
Id: !Ref WebBucket
S3OriginConfig:
OriginAccessIdentity: !Sub origin-access-identity/cloudfront/$WebOriginAccessIdentity
PriceClass: PriceClass_All
ViewerCertificate:
AcmCertificateArn: !Ref WebCertificate
SslSupportMethod: sni-only
Type: AWS::CloudFront::Distribution
【讨论】:
我已经在使用 CloudFormation 模板来部署我的 Lambda@Edge 函数。但是,当我更新我的 CloudFront 分配(使用另一个 CloudFormation 模板)时,所有关联/触发器都消失了 您有两个 CloudFormation 模板在单个 CloudFront 分配上运行?您是否在 CloudFormation 中使用 Lambda 版本和别名?在此处查看本指南,因为这对我有用。 github.com/awslabs/serverless-application-model/blob/master/…。注意我使用的是 CloudFormation 的 SAM 方言 对于 CloudFormation,模板是源。因此,如果您在没有 lambda 关联的情况下应用模板,它将删除以前手动或由另一个模板设置的关联。以上是关于阻止 CloudFormation 从 CloudFront 中删除 Lambda 边缘关联的主要内容,如果未能解决你的问题,请参考以下文章
在 Spring Cloud AWS 中禁用 Cloudformation
CloudFormation API Gateway CORS 问题访问 XMLHttpRequest 被阻止
如何从 Cloud Formation 获取 Elastic Container Repository URI?