我有一个CloudFormation模板,它定义了两个条件。如果我们在us-west-2(支持网络ELB IS )中启动堆栈,则会将CreateNetworkLoadBalancer
设置为True。如果我们在sa-east-1(圣保罗,仅支持Classic ELB)中运行此堆栈,则CreateNetworkLoadBalancer
设置为False
,{ {1}}是CreateClassicLoadBalancer
。 (以下示例)
True
该堆栈稍后定义了两个资源,即Network和Classic ELB,如下所示。它根据区域和条件仅旋转适当的LB.这一切都按预期工作。 (以下示例)
Conditions:
CreateClassicLoadBalancer: !Equals [ !Ref "AWS::Region", sa-east-1 ]
CreateNetworkLoadBalancer: !Equals [ !Ref "AWS::Region", us-west-2 ]
通过堆栈更新,我们现在想要添加代码以将现有的Load Balancer(基于该区域配置的Load Balancer)与AutoScaling组相关联。为此,AutoScaling为每个(网络负载均衡器目标组Resources:
######################################################
# Network Load Balancer, Target Group, etc.
# NLB
NLB:
Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
Condition: CreateNetworkLoadBalancer
Properties:
LoadBalancerAttributes:
- Key: deletion_protection.enabled
Value: False
Name: !Join [ "-", [ !Ref awsTagsNamePrefix, "nlb" ] ]
Scheme: internet-facing
Subnets: !Ref bastionSubnetList
Tags:
- Key: Environment
Value: !Ref awsTagsEnvironment
- Key: Application
Value: !Ref awsTagsApplication
- Key: Name
Value: !Join [ "-", [ !Ref awsTagsNamePrefix, "nlb" ] ]
Type: network
IpAddressType: ipv4
# target group
NLBTargetGroup:
Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
Condition: CreateNetworkLoadBalancer
Properties:
HealthCheckIntervalSeconds: 30
HealthCheckPort: 22
HealthCheckProtocol: TCP
HealthCheckTimeoutSeconds: 10
HealthyThresholdCount: 3
Name: !Join [ "-", [ !Ref awsTagsNamePrefix, "elb-target-group" ] ]
Port: 22
Protocol: TCP
Tags:
- Key: Environment
Value: !Ref awsTagsEnvironment
- Key: Application
Value: !Ref awsTagsApplication
- Key: Name
Value: !Join [ "-", [ !Ref awsTagsNamePrefix, "elb-target-group" ] ]
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 0
UnhealthyThresholdCount: 3
VpcId: !Select [0, !Ref vpcIdList]
# Listener
NLBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Condition: CreateNetworkLoadBalancer
Properties:
DefaultActions:
- TargetGroupArn: !Ref NLBTargetGroup
Type: forward
LoadBalancerArn: !Ref NLB
Port: 22
Protocol: TCP
######################################################
######################################################
# Classic ELB - for regions that do not yet support a Network LB.
# ELB
ELB:
Type: "AWS::ElasticLoadBalancing::LoadBalancer"
Condition: CreateClassicLoadBalancer
Properties:
Subnets: !Ref bastionSubnetList
HealthCheck:
HealthyThreshold: '3'
Interval: '10'
Target: TCP:22
Timeout: '5'
UnhealthyThreshold: '3'
ConnectionSettings:
IdleTimeout: '60'
CrossZone: 'true'
SecurityGroups:
- Ref: BastionELBSG
Listeners:
- InstancePort: '22'
LoadBalancerPort: '22'
Protocol: TCP
InstanceProtocol: TCP
LoadBalancerName: !Join [ "-", [ !Ref awsTagsNamePrefix, "bastion-elb" ] ]
Tags:
- Key: Environment
Value: !Ref awsTagsEnvironment
- Key: Application
Value: !Ref awsTagsApplication
- Key: Name
Value: !Join [ "-", [ !Ref awsTagsNamePrefix, "bastion-elb" ] ]
和经典ELB的TargetGroupARNs
分别具有属性。我们在LoadBalancerNames
中定义两者,并依赖于条件的True / False值,内部函数(AWS::AutoScaling::AutoScalingGroup
)和Fn::If
伪参数。从理论上讲,下面的代码应该可行。
AWS::NoValue
然而,Yaml的语法/格式不正确 - 我们在运行堆栈时遇到以下错误(属性TargetGroupARNs的值必须是String类型的列表)。
将If,条件和NoValue绑定在一起的正确方法是什么,以便单个String的列表(导致!Ref到 NoValue 或 NLB )被赋值为TargetGroupARNs:
!If
- CreateNetworkLoadBalancer
- !Ref NLBTargetGroup
- !Ref "AWS::NoValue"
LoadBalancerNames:
!If
- CreateClassicLoadBalancer
- !Ref ELB
- !Ref "AWS::NoValue"
的值?
TargetGroupARNs
答案 0 :(得分:2)
我认为您最好在资源上使用conditions创建两个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
答案 1 :(得分:1)
在YAML中,您可以使用两个短划线- -
来创建列表列表:
Prop:
- - one
- two
- three
- - red
- blue
因此,对于绑定到列表属性的!If
语句,您将第二个值包装在子列表中:
TargetGroupARNs:
!If
- CreateNetworkLoadBalancer
- - !Ref NLBTargetGroup
- !Ref "AWS::NoValue"
查看我自己的脚本看起来AWS::NoValue
不需要被包装,但如果你在第二个块中有一个不同的!Ref
,那么它也需要是一个子列表。