Sometimes we want to give users the ability to create pretty much anything with CloudFormation but at the same time prevent them from doing the same through the console or aws-cli. Perhaps it’s a company policy that everything must be managed using CloudFormation. Or on the other hand you may have Admin privileges but want to CloudFormation can do on your behalf.
CloudFormation Service Role
CFN Service Role can achieve exactly that – users can have a separate set of credentials for work outside of CloudFormation and a completely different set of credentials for creating, updating and deleting CloudFormation stacks.
For example grant CloudFormation all the privileges it needs to create the stack but in the console limited the users to ReadOnly access.
Here is how…
1. Create CloudFormation Service Role
In this case we’ll give it Administrative privileges but in reality you should only give it as little privileges as it needs.
Of course we’ll use CloudFormation to create it 🙂
CfnServiceRole: Type: AWS::IAM::Role Properties: RoleName: svcCloudFormation Path: /service/ AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: cloudformation.amazonaws.com ManagedPolicyArns: - arn:aws:iam::aws:policy/AdministratorAccess
This role can only be used by CloudFormation, you can’t assume it as a user e.g. with
aws sts assume-role or use it as EC2 instance role.
2. Create an IAM Policy that can use the role
The most important permission it needs is iam:PassRole that gives it the ability to instruct CloudFormation to use the above IAM Role to create resources in CFN stacks.
The policy also needs some basic CloudFormation permissions to upload the template file to S3 and to actually create the stack. However it does not need permissions to create any of the resources in the stack. That will be done through the role.
CfnUserPolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: svcCloudFormation Path: / PolicyDocument: Version: 2012-10-17 Statement: - Action: - iam:PassRole Effect: Allow Resource: - !GetAtt CfnServiceRole.Arn - Action: - cloudformation:CreateStack - cloudformation:CreateUploadBucket Effect: Allow Resource: "*" - Action: - s3:PutObject - s3:GetObject - s3:ListBucket Effect: Allow Resource: - arn:aws:s3:::cf-templates-* - arn:aws:s3:::cf-templates-*/*
The complete CloudFormation template to create the role and the policy is can be downloaded here: cfn-service-role-and-policy.yml
3. Create CFN User
We’ll create a new IAM User called e.g. cfn-user. We will restrict it to Read Only access but will also attach the above cfnCloudFormation managed policy to give it the ability to create CFN stacks.
4. Create a stack using the service role
Login in a new window as the just-created cfn-user account and try to create a new CloudFormation stack. Without the role the stack creation will fail because cfn-user doesn’t have a permission to create any resources:
However if you select the role in the drop-down list and proceed as usual your stack will get successfully created:
Updating and deleting stacks
Notice the warning above when you selected the role:
WarningAWS CloudFormation will use this role for all stack operations. Other
users that have permissions to operate on this stack will be able to
use this role, even if they don’t have permission to pass it.
What does that mean? Once the IAM Role is attached to the CFN stack it is used for all subsequent operations on the stack! That means the users who can manipulate the stack can update, delete and add new resources even if they don’t have the appropriate
iam:PassRole permission. The IAM role is attached to the stack when created and stays attached – keep this in mind!
Use only with permission boundaries!
Giving otherwise-restricted users the ability to create any resources through CloudFormation means that they can create new IAM users and even use CloudFormation to extend their own permissions for example through custom resources! Where possible use IAM Permission Boundary to mitigate this.
Thank you for this post. I was struggling to understand this.
Nice article. Please provide rss for these articles 🙂