Amazon cloudformation AWS CloudFormation:使用{{resolve}}的动态引用的嵌套Sub会导致错误,并且不会';t执行resolve以从参数存储中获取值

Amazon cloudformation AWS CloudFormation:使用{{resolve}}的动态引用的嵌套Sub会导致错误,并且不会';t执行resolve以从参数存储中获取值,amazon-cloudformation,aws-cli,amazon-eks,Amazon Cloudformation,Aws Cli,Amazon Eks,我试图使用AWS CloudFormation模板创建一个EC2实例,其中包含一些使用模板中的动态引用和跨堆栈引用生成的用户数据。AWS Systems Manager参数存储中存储了一个参数,其名称为名称:/MyCustomParameter和值为:Test1 其思想是将一个参数传递给模板堆栈(堆栈a),该堆栈引用另一个cloudformation堆栈(堆栈B)。堆栈B导出一个引用为“StackB::ParameterStoreName”的变量。堆栈A使用Fn::ImportValue:'St

我试图使用AWS CloudFormation模板创建一个EC2实例,其中包含一些使用模板中的动态引用和跨堆栈引用生成的用户数据。AWS Systems Manager参数存储中存储了一个参数,其名称为
名称:/MyCustomParameter
值为:Test1

其思想是将一个参数传递给模板堆栈(堆栈a),该堆栈引用另一个cloudformation堆栈(堆栈B)。堆栈B导出一个引用为“StackB::ParameterStoreName”的变量。堆栈A使用
Fn::ImportValue:'StackB::ParameterStoreName'
获取其值,以便可以与动态引用方法一起使用,使用
{{resolve:SSM:/MyCustomParameter:1}
从AWS SSM参数存储获取其值,并将其值传递给模板中的UserData字段。我在尝试将嵌套的
Fn::Sub:
函数用于此用例时遇到了困难

我尝试删除
|
管道,并使用双引号和转义的新行字符,但这不起作用

我还尝试使用不同类型的资源,以及它的属性。下面是一个有效的代码示例

Resources:
  TestBucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      BucketName: 
        Fn::Sub:
          - '${SSMParameterValue}-12345'
          - SSMParameterValue: 
              Fn::Sub:
                - '{{resolve:ssm:${SSMParameterName}:1}}'
                - SSMParameterName: 
                    Fn::ImportValue:
                      !Sub '${CustomStack}::ParameterStoreName'
以下是我当前代码的摘录:

Parameters:
  CustomStack:
    Type: "String"
    Default: "StackB"
Resources:
  MyCustomInstance:  
    Type: 'AWS::EC2::Instance'
        Properties:
        UserData:
            Fn::Base64:
            Fn::Sub:
                - |
                #!/bin/bash -e 
                #
                # Bootstrap and join the cluster 
                /etc/eks/bootstrap.sh --b64-cluster-ca '${SSMParameterValue}' --apiserver-endpoint '${Endpoint}' '${ClusterName}'"
                - SSMParameterValue:
                    Fn::Sub:
                    - '{{resolve:ssm:/${SSMParameterName}:1}}'
                    - SSMParameterName: 
                        Fn::ImportValue:
                            !Sub '${CustomStack}::ParameterStoreName'
                Endpoint:
                    Fn::ImportValue:
                    !Sub '${CustomStack}::Endpoint'
                ClusterName: 
                    Fn::ImportValue:
                    !Sub '${CustomStack}::ClusterStackName'
电流输出:

#!/bin/bash -e 
# 
# Bootstrap and join the cluster 
/etc/eks/bootstrap.sh --b64-cluster-ca `{{resolve:ssm:MyCustomParameter:1}}` --apiserver-endpoint 'https://04F1597P0HJ11FQ54K0YFM9P19.gr7.us-east-1.eks.amazonaws.com' 'eks-cluster-1'
预期产出:

#!/bin/bash -e 
# 
# Bootstrap and join the cluster 
/etc/eks/bootstrap.sh --b64-cluster-ca `Test1` --apiserver-endpoint 'https://04F1597P0HJ11FQ54K0YFM9P19.gr7.us-east-1.eks.amazonaws.com' 'eks-cluster-1'

我认为这是因为解决方案在base64中,也许。。。?当它处理该行时,它只看到一个base64块,而不是{resolve…}}代码。“resolves”将在比!函数,因为在代码运行之前无法解析它们

为了解决这个问题,我添加了一个临时SSM参数:

eksCAtmp:
  Type: "AWS::SSM::Parameter"
  Properties:
    Type: String
    Value:
      Fn::Join:
        - ''
        - - '{{resolve:ssm:'
          - Fn::ImportValue:
              !Sub "${ClusterName}-EksCA"
          - ':1}}'
这将导入原始SSM参数,并取消“导入”并再次解析它的要求。现在您可以使用
!GetAtt eksCAtemp.值

例如:

(当然,如果他们允许跨堆栈导出超过1024个字符,我们就不需要在专用网络上启动EKS了。)

  UserData: !Base64
    "Fn::Sub":
      - |
        #!/bin/bash
        set -o xtrace
        /etc/eks/bootstrap.sh ${ClusterName} --b64-cluster-ca ${CA}  --apiserver-endpoint ${endpoint} --kubelet-extra-args '--read-only-port=10255'
        /opt/aws/bin/cfn-signal --exit-code $? \
                 --stack  ${AWS::StackName} \
                 --resource NodeGroup  \
                 --region ${AWS::Region}
      - endpoint:
          Fn::ImportValue:
            !Sub "${ClusterName}-EksEndpoint"
        CA: !GetAtt eksCAtmp.Value