I have been trying to write a number of my AWS CloudFormation templates in the YAML format.
I have been having issues with CloudFormation trying to parse IAM policy variables, such as ${aws:username}
, in conjunction with substitutions. An example is the following:
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: "*"
- Effect: Allow
Action: "iam:ChangePassword"
Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:user/${aws:username}'
When the CloudFormation template is used to try and create a stack the following error is returned:
Template validation error: Template format error: Unresolved resource dependencies [aws:username] in the Resources block of the template
If I manually specify the username, rather than using a policy variable, like:
'arn:aws:iam::${AWS::AccountId}:user/bob'
Then the error goes away.
Is there a way that one can escape policy variables such that CloudFormation doesn't try and parse them as part of the template?
After a bit of searching I came across the following Reddit post which mentions the same problem: Creating No MFA No Access policy via YAML template - substitution issues
A reply to this thread referenced the following AWS CloudFormation documentation: Filter View: Fn::Sub, which states:
To write a dollar sign and curly braces (${}) literally, add an exclamation point (!) after the open curly brace, such as ${!Literal}. AWS CloudFormation resolves this text as ${Literal}.
This can be used to escape policy variables.
So in the example in my question, ${aws:username}
can be escaped in the YAML as ${!aws:username}
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With