Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform iterate over list

I would like to replace the 3 indepedent variables (dev_id, prod_id, stage_id), for a single list containing all the three variables, and iterate over them, applying them to the policy.

Is this something terraform can do?

data "aws_iam_policy_document" "iam_policy_document_dynamodb" {
  statement {
    effect    = "Allow"
    resources = ["arn:aws:dynamodb:${var.region}:${var.account_id}:table:${var.dynamodb_table_name}"]

    actions = [
      "dynamodb:GetItem",
      "dynamodb:PutItem",
      "dynamodb:DeleteItem",
    ]

    principals {
      type = "AWS"

      identifiers = [
        "arn:aws:iam::${var.dev_id}:root",
        "arn:aws:iam::${var.prod_id}:root",
        "arn:aws:iam::${var.stage_id}:root"
      ]
    }
  }
}

I looked into cycles and interpolation, but It seems that 99% of the time the interpolation is done with "count" which only works for the creation of multiple resources (I hope I am not saying a big lie).

For example, I used

principals {
   count = "${length(var.list)}"
   identifiers = ["arn:aws:iam::${var.list[count.index]}"]
}

but that was unsuccessful.

Is there some way of achieving the final goal of replacing those 3 variables by a single list (or map) and iterate over them?

like image 791
Rafael Marques Avatar asked Oct 16 '18 14:10

Rafael Marques


People also ask

Can we use for loop in Terraform?

In a general-purpose programming language, you'd probably use a for-loop: # This is just pseudo code. It won't actually work in Terraform. One problem with this code is that all three IAM users would have the same name, which would cause an error, since usernames must be unique.

How do you make a loop in Terraform?

Using the count meta-argument The count meta-argument is the simplest of the looping constructs within Terraform. By either directly assigning a whole number or using the length function on a list or map variable, Terraform creates this number of resources based on the resource block it is assigned to.

What is For_each in Terraform?

for_each is a meta-argument defined by the Terraform language. It can be used with modules and with every resource type. The for_each meta-argument accepts a map or a set of strings, and creates an instance for each item in that map or set.

What is difference between Count and For_each in Terraform?

Like the count argument, the for_each meta-argument creates multiple instances of a module or resource block. However, instead of specifying the number of resources, the for_each meta-argument accepts a map or a set of strings. This is useful when multiple resources are required that have different values.


Video Answer


1 Answers

Given you have the list of account ids, have you tried this?

var "accounts" {
  default = ["123", "456", "789"]
  type = "list"
}

locals {
  accounts_arn = "${formatlist("arn:aws:iam::%s", var.accounts)}"
}

Then in your policy document:

principals {
  type = "AWS"
  identifiers = ["${local.accounts_arn}"]
}

I haven't actually tried it, but can't think of a reason it wouldn't work.

like image 200
Magd Kudama Avatar answered Oct 30 '22 06:10

Magd Kudama