For-each looping with lists

Newbie question.I am using 0.12.7 and facing an issue related to maps and lists. Below is a sample code and not specific for storage containers.

variable “storage_container_nm”{
type=map
default={
StorageContAcct1 ={
name=[“test1”,“test2”]
storage_acc_nm =“StorageAccount1”
},
StorageContAcct2 ={
name=[“test3”]
storage_acc_nm =“StorageAccount2”
}
}
}

resource “azurerm_storage_contianer” “asc”{
for_each=[for k in keys(var.storage_container_nm):[
for v in values(var.storage_container_nm):[
for f in v.name:[{
nm=f
storage_acc_nm=v.storage_acc_nm
}]
]
]
]

name = each.value.nm
storage_account_name = each.value.storage_acc_nm
container_access_type ="private"

}

I get the below error .

The given “for_each” argument value is unsuitable: the “for_each” argument
must be a map, or set of strings, and you have provided a value of type tuple.

Can you please tell me the best way to loop through the list of names and create storage containers ?

Hello! This isn’t entirely working (I get an error with “terraform plan”), but maybe this will give you a start. Sometimes it’s easier to use locals to transform your variable into a different structure first, before passing it into for_each:

locals {
  name_acct_pairs = flatten([
    for sca in var.storage_container_nm : [
      for n in sca.name : {
        name           = n
        storage_acc_nm = sca.storage_acc_nm
      }
    ]
  ])
  name_acct_map = {
    for k in local.name_acct_pairs : k.name => k.storage_acc_nm
  }
}

output "map" {
  value = local.name_acct_map
}

The output:

map = {
  "test1" = "StorageAccount1"
  "test2" = "StorageAccount1"
  "test3" = "StorageAccount2"
}

Thanks a lot ! I got the idea and made it work.

Hi @sam,

Any chance you could provide your working solution please?

TIA.

variable “storage_container_nm”{
type=map
default={
	StorageContAcct1 ={
		name=[“test1”,“test2”]
		storage_acc_nm =“StorageAccount1”
	},
	StorageContAcct2 ={
		name=[“test3”]
		storage_acc_nm =“StorageAccount2”
	}
}
}

locals {
  name_acct_pairs = flatten([
	for sca in var.storage_container_nm : [
	  for n in sca.name : {
		name           = n
		storage_acc_nm = sca.storage_acc_nm
	  }
	]
  ])
  name_acct_map = {
	for k in local.name_acct_pairs : k.name => k.storage_acc_nm
  }
}

resource “azurerm_storage_contianer” “asc”{
	for_each=local.name_acct_map
	name = each.key
	storage_account_name = each.value
	container_access_type ="private"
}
1 Like

Sure. Foreach loop is a blessing. Play around to get a hang of it.
I feel that Terraform official documentation should provide some examples of List , Map , List(List) etc … and how to access the elements.

If you’re still stuck, post your code and people in the forum would be able to help you out.

2 Likes

Good info here, thanks for sharing guys!