如何在 Cloud Formation 模板中使列表项有条件?

Posted

技术标签:

【中文标题】如何在 Cloud Formation 模板中使列表项有条件?【英文标题】:How to make a list item conditional in Cloud Formation template? 【发布时间】:2018-01-21 17:01:02 【问题描述】:

我有以下创建代码管道的云形成模板。管道分为三个阶段:

  Stages:
    -
      Name: "Source"
      Actions:
        -
          Name: "Source"
          ActionTypeId:
            Category: "Source"
            Owner: "ThirdParty"
            Version: "1"
            Provider: "GitHub"
          OutputArtifacts:
            - Name: "MyApp"
          Configuration:
            Owner: !Ref GithubOwner
            Repo: !Ref GithubRepo
            PollForSourceChanges: "true"
            Branch: !Ref GithubBranch
            OAuthToken: !Ref GithubTokenParameter
          RunOrder: 1
    -
      Name: "Run-Unit-Tests"
      Actions:
        -
          InputArtifacts:
            - Name: "MyApp"
          Name: "UnitTests"
          ActionTypeId:
            Category: "Test"
            Owner: "AWS"
            Version: "1"
            Provider: "CodeBuild"
          OutputArtifacts:
            - Name: "MyTests"
          Configuration:
          ProjectName: !Ref CodeBuildName
          RunOrder: 1
    -
      Name: "Deploy-Staging"
      Actions:
        -
          InputArtifacts:
            - Name: "MyApp"
          Name: "Deploy-Staging"
          ActionTypeId:
            Category: "Deploy"
            Owner: "AWS"
            Version: "1"
            Provider: "ElasticBeanstalk"
          Configuration:
            ApplicationName: !Ref BeanstalkApplicationName
            EnvironmentName: !Ref BeanstalkEnvironmentStaging
          RunOrder: 1

我也有一个条件:

IncludeStagingEnv: !Equals [Staging, !Ref CodePipelineEnvironment]

当条件为假时,我想省略代码管道阶段列表中的第 3 项。

我尝试将 !If 与 AWS::NoValue 一起使用,但 NoValue 不是有效的列表项:

Stages:
  - !IF
    - IncludeStagingEnv
    - Name: "Deploy-Staging"
      Actions:
        -
          InputArtifacts:
            - Name: "MyApp"
          Name: "Deploy-Staging"
          ActionTypeId:
            Category: "Deploy"
            Owner: "AWS"
            Version: "1"
            Provider: "ElasticBeanstalk"
          Configuration:
            ApplicationName: !Ref BeanstalkApplicationName
            EnvironmentName: !Ref BeanstalkEnvironmentStaging
            RunOrder: 1
    - AWS::NoValue

IncludeStagingEnv==false时如何省略最后一项?

【问题讨论】:

【参考方案1】:

我的 Cloudfront 分发模板也出现了同样的问题。

解决方案是使用AWS::NoValue Ref 属性。

...
LambdaFunctionAssociations: 
  Fn::If: 
    - Authentication
    - - EventType: "viewer-request"
        LambdaFunctionARN: "arn:aws:lambda:us-east-1:..."
    - - Ref: "AWS::NoValue"
...

如果这适用于所有资源,您应该将条件部分更改为:

Stages:
  - !If
    - IncludeStagingEnv
    - - Name: "Deploy-Staging"
        Actions:
          - InputArtifacts:
            ...
    - - Ref: "AWS::NoValue"

希望这会有所帮助!

【讨论】:

【参考方案2】:

@Fabi755 的回答让我走上了正确的道路,谢谢!

我正在与同样的LambdaFunctionAssociations 挑战作斗争。我选择了一种稍微不同,稍微好一点的方法,如下所示。我认为更好的是它适用于多个可选列表项。

          LambdaFunctionAssociations:
          - !If
            - HasOriginResponseFunctionArn
            - EventType: origin-response
              LambdaFunctionARN: !Ref OriginResponseFunctionArn
            - !Ref AWS::NoValue
          - !If
            - HasViewerRequestFunctionArn
            - EventType: viewer-request
              LambdaFunctionARN: !Ref ViewerRequestFunctionArn
            - !Ref AWS::NoValue

【讨论】:

我需要在 CloudFront 设置中做这件事,并认为这是要走的路,但并不期待必须部署很多次才能确保它做到了。感谢您发布此信息! 正是我想要有条件地设置 LambdaFunctionAssociations。谢谢!

以上是关于如何在 Cloud Formation 模板中使列表项有条件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在各种 .NET ORM 中使列成为自动递增的主键?

如何使用 Cloud Formation 模板在 S3 存储桶上设置 SSE-S3 或 SSE-KMS 加密?

如何在 Ruby on Rails 迁移中使列唯一并为其编制索引?

Cloud Formation 模板将入口规则添加到现有安全组

如何在 Elastic Beanstalk Cloud Formation 脚本中强制 ELB 配置

我能否在 SAM 模板中使用 AWS Cloud Formation 资源语法,反之亦然?