【发布时间】:2021-09-10 16:41:12
【问题描述】:
我正在尝试将现有负载均衡器导入 CloudFormation 堆栈。监听器必须指定为 YAML 列表,但列表(数组)或对象没有 CloudFormation 参数类型,因此 YAML 列表的参数必须是字符串。这导致以下 CloudFormation 错误
属性Listeners的值必须是List类型
使用 CLI 设置侦听器的字符串参数值 -
aws elb describe-load-balancers --load-balancer-names $ELB_DNS_NAME --query 'LoadBalancerDescriptions[0].ListenerDescriptions[].Listener' | jq --compact-output '.' | sed -e 's/"/\\"/g'
请注意,上述命令生成的 JSON 已转义。我怀疑这是问题的根本原因。
[
...
{
"ParameterKey": "ElbListeners",
"ParameterValue": "[{\"Protocol\":\"TCP\",\"LoadBalancerPort\":443,\"InstanceProtocol\":\"TCP\",\"InstancePort\":31672},{\"Protocol\":\"TCP\",\"LoadBalancerPort\":80,\"InstanceProtocol\":\"TCP\",\"InstancePort\":30545}]"
},
...
]
CloudFormation 似乎没有提供任何取消转义字符串参数的方法,因此以下模板失败。
AWSTemplateFormatVersion: 2010-09-09
Resources:
...
IngressLoadBalancer:
Type: AWS::ElasticLoadBalancing::LoadBalancer
DeletionPolicy: Delete
Properties:
Listeners: !Ref ElbListeners
LoadBalancerName: !Ref ElbName
Parameters:
...
ElbListeners:
Type: String
Description: Listeners for the load balancer
Default: ""
ElbName:
Type: String
Description: Name of the load balancer
Default: ""
将生成的 JSON 中的引号替换为参数文件中的 ${quote},然后将 ${quote} 替换为使用 !Sub 的引号失败。 !Sub 的第一个输入似乎不能是 !Ref ParameterName。
我不知道会有多少侦听器,因此在模板中硬编码侦听器列表并为端口/协议传递多个参数是不可行的。
如何将 YAML 列表作为 JSON 字符串参数传递?
【问题讨论】:
-
愚蠢的问题:我对 YAML 没有那么丰富的经验,但是如果模板是在 YAML 中,那么侦听器列表不能/不应该在 YAML 中吗?请参阅此处并向下滚动到 YAML 示例:docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…
-
我查看了文档。我不相信它实际上是在期待一个 JSON 字符串。它需要一个“类型:听众列表”docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…。因此,即使您可以做到,我认为在 YAML 中传递 JSON 字符串也不会成功。我是否可以为侦听器的每个值建议一个逗号分隔列表,然后为每种类型使用参数。然后使用 Fn::Select。这当然假设您有已知数量的侦听器,因为没有 for 循环逻辑。
-
@TimBassett - 是的,这就是问题所在。这不是与负载均衡器相关的问题,而是与 CloudFormation 相关的问题,其中正在导入的资源恰好是负载均衡器。 CloudFormation 资源
AWS::ElasticLoadBalancing::LoadBalancer需要一个 YAML 侦听器列表。但是,CloudFormation 似乎没有提供可以通过参数传递 YAML 列表的机制。参数的类型非常有限,只留下String作为一个可行的选项。我正在寻找解决该问题的方法。 -
您是否有已知数量的听众,或者它是可变的?
-
通常是两个(80 和 443),但不能保证。因此需要传递整个列表,而不是传递给每个侦听器的一部分。
标签: yaml amazon-cloudformation