How to attach multiple IAM policies to IAM roles using Terraform?

Viewed 54690

I want to attach multiple IAM Policy ARNs to a single IAM Role.

One method is to create a new policy with privileges of all the policies (multiple policies).

But in AWS, we have some predefined IAM policies like AmazonEC2FullAccess, AmazomS3FullAccess, etc. I want to use a combination of these for my role.

I could not find a way to do so in the Terraform documentation.

As per documentation we can use aws_iam_role_policy_attachment to attach a policy to a role, but not multiple policies to a role as this is available via AWS console.

Please let me know if there is a method to do the same or is it still a feature to be added.

The Terraform version I use is v0.9.5

6 Answers

For Terraform versions >= 0.12 the cleanest way to add multiple policies is probably something like this:

resource "aws_iam_role_policy_attachment" "role-policy-attachment" {
  for_each = toset([
    "arn:aws:iam::aws:policy/AmazonEC2FullAccess", 
    "arn:aws:iam::aws:policy/AmazonS3FullAccess"
  ])

  role       = var.iam_role_name
  policy_arn = each.value
}

As described in Pranshu Verma's answer, the list of policies can also be put into a variable.

Using for_each in favor of count has the advantage, that insertions to the list are properly recognized by terraform so that it would really only add one policy, while with count all policies after the insertion would be changed (this is described in detail in this blog post)

Adding another option, which is similar to the excepted answer but instead of:

policy_arn = "${var.iam_policy_arn[count.index]}"

You can use the element function:

policy_arn = "${element(var.iam_policy_arn,count.index)}"

I think that in some cases (like a project with a large amount of code) this could be more readable.

This is an example how i did it:

resource "aws_iam_group_policy_attachment" "policy_attach_example" {
  for_each   = aws_iam_policy.example
  group      = aws_iam_group.example.name
  policy_arn = each.value["arn"]
}

So basically "aws_iam_policy.example" is a list of policies that i have made in the same way, with for_each

Hope that this help you, i know i come late but i had this simillar issue

In my case I added multiple statements in one policy document:

data "aws_iam_policy_document" "sns-and-sqs-policy" {
  statement {
    sid    = "AllowToPublishToSns"
    effect = "Allow"
    actions = [
      "sns:Publish",
    ]
    resources = [
      data.resource.arn,
    ]
  }
  statement {
    sid    = "AllowToSubscribeFromSqs"
    effect = "Allow"
    actions = [
      "sqs:changeMessageVisibility*",
      "sqs:SendMessage",
      "sqs:ReceiveMessage",
      "sqs:GetQueue*",
      "sqs:DeleteMessage",
    ]
    resources = [
      data.resource.arn,
    ]
  }
}

resource "aws_iam_policy" "sns-and-sqs" {
  name   = "sns-and-sqs-policy"
  policy = data.aws_iam_policy_document.sns-and-sqs-policy.json
}

resource "aws_iam_role_policy_attachment" "sns-and-sqs-role" {
  role       = "role_name"
  policy_arn = aws_iam_policy.sns-and-sqs.arn
}

simply combine your policies in one policy

Related