Error Message :
Property AssumeRolePolicyDocument cannot be empty
Problem:
When you try to create an IAM role using AWS::IAM::Role resource and you don’t specify anything in AssumeRolePolicyDocument parameter, you get this error.
I guess the error message itself is self explanatory that AssumeRolePolicyDocument can not be empty.
If you check documentation for IAM role using CloudFormation, you will notice that AssumeRolePolicyDocument is a mandatory parameter indeed and hence you can not create a role without specifying this parameter.
For example, I tried creating an IAM role with just a managed policy using below template-
AWSTemplateFormatVersion: '2010-09-09'
Description: Template to Create an IAM Role
Resources:
MyTestRole:
Type: AWS::IAM::Role
Properties:
Description: Role to provide access to S3
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonS3FullAccess
RoleName: LambdaS3Access
As expected, my stack creation failed with below error !!!
Property AssumeRolePolicyDocument cannot be empty
Solution:
Have you guessed the solution by now?
I think so 🙂
Okay, so solution is very simple.
Update your template by specifying AssumeRolePolicyDocument parameter and you should be good to go.
Your stack creation will not fail and you will be able to create IAM role using CloudFormation.
However, if you are new to AWS and are wondering-
- What should you put in AssumeRolePolicyDocument parameter ?
Don’t worry, I will explain it for you in the next section.
Significance of AssumeRolePolicyDocument:
As you might already know, IAM roles are identities in AWS that has certain permissions and they can be assumed by a person, application or AWS service to provide a temporary credential so that they can perform actions permitted to the role.
Usually roles are meant to be used by an application or AWS services to perform action on your behalf. Now you might think anyone can assume a role and do actions defined by the role.
So, what about security?
Well, that’s where AssumeRolePolicyDocument comes in to picture.
AssumeRolePolicyDocument is nothing but the trust relationship.
AssumeRolePolicyDocument in CloudFormation = Trust Relationship in AWS Console
It is used by an administrator or someone creating the role to specify who can assume the role they are creating. Only those entity can assume this role and perform actions specified by the role.
How do you specify it in CloudFormation?
Well, in my case I want AWS Lambda service to assume this role to be able to perform actions on my s3 bucket. So this is how I specify it in CloudFormation template.
Below template is in YAML because I prefer YAML over JSON while creating CloudFormation template. However if you would like to have JSON template, I will include that right after this section. Scroll down to see JSON template
CloudFormation Template in YAML to create IAM role with managed policy
AWSTemplateFormatVersion: '2010-09-09'
Description: Template to Create an IAM Role
Resources:
MyTestRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Description: Role to provide access to S3
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonS3FullAccess
RoleName: LambdaS3Access
CloudFormation Template in JSON to create IAM role with managed policy
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Template to Create an IAM Role",
"Resources": {
"MyTestRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Description": "Role to provide access to S3",
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/AmazonS3FullAccess"
],
"RoleName": "LambdaS3Access"
}
}
}
}
How service principal is specified?
As you might have noticed in the policy statement, service principal takes form of-
service-name
.amazonaws.com
that’s why, for lambda, it is lambda.amazonaws.com
If you are looking for complete list of service principal, you can check it here.
Note: Please note that you can associate only one trust policy with a role
Therefore, if you have multiple principal to specify, don’t try using service element twice, rather specify them in array form for example-
YAML
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- ecs.amazonaws.com
Action:
- 'sts:AssumeRole'
JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ecs.amazonaws.com",
"lambda.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
Conclusion:
In this troubleshooting post, we learnt how to solve Property AssumeRolePolicyDocument cannot be empty. We also learnt why it occurs and significance of AssumeRolePolicyDocument in terms of security.
I hope you were able to solve the issue. If not, please let us know what exactly you are facing in the comment section. We might be able to help you.
Enjoyed the content?
Subscribe to our newsletter below to get awesome AWS learning materials delivered straight to your inbox.
Don’t forget to motivate me by-
- Adding a comment below on what you liked and what can be improved.
- Follow us on
- Share this post with your friends
Suggested Read:
- Create a DynamoDB table using CloudFormation
- 5 Ways to Create and Manage your AWS Resources
- AWS S3 Storage Classes: Everything you need to know
- How to Create an EC2 instance in an existing VPC using CloudFormation
- Attach an IAM role to an EC2 instance using CloudFormation
- How to create an S3 bucket using CloudFormation
- Understand IAM PassRole to Secure Your AWS Infrastructure
- Understand IAM PassRole to Secure your AWS Infrastructure
- Serverless Services on AWS with Explanation