如何在AWS CloudFormation YAML模板中转义IAM策略变量?
解决CloudFormation中使用IAM策略变量${aws:username}的解析异常问题
最近我在用YAML编写多份AWS CloudFormation模板时踩了个实在的坑——当我尝试在IAM策略里结合替换操作使用${aws:username}这类内置变量时,CloudFormation直接抛出了解析异常。先给大伙看看我出问题的代码片段:
CommonUserGroup: Type: AWS::IAM::Group Properties: GroupName: Common Path: /project/ Policies: - PolicyName: ClusterPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: "iam:GetAccountPasswordPolicy" Resource: "arn:aws:iam::${AWS::AccountId}:user/${aws:username}"
问题根源
其实这个问题的核心是语法冲突:CloudFormation本身就用${}语法来识别模板内的自定义变量(比如${AWS::AccountId}),它会优先把${aws:username}当成自己的模板变量去解析,但这个变量根本没在模板里定义,自然就抛出解析异常了,完全没意识到这是IAM策略的内置变量。
解决办法
这里给两个靠谱的解决思路,亲测有效:
转义美元符号
在YAML中,只需要给${aws:username}里的美元符号加个反斜杠转义,写成\${aws:username}。这样CloudFormation就会把整个内容原封不动地传递给IAM策略,不会再去尝试解析它:CommonUserGroup: Type: AWS::IAM::Group Properties: GroupName: Common Path: /project/ Policies: - PolicyName: ClusterPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: "iam:GetAccountPasswordPolicy" Resource: "arn:aws:iam::${AWS::AccountId}:user/\${aws:username}"使用
Fn::Sub的参数映射
如果你本来就用!Sub(也就是Fn::Sub)来做字符串替换,可以通过Sub的参数映射功能,明确把${aws:username}作为字符串传递,避免CloudFormation误解析:CommonUserGroup: Type: AWS::IAM::Group Properties: GroupName: Common Path: /project/ Policies: - PolicyName: ClusterPolicy PolicyDocument: !Sub - Version: 2012-10-17 Statement: - Effect: Allow Action: "iam:GetAccountPasswordPolicy" Resource: "arn:aws:iam::${AWS::AccountId}:user/${UserName}" - { UserName: "${aws:username}" }
额外提醒
不光是${aws:username},其他IAM内置变量比如${aws:userId}、${aws:PrincipalAccount}也会遇到同样的问题,处理逻辑都是一样的——要么转义美元符号,要么用Sub的参数映射来区分模板变量和IAM内置变量。
内容的提问来源于stack exchange,提问作者PicoutputCls
相关产品推荐
相关产品推荐

