【问题标题】:Conditionally define Elastic Beanstalk environment variable using CloudFormation使用 CloudFormation 有条件地定义 Elastic Beanstalk 环境变量
【发布时间】:2019-07-23 23:18:07
【问题描述】:

我想使用 CloudFormation 模板创建 Elastic Beanstalk。我想定义一个环境变量ENV_VAR_1 并将其值设置为模板参数var1 的值。但是如果var1 是一个空字符串,则根本不希望ENV_VAR_1 存在。 IE。我不希望 ENV_VAR_1 没有价值。

首先我尝试了Conditions,但在创建ElasticBeanstalkEnvironment 资源期间我得到了"Encountered unsupported property Condition"

Parameters:
  var1:
    Type: String

Conditions:
  isVar1Empty: !Equals [ !Ref var1, "" ]

Resources:
  ElasticBeanstalkEnvironment:
    Type: 'AWS::ElasticBeanstalk::Environment'
    Properties:
      OptionSettings:
        - Namespace: 'aws:elasticbeanstalk:application:environment'
          Condition: isVar1Empty
          OptionName: ENV_VAR_1
          Value: !Ref var1

然后我尝试了AWS::NoValue

Parameters:
  var1:
    Type: String

Resources:
  ElasticBeanstalkEnvironment:
    Type: 'AWS::ElasticBeanstalk::Environment'
    Properties:
      OptionSettings:
        - Namespace: 'aws:elasticbeanstalk:application:environment'
          OptionName: ENV_VAR_1
          Value: !If [[!Equals [ !Ref var1, "" ]], !Ref 'AWS::NoValue', !Ref var1]

和许多排列组合。结果相同:当var1 为空时,将创建Elastic Beanstalk,并将ENV_VAR_1 设置为""

【问题讨论】:

  • !Equals 在 Fn::If 块中是不允许的......所以你上面所说的将不起作用。是的,我知道您的问题是如果不满足条件,如何避免设置变量(甚至设置为 null 或空字符串),但只是指出这一点,这样其他人就不会对共享的代码中的明显错误感到困惑

标签: amazon-web-services environment-variables amazon-cloudformation amazon-elastic-beanstalk


【解决方案1】:

在选项级别处理条件的另一种解决方法:

Conditions:    
    CreateProdResources: !Equals [!Ref Env, "prod"]

EBEnvironment:
    Type: AWS::ElasticBeanstalk::Environment
    Properties: 
      OptionSettings: 
       - Namespace : "aws:elasticbeanstalk:command"
         OptionName: Timeout
         Value : 1200
       - Namespace : !If [CreateProdResources, "aws:elbv2:listener:443", "aws:elasticbeanstalk:command"]
         OptionName: !If [CreateProdResources, Protocol, Timeout]
         Value : !If [CreateProdResources, HTTPS, 1200]
       - Namespace : !If [CreateProdResources, "aws:elbv2:listener:443", "aws:elasticbeanstalk:command"]
         OptionName: !If [CreateProdResources, SSLPolicy, Timeout]
         Value : !If [CreateProdResources, "ELBSecurityPolicy-2016-08", 1200]
       - Namespace : !If [CreateProdResources, "aws:elbv2:listener:443", "aws:elasticbeanstalk:command"]
         OptionName: !If [CreateProdResources, SSLCertificateArns, Timeout]
         Value : !If [CreateProdResources, !Ref ACMCertificate, 1200]

重复选项在 Elastic Beanstalk 中只考虑一次。

【讨论】:

  • 好建议,但设置超时也有它自己的考虑。我猜逻辑是找到一个安全的参数,即使它是重新设置默认值,并将其用作后备。这可以节省很多代码行,尤其是对于像 elasticbeanstalk 这样的冗长资源
  • Timeout 是我在我的场景中使用的一个示例。您可以使用已在 EB 环境中使用的任何参数。是的,我们甚至可以重新设置默认值来实现这一点。
【解决方案2】:

条件将应用于资源级别...目前,您无法将条件应用于特定属性。

您可以做些什么来满足这些确切的要求(这有点难看),就是创建两个条件,一个否定另一个。然后在这两个条件下,让他们有条件地创建特定的资源。

Parameters:
  var1:
    Type: String

Conditions:
  isVar1Empty: !Equals [ !Ref var1, "" ]
  isVar1NonEmpty: !Not [ !Equals [ !Ref var1, "" ] ]

Resources:
  ElasticBeanstalkEnvironmentWithVar1:
    Type: 'AWS::ElasticBeanstalk::Environment'
    Condition: isVar1NonEmpty
    Properties:
      OptionSettings:
        - Namespace: 'aws:elasticbeanstalk:application:environment'
          OptionName: ENV_VAR_1
          Value: !Ref var1
  ElasticBeanstalkEnvironmentWithoutVar1:
    Type: 'AWS::ElasticBeanstalk::Environment'
    Condition: isVar1Empty
    Properties:
      OptionSettings:
        - Namespace: 'aws:elasticbeanstalk:application:environment'

就像我说的……有点难看。请注意,只有当您有一个或两个这样的变量时,这才会真正有效。一旦您添加第二个或第三个“可选”参数,这很快就会开始失控。

更好的选择可能是使用 mustache 之类的模板库生成 CloudFormation 模板。

【讨论】:

  • 是的,这比我拥有 2 个单独模板的备份计划要好一些。谢谢!
  • 不适合占用多行代码的资源。好的建议,我猜,对于更短的代码行,或者如果一个人真的很绝望
猜你喜欢
  • 1970-01-01
  • 2012-12-13
  • 2014-08-25
  • 2015-08-05
  • 2022-01-07
  • 2020-11-09
  • 2017-07-24
  • 2015-06-08
  • 2015-04-02
相关资源
最近更新 更多