I am trying to use Terraform's public modules and I created a lot of IAM users like so:
module "iam_finance_users" {
source = "terraform-aws-modules/iam/aws//modules/iam-user"
version = "5.9.1"
for_each = var.finance_users
name = each.value
force_destroy = true
create_iam_access_key = false
password_reset_required = true
}
My variables.tf file has the following:
variable "finance_users" {
type = set(string)
default = ["[email protected]","[email protected]"....]
}
Now I am trying to add these users to a group like so
module "iam_group_finance" {
source = "terraform-aws-modules/iam/aws//modules/iam-group-with-policies"
version = "5.9.1"
name = "finance"
group_users = ["${module.iam_finance_users.iam_user_name}"]
attach_iam_self_management_policy = true
custom_group_policy_arns = [
"${module.iam_read_write_policy.arn}",
]
}
But no matter what I try I still keep getting errors. I have a list of users in a variable and I want to add all those users created in that module to the group module. I know I'm close but I can't quite seem to close this.
CodePudding user response:
Since you used for_each
in the module, you have to use values
to access elements of all instances of the module created:
group_users = values(module.iam_finance_users)[*].iam_user_name
CodePudding user response:
You could try something like below: This is untested, so you might need to tweak a bit. Reference thread: https://discuss.hashicorp.com/t/for-each-objects-to-list/36609/2
module "iam_group_finance" {
source = "terraform-aws-modules/iam/aws//modules/iam-group-with-policies"
version = "5.9.1"
name = "finance"
group_users = [ for o in module.iam_finance_users : o.iam_user_name ]
attach_iam_self_management_policy = true
custom_group_policy_arns = [
module.iam_read_write_policy.arn
]
}
CodePudding user response:
It's often helpful to know what the error is. In versions of Terraform v1.0 or newer, the errors become fairly explanatory. The error you were likely getting was something similar to:
│ Error: Unsupported attribute
│
│ on main.tf line 14, in output "iam_finance_users":
│ 14: value = module.iam_finance_users.iam_user_name
│ ├────────────────
│ │ module.iam_finance_users is object with 2 attributes
│
│ This object does not have an attribute named "iam_user_name".
The solutions, which both work, can be tested using the following example code:
Module 1: modules/iam-user
variable "name" {
type = string
}
output "iam_user_name" {
value = "IAM-${var.name}"
}
Module 2: modules/iam-group-with-policies
variable "group_users" {
type = set(string)
}
output "iam-users" {
value = var.group_users
}
Root module (your code):
variable "finance_users" {
type = set(string)
default = ["[email protected]", "[email protected]"]
}
module "iam_finance_users" {
source = "../modules/iam-user"
for_each = var.finance_users
name = each.value
}
module "iam_group_finance" {
source = "../modules/iam-group-with-policies"
# This works...
group_users = values(module.iam_finance_users)[*].iam_user_name
# This also works...
group_users = [for o in module.iam_finance_users : o.iam_user_name]
}
output "group_users" {
value = module.iam_group_finance.iam-users
}
You can easily test each module along the way using terraform console
.
E.g.:
terraform console
> module.iam_finance_users
{
"[email protected]" = {
"iam_user_name" = "[email protected]"
}
"[email protected]" = {
"iam_user_name" = "[email protected]"
}
}
Here you can see why it didn't work. The module doesn't spit out a list in that way, so you have to iterate through the module to get your variable. This is why both the for
method as well as the values
method works.
Look at how differently a single module is handled:
module "iam_finance_users" {
source = "../modules/iam-user"
name = tolist(var.finance_users)[1]
}
terraform console
> module.iam_finance_users
{
"iam_user_name" = "[email protected]"
}
Notice that when not inside a loop (foreach
), that the single iam_user_name
is accessible.