阻止 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 可以说是在做正确的事情 - CloudFront UpdateDistribution 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?

AWS:Cloud Formation:是不是可以使用多个“DependsOn”?

CloudFormation 跨区域参考

如何使用 cloudformation 模板创建 cloudwatch 事件?