Amazon web services CloudFormation—将条件、伪参数和内在函数一起使用来定义单个资源属性

Amazon web services CloudFormation—将条件、伪参数和内在函数一起使用来定义单个资源属性,amazon-web-services,yaml,amazon-cloudformation,autoscaling,elastic-load-balancer,Amazon Web Services,Yaml,Amazon Cloudformation,Autoscaling,Elastic Load Balancer,我有一个CloudFormation模板,它定义了两个条件。如果我们在us-west-2(支持网络ELB的地方)中启动堆栈,那么它会将CreateNetworkLoadBalancer设置为True。如果我们在sa-east-1(圣保罗,那里只支持经典ELB)中运行此堆栈,则CreateNetworkLoadBalancer设置为False,CreateClassicLoadBalancer为True。(下面的例子) 堆栈稍后定义了两个资源,一个网络和一个经典ELB,如下所示。根据区域和条件,它

我有一个CloudFormation模板,它定义了两个条件。如果我们在us-west-2(支持网络ELB的地方)中启动堆栈,那么它会将
CreateNetworkLoadBalancer
设置为True。如果我们在sa-east-1(圣保罗,那里只支持经典ELB)中运行此堆栈,则
CreateNetworkLoadBalancer
设置为
False
CreateClassicLoadBalancer
True
。(下面的例子)

堆栈稍后定义了两个资源,一个网络和一个经典ELB,如下所示。根据区域和条件,它只会向上旋转适当的磅数。这一切都按预期进行。(下面的例子)

通过堆栈更新,我们现在希望添加代码,将现有负载平衡器(基于区域配置的负载平衡器)关联到自动缩放组。为此,自动缩放对每个对象都有单独的属性(
TargetGroupARNs
用于网络负载平衡器目标组,而
LoadBalancerNames
用于经典ELB)。我们在
AWS::AutoScaling::AutoScalingGroup
中定义,并依赖于条件的真/假值、内在函数(
Fn::If
)和
AWS::NoValue
伪参数。理论上,下面的代码应该可以工作

TargetGroupARNs:
        !If
          - CreateNetworkLoadBalancer
          - !Ref NLBTargetGroup
          - !Ref "AWS::NoValue"
      LoadBalancerNames:
        !If
          - CreateClassicLoadBalancer
          - !Ref ELB
          - !Ref "AWS::NoValue"
但是Yaml的语法/格式不正确-我们在运行堆栈时遇到以下错误(属性TargetGroupARNs的值必须是字符串列表类型)

将If、条件和NoValue绑定在一起的正确方法是什么,以便将单个字符串的列表(导致对NoValueNLB的!Ref)分配给
TargetGroupARNs

BastionASG:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      AvailabilityZones:
        Fn::GetAZs: !Ref "AWS::Region"
      Cooldown: '0'
      DesiredCapacity: '0'
      HealthCheckGracePeriod: '60'
      HealthCheckType: EC2
      MaxSize: '0'
      MinSize: '0'
      VPCZoneIdentifier: !Ref bastionSubnetList
      LaunchConfigurationName:
        Ref: BastionLC
      Tags:
      - Key: Environment
        Value: !Ref awsTagsEnvironment
        PropagateAtLaunch: true
      - Key: Application
        Value: !Ref awsTagsApplication
        PropagateAtLaunch: true
      - Key: Name
        Value: !Join [ "-", [ !Ref awsTagsNamePrefix, "asg-ec2" ] ]
        PropagateAtLaunch: true
      TargetGroupARNs:
        !If
          - CreateNetworkLoadBalancer
          - !Ref NLBTargetGroup
          - !Ref "AWS::NoValue"
      LoadBalancerNames:
        !If
          - CreateClassicLoadBalancer
          - !Ref ELB
          - !Ref "AWS::NoValue"
      TerminationPolicies:
      - OldestInstance

我认为您最好在资源上创建两个
BastionASG
资源

BastionASGElb:
  Type: AWS::AutoScaling::AutoScalingGroup
  Condition: CreateClassicLoadBalancer
  Properties:
    AvailabilityZones:
      Fn::GetAZs: !Ref "AWS::Region"
    Cooldown: '0'
    DesiredCapacity: '0'
    HealthCheckGracePeriod: '60'
    HealthCheckType: EC2
    MaxSize: '0'
    MinSize: '0'
    VPCZoneIdentifier: !Ref bastionSubnetList
    LaunchConfigurationName:
      Ref: BastionLC
    Tags:
    - Key: Environment
      Value: !Ref awsTagsEnvironment
      PropagateAtLaunch: true
    - Key: Application
      Value: !Ref awsTagsApplication
      PropagateAtLaunch: true
    - Key: Name
      Value: !Join [ "-", [ !Ref awsTagsNamePrefix, "asg-ec2" ] ]
      PropagateAtLaunch: true
    LoadBalancerNames:
      - !Ref ELB
    TerminationPolicies:
    - OldestInstance

BastionASGAlb:
  Type: AWS::AutoScaling::AutoScalingGroup
  Condition: CreateNetworkLoadBalancer
  Properties:
    AvailabilityZones:
      Fn::GetAZs: !Ref "AWS::Region"
    Cooldown: '0'
    DesiredCapacity: '0'
    HealthCheckGracePeriod: '60'
    HealthCheckType: EC2
    MaxSize: '0'
    MinSize: '0'
    VPCZoneIdentifier: !Ref bastionSubnetList
    LaunchConfigurationName:
      Ref: BastionLC
    Tags:
    - Key: Environment
      Value: !Ref awsTagsEnvironment
      PropagateAtLaunch: true
    - Key: Application
      Value: !Ref awsTagsApplication
      PropagateAtLaunch: true
    - Key: Name
      Value: !Join [ "-", [ !Ref awsTagsNamePrefix, "asg-ec2" ] ]
      PropagateAtLaunch: true
    TargetGroupARNs:  
      - !Ref NLBTargetGroup
    TerminationPolicies:
    - OldestInstance

在YAML中,可以使用两个破折号
-
创建列表列表:

Prop:
  - - one
    - two
    - three
  - - red
    - blue
所以对于你的
!如果绑定到列表属性的
语句将第二个值包装在子列表中:

TargetGroupARNs:
  !If
    - CreateNetworkLoadBalancer

    - - !Ref NLBTargetGroup

    - !Ref "AWS::NoValue"

看看我自己的脚本,似乎不需要包装
AWS::NoValue
,但是如果您有不同的
!Ref
在第二个块中,它还需要是一个子列表。

是的,这是用另一种方式完成它的好方法。谢谢我会让这个问题再等一段时间,看看是否有人想参与进来。很好的建议,我会尝试一下,看看结果如何。
Prop:
  - - one
    - two
    - three
  - - red
    - blue
TargetGroupARNs:
  !If
    - CreateNetworkLoadBalancer

    - - !Ref NLBTargetGroup

    - !Ref "AWS::NoValue"