首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >拆分从SecretsManager加载的字符串

拆分从SecretsManager加载的字符串
EN

Stack Overflow用户
提问于 2020-06-02 22:18:58
回答 1查看 134关注 0票数 0

我正在尝试创建一个ListenerRule,它将只接受从Secrets Manager加载的特定IP地址。以下是我的原始代码:

代码语言:javascript
复制
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时,它工作得很好:

代码语言:javascript
复制
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的硬编码路径:

代码语言:javascript
复制
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中时,它似乎工作正常。

我在这里做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2020-06-03 14:37:24

我不能提供完整的答案,因为我同意@OleksiiDonoha,并且我相信在创建变更集期间,在执行所有内部函数之后,resolve:secretsmanager是最后解析的。

然而,我想澄清这一声明:

Split这个错误本身表明!

做了一些事情,因为CloudFormation不报告错误,属性值的类型必须是字符串列表。

Select不同,!Split只使用String,而不使用字符串列表。此外,如果您提供了错误的分隔符,它将只返回原始字符串。

因此,我认为,Split正在发生的事情如下:

在表达式中:

代码语言:javascript
复制
  Values:
    - !Split [ ';', !Sub '{{resolve:secretsmanager:/${ProjectName}/${EnvType}/${ServiceName}:SecretString:ALLOWED_IPS}}' ]

!Sub首先执行,您最终得到(例如):

代码语言:javascript
复制
  Values:
    - !Split [ ';', '{{resolve:secretsmanager:/MyProject/TestType/MyService:SecretString:ALLOWED_IPS}}' ]

然后,!Split执行并尝试按;拆分字符串'{{resolve:secretsmanager:/MyProject/TestType/MyService:SecretString:ALLOWED_IPS}}'。它不能,因此你最终会得到:

代码语言:javascript
复制
  Values:
    - '{{resolve:secretsmanager:/MyProject/TestType/MyService:SecretString:ALLOWED_IPS}}'

最后,现在这个问题得到了解决,结果是:

代码语言:javascript
复制
  Values:
    - "1.2.3.4/32;2.3.4.5/32;4.5.6.7/29;5.6.7.8/32"

这可以解释你的错误。

我目前看到的唯一解决方案是使用自定义资源,它将在内部函数求值之前或通过内部堆栈获取秘密。

或者,您可以链接堆栈(一个堆栈产生的输出进入下一个堆栈的参数)您可以在第一个堆栈中解析秘密,然后将CIDRs字符串列表作为参数传递给第二个堆栈。

希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62154143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档