我正在尝试使用AWS CloudFormation模板创建EC2实例,并使用模板中的动态引用和跨栈引用生成一些用户数据。在AWS Systems Manager参数存储中有一个参数Name:/MyCustomParameter
和Value:Test1
。
此想法是将参数传递给模板堆栈(堆栈A),该模板堆栈引用另一个云信息堆栈(StackB)。堆栈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'
答案 0 :(得分:0)
我认为这是因为解决方法位于base64中,也许...?当处理该行时,它只会看到一个base64块,而不是{{resolve ...}}代码。比“!函数”晚些处理“解析”,因为在代码运行之前无法解析它们。
要解决此问题,我添加了一个临时SSM参数:
eksCAtmp:
Type: "AWS::SSM::Parameter"
Properties:
Type: String
Value:
Fn::Join:
- ''
- - '{{resolve:ssm:'
- Fn::ImportValue:
!Sub "${ClusterName}-EksCA"
- ':1}}'
那将导入原始的SSM参数,并摆脱了“导入”并再次解决它的要求。因此,现在您可以使用!GetAtt eksCAtemp.Value
例如:
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
(当然,如果它们允许跨堆栈导出超过1024个字符,则在专用网络上启动EKS时不需要此。)