Amazon web services CloudFormation—将条件、伪参数和内在函数一起使用来定义单个资源属性
我有一个CloudFormation模板,它定义了两个条件。如果我们在us-west-2(支持网络ELB的地方)中启动堆栈,那么它会将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,如下所示。根据区域和条件,它
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绑定在一起的正确方法是什么,以便将单个字符串的列表(导致对NoValue或NLB的!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"