aws_iam_role: Error Updating IAM Role – Assume Role Policy: MalformedPolicyDocument: Has prohibited field Resource

I recently ran into two errors when using Terraform:

1. Has prohibited field Resource

aws_iam_role: Error Updating IAM Role - Assume Role Policy: MalformedPolicyDocument: Has prohibited field Resource

also experienced here:

The policy looked like this:

  assume_role_policy = <<POLICY
  "Version": "2012-10-17",
  "Statement": [
      "Effect": "Allow",
      "Principal": {
        "Service": ""
      "Action": "sts:AssumeRole"


2. Has prohibited field Principal

When I pasted this into AWS Policy Editor here:$new?step=edit

I would get:

This policy contains the following error: Has prohibited field Principal For more information about the IAM policy grammar, see AWS IAM Policies 

Looking at AWS IAM Policies > Policy Grammar Notes:

  • The principal_block element is required in resource-based policies (for example, in Amazon S3 bucket policies) and in trust policies for IAM roles. It must not be included in identity-based policies.


Some notes:

a. Policy Types

  • Identity: attach to IAM identities: must NOT have principal
  • Resource: attach to resources such as S3: must have principal
    • Trust Policies are resource-based policies attached to a role and define which principals can assume the role


Identity-based policies (must NOT have Principal):


Resource-based policies (must have Principal):


b. Policy Permission Categories:

  • Permissions policies



b. Also related

assume_role_policy – (Required) The policy that grants an entity permission to assume the role.
NOTE: This assume_role_policy is very similar but slightly different than just a standard IAM policy and cannot use an aws_iam_policy resource. It can however, use an aws_iam_policy_document data source, see example below for how this could work.


IAM Policies

Breaking down a Policy:


Version: just use "Version": "2012-10-17"

Statement: the meat of the Policy


The Statement contains:

Effect: Allow or Deny

Principal: Who


  • if we’re attaching Policies to IAM users, groups or roles then Principal isn’t needed as the policy assumes the user, group or role is the Principal
  • differences between attaching a policy to an IAM user vs a resource (e.g. S3 or EC2):
    • if it’s with the user, we check the policy and are done
    • if it’s with the resource then we need to have a Principal to make sure who’s allowed this resource





Beginner’s Guide to IAM: IAM, Roles, Policies, Policy Attachments with Terraform

IAM is short for Identity and Access Management.

  1. What’s the difference between an IAM user and role?

An IAM user has long term credentials and directly interacts with AWS services. An IAM role does not have any credentials and don’t directly access AWS services. IAM roles are assumed by entities (such as users, applications or services like EC2).

2. What’s an IAM Policy?

An IAM Policy allows access  -i.e. they define permissions. You create a policy then attach it to an IAM identity or AWS resource.

3. what’s an IAM Role Policy Attachment?

This can be found in Terraform. e.g.

It attaches an IAM Policy to an IAM role and typically looks like this:

resource “aws_iam_role_policy_attachment” “test-attach” {
role = “${}”
policy_arn = “${aws_iam_policy.policy.arn}”

4. Principal

The Principalelement specifies the AWS user, account, service that is allowed or denied access to a resource.

5. assume_role_policyis very similar but slightly different than a standard IAM policy

6. Service Roles are IAM roles that can be assumed by an AWS service


  "Version": "2012-10-17",
  "Statement": [
      "Effect": "Allow",
      "Principal": {
        "Service": [
      "Action": "sts:AssumeRole"

Note how there are 2 Services listed. The Service key must be unique. So it’s value must be a list.

and a list of Services that work with IAM: