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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With