Select specific object from a map variable via a condition inside for_each

Hi there, First post here, I’ve been creating an IAM user IAC for AWS. I am stuck on this one part. I want to create users from a large list, some users have to create for certain environments, so trying to create a condition based logic using the for_each block allowing me to look over the “env” attribute and match with it with the “var.environment” allowing it to create a user if it matches.

My issue is on Terraform can’t understand what I’m trying to do. I want to have a condition saying if I enter “dev” as an Environment variable == the “env” attribute in the each user block. Somehow I cannot get TF to grab that part from my var.aws_users file.

Can anyone help me? This is what I’ve done so far and it isn’t working.

resource "aws_iam_user" "aws_users" {
  for_each = var.environment == [var.aws_users["env"]] ? 1 : 0

  name = each.key
  path          = "/"
  force_destroy = each.value["force_destroy"]
  tags          = each.value["tags"]

}

variable environment  {
default = "prod"
}

variable aws_users {

  default = {

    #Users

    "elon.musk" = {
      path          = "/"
      force_destroy = true
      env = ["dev" , "preprod"]
        group_dev = [""]
        group_preprod   = ["Administrators"]
        group_prod      = ["Administrators"]
      tags = {
        mobile       = "",
        type         = "User",
        organisation = "organisation1",
        email        = "",
        deployment   = "terraform"
      }
    }

Hi @samitpatel55,

I think I would start with this problem by filtering your input list to only include users that participate in the current environment, like this:

locals {
  current_env_users = {
    for name, u in var.aws_users : name => u
    if contains(u.env, var.environment)
  }
}

local.current_env_users should then have the same general structure as var.aws_users, but include only the users belonging to the current environment. You can then use that value instead of var.aws_users in any situation where you only want the current environment users:

resource "aws_iam_user" "aws_users" {
  for_each = local.current_env_users

  name          = each.key
  path          = "/"
  force_destroy = each.value.force_destroy
  tags          = each.value.tags
}
1 Like

Hi @apparentlymart

Thanks for your speedy response, I am quite new to Terraform and this logic makes complete sense, I saw a few examples online on creating “for loops” within “locals”, just wasn’t sure how to implement it into my code. I guess using the conditionals was just making it more complicated.

Just placed into my code and it works a dream. Thank you so much, have an awesome day!!!

Hi @apparentlymart , I have another question if you have a second…

Another “newbie to TF” question, I want to make this environment specific, but I’ve already used a for_each to call the variable posted at the bottom. Can I use this locals that I’ve created, if so how do I implement it? Or is there a better way to do this? I have many of these polices/roles that are only for our “Dev” environment, I don’t want these to be applying to any other environments.

locals {
    env_dev_only = {
        if contains(var.environment, "dev")
    }

}

resource "aws_iam_group_policy_attachment" "dev-attach" {
  for_each   = toset(var.dev-polices)
  group      = "Developers"
  policy_arn = each.key
}

variable-dev-polices {
  default = ["arn:aws:iam::aws:policy/AmazonSQSFullAccess", "arn:aws:iam::aws:policy/AWSCodePipelineReadOnlyAccess", "arn:aws:iam::aws:policy/AmazonRoute53ReadOnlyAccess", "arn:aws:iam::aws:policy/AWSBatchFullAccess", "file(./policies/SecretManagerReadOnly.json"]
}