我正在尝试创建一个ListenerRule,它将只接受从Secrets Manager加载的特定IP地址。以下是我的原始代码:
LoadBalancerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- TargetGroupArn: !Ref 'TargetGroup'
Type: 'forward'
Conditions:
Fn::If:
- IsProdEnvironment
- - Field: host-header
Values:
- !Ref 'BaseUrl'
- - Field: host-header
Values:
- !Ref 'BaseUrl'
- Field: source-ip
SourceIpConfig:
Values:
- !Split [ ';', !Sub '{{resolve:secretsmanager:/${ProjectName}/${EnvType}/${ServiceName}:SecretString:ALLOWED_IPS}}' ]上面的解析似乎工作正常,并被解析为类似1.2.3.4/32;2.3.4.5/32;4.5.6.7/29;5.6.7.8/32的字符串(地址显然是模糊的,但数量和子网掩码是相同的)。
但是,当我尝试部署模板时,我得到一个错误:
The specified value '1.2.3.4/32;2.3.4.5/32;4.5.6.7/29;5.6.7.8/32' is not a valid CIDR block (Service: AmazonElasticLoadBalancingV2; Status Code: 400; Error Code: ValidationError; Request ID: error-id)
这个错误本身表明!Split做了一些事情,因为CloudFormation不报告错误Value of property Values must be of type List of String。显然,字符串被转换为一个包含一个元素的列表,但它并没有被;字符分割成4个字符串的列表。
此外,当我尝试运行非常相似的代码,但使用硬编码的值而不是secret时,它工作得很好:
LoadBalancerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- TargetGroupArn: !Ref 'TargetGroup'
Type: 'forward'
Conditions:
Fn::If:
- IsProdEnvironment
- - Field: host-header
Values:
- !Ref 'BaseUrl'
- - Field: host-header
Values:
- !Ref 'BaseUrl'
- Field: source-ip
SourceIpConfig:
Values:
!Split [';', '1.2.3.4/32;2.3.4.5/32;4.5.6.7/29;5.6.7.8/32' ]我还检查了没有!Sub的版本,但有指向Secret value的硬编码路径:
LoadBalancerRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- TargetGroupArn: !Ref 'TargetGroup'
Type: 'forward'
Conditions:
Fn::If:
- IsProdEnvironment
- - Field: host-header
Values:
- !Ref 'BaseUrl'
- - Field: host-header
Values:
- !Ref 'BaseUrl'
- Field: source-ip
SourceIpConfig:
Values: !Split [';', '{{resolve:secretsmanager:/dummy-project/dev/foo:SecretString:ALLOWED_IPS}}']结果,我得到了与第一种情况相同的错误:长字符串没有拆分成更小的部分。
更奇怪的是..。这是相当大的模板的一部分,但当我将此资源复制到一个简单的test.yaml中时,它似乎工作正常。
我在这里做错了什么?
发布于 2020-06-03 14:37:24
我不能提供完整的答案,因为我同意@OleksiiDonoha,并且我相信在创建变更集期间,在执行所有内部函数之后,resolve:secretsmanager是最后解析的。
然而,我想澄清这一声明:
Split这个错误本身表明!
做了一些事情,因为CloudFormation不报告错误,属性值的类型必须是字符串列表。
与Select不同,!Split只使用String,而不使用字符串列表。此外,如果您提供了错误的分隔符,它将只返回原始字符串。
因此,我认为,Split正在发生的事情如下:
在表达式中:
Values:
- !Split [ ';', !Sub '{{resolve:secretsmanager:/${ProjectName}/${EnvType}/${ServiceName}:SecretString:ALLOWED_IPS}}' ]!Sub首先执行,您最终得到(例如):
Values:
- !Split [ ';', '{{resolve:secretsmanager:/MyProject/TestType/MyService:SecretString:ALLOWED_IPS}}' ]然后,!Split执行并尝试按;拆分字符串'{{resolve:secretsmanager:/MyProject/TestType/MyService:SecretString:ALLOWED_IPS}}'。它不能,因此你最终会得到:
Values:
- '{{resolve:secretsmanager:/MyProject/TestType/MyService:SecretString:ALLOWED_IPS}}'最后,现在这个问题得到了解决,结果是:
Values:
- "1.2.3.4/32;2.3.4.5/32;4.5.6.7/29;5.6.7.8/32"这可以解释你的错误。
我目前看到的唯一解决方案是使用自定义资源,它将在内部函数求值之前或通过内部堆栈获取秘密。
或者,您可以链接堆栈(一个堆栈产生的输出进入下一个堆栈的参数)您可以在第一个堆栈中解析秘密,然后将CIDRs字符串列表作为参数传递给第二个堆栈。
希望这能有所帮助。
https://stackoverflow.com/questions/62154143
复制相似问题