如何在CloudFormation模板中为Key和Value同时使用!Sub函数?
在CloudFormation中同时替换IAM Role Condition的Key和Value变量
在编写AWS::IAM::Role的CloudFormation模板时,会遇到这样的问题:Condition里StringEquals的Value部分可以通过!Sub正常替换变量,但Key部分(比如oidc.eks.${AWS::Region}.amazonaws.com/id/${ClusterID}:sub)无法直接用!Sub处理,尝试多种写法都会触发模板报错。下面是可行的解决方法:
核心原因
CloudFormation的YAML语法不允许直接在对象的Key位置使用!Sub函数,必须先构造包含动态Key的完整JSON结构,再转换为CloudFormation可识别的对象。
解决方案:用!Sub生成JSON字符串,再通过!FromJson解析
直接生成包含动态Key和Value的StringEquals结构的JSON字符串,再用!FromJson转换为对象,这样就能同时替换Key和Value里的变量。
完整代码示例
Type: "AWS::IAM::Role" Properties: # 省略其他属性(比如RoleName、Description等) AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Federated: !Sub "arn:aws:iam::${AWS::AccountId}:oidc-provider/oidc.eks.${AWS::Region}.amazonaws.com/id/${ClusterID}" Action: "sts:AssumeRoleWithWebIdentity" Condition: !Sub - '{"StringEquals": {"${OidcKey}": "${ServiceAccount}"}}' - OidcKey: !Sub "oidc.eks.${AWS::Region}.amazonaws.com/id/${ClusterID}:sub" ServiceAccount: !Sub "system:serviceaccount:${Namespace}:${ServiceName}"
另一种简化写法
如果变量不多,也可以直接在!Sub的字符串里拼接所有变量:
Condition: !Sub '{"StringEquals": {"oidc.eks.${AWS::Region}.amazonaws.com/id/${ClusterID}:sub": "system:serviceaccount:${Namespace}:${ServiceName}"}}'
为什么之前的写法报错
- 第一种尝试的写法:把
!Sub放在Key位置,YAML解析时会将!Sub视为键的一部分,不符合CloudFormation的语法规则。 - 第二种尝试的写法:直接在Key位置用
!Sub,同样违反了YAML对象键的语法要求,CloudFormation无法识别这种格式。
内容的提问来源于stack exchange,提问作者prosto.vint
相关产品推荐
相关产品推荐

