Home > Software design >  Malformed Policy Document: Has prohibited field Resource
Malformed Policy Document: Has prohibited field Resource

Time:01-11

I'm trying to create an IAM Role and IAM Policy using Terraform.

I'm getting this error:

│ Error: error creating IAM Role (asg-domain-join-policy): MalformedPolicyDocument: Has prohibited field Resource
 
  status code: 400, request id: 53fa1ae0-f22f-4f2e-8aa6-1947421eae9b

  with aws_iam_role.ad_join_role,
  on iam.tf line 30, in resource "aws_iam_role" "ad_join_role":
  30: resource "aws_iam_role" "ad_join_role" {

My current code for the IAM Role is the following:

resource "aws_iam_role" "ad_join_role" {
  name                 = "asg-domain-join-policy"
  assume_role_policy   = data.aws_iam_policy_document.asg_domain_join_policy.json
  permissions_boundary = "arn:aws:iam::${var.account_id}:policy/****"
}

The code for IAM Policy is the following:

data "aws_iam_policy_document" "asg_domain_join_policy" {
  statement {
    actions = [
      "ssm:DescribeAssociation",
      "ssm:GetDocument",
      "ssm:ListAssociations",
      "ssm:UpdateAssociationStatus",
      "ssm:UpdateInstanceInformation",
      "ssm:CreateAssociation",
    ]
    effect    = "Allow"
    resources = ["ec2"]
    }
}

I'm unsure why I'm getting that error.

CodePudding user response:

The assume_role_policy can have a document which specifies only the AssumeRole action. What you have to do is split your policy to create separate ones for being able to assume a role, and being able to attach other permissions to the role.

For example:

# Allow EC2 instances to assume the role
data "aws_iam_policy_document" "asg_assume_role_policy" {
  statement {
    actions = [
      "sts:AssumeRole"
    ]
    effect = "Allow"
    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }

  }
}

# Create the policy which allows other actions for the EC2 instance
data "aws_iam_policy_document" "asg_domain_join_policy" {
  statement {
    actions = [
      "ssm:DescribeAssociation",
      "ssm:GetDocument",
      "ssm:ListAssociations",
      "ssm:UpdateAssociationStatus",
      "ssm:UpdateInstanceInformation",
      "ssm:CreateAssociation"
    ]
    effect = "Allow"
    resources = ["*"]
  }
}

resource "aws_iam_role" "ad_join_role" {
  name               = "asg-domain-join-policy"
  assume_role_policy = data.aws_iam_policy_document.asg_assume_role_policy.json
 
  # Attach the policy
  inline_policy {
    policy = data.aws_iam_policy_document.asg_domain_join_policy.json
  }
}

Some things to note in this example:

  • The second policy is attached as an inline policy. This is fine, if the policy is shorter, otherwise you may want to use aws_iam_policy_attachment
  • The resource type for the actions in the second policy is a wildcard ["*"]. If you want more granularity for your actions on the policy, you may want to check out this page to see which action allows what kind of resource type. Obviously, ["ec2"] is not a valid resource type.

CodePudding user response:

Your resource block is using an incorrect reference. ec2 is not a resource. If you are referencing an instance you need to use aws_instance.my_ec2_instance, or if you want to allow all resources you can put "*".

  •  Tags:  
  • Related