Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

terraform nested for each loop in azure storage account

I would want to create multiple storage acounts and inside each of those sotrage accounts some containers. If I would want 3 storage account i would always want to create container-a and container-b in those 3 storage accounts

So for example would be. Storage account list ["sa1","sa2","sa3"].

resource "azurerm_storage_account" "storage_account" {
  count = length(var.list) 
  name = var.name
  resource_group_name = module.storage-account-resource-group.resource_group_name[0]
  location = var.location
  account_tier = var.account_tier
  account_kind = var.account_kind
  

then container block

resource "azurerm_storage_container" "container" {
  depends_on = [azurerm_storage_account.storage_account]
  count =  length(var.containers)
  name                  = var.containers[count.index].name
  container_access_type = var.containers[count.index].access_type
  storage_account_name  = azurerm_storage_account.storage_account[0].name

container variables:

variable "containers" {
  type = list(object({
    name        = string
    access_type = string
  }))
  default     = []
  description = "List of storage account containers."
}

list variable

variable "list" {
  type        = list(string)
  description = "the env to deploy. ['dev','qa','prod']"

This code will create only one container in the first storage account "sa1" but not in the others two "sa2" and "sa3". I read I need to use 2 for each to iterate in both list of storage account and continaers, but not sure how should be the code for it.

like image 347
Chanafot Avatar asked Feb 02 '26 15:02

Chanafot


1 Answers

It would be better to use for_each:

resource "azurerm_storage_account" "storage_account" {
  for_each = toset(var.list) 
  name = var.name
  resource_group_name = module.storage-account-resource-group.resource_group_name[0]
  location = var.location
  account_tier = var.account_tier
  account_kind = var.account_kind
}

then you need an equivalent of a double for loop, which you can get using setproduct:

locals {
    flat_list = setproduct(var.list, var.containers)
}

and then you use local.flat_list for containers:

resource "azurerm_storage_container" "container" {
  for_each              = {for idx, val in local.flat_list: idx => val}
  name                  = each.value.name[1].name
  container_access_type = each.value.name[1].access_type
  storage_account_name  = azurerm_storage_account.storage_account[each.value[0]].name
}

p.s. I haven't run the code, thus it may require some adjustments, but the idea remains valid.

like image 155
Marcin Avatar answered Feb 04 '26 05:02

Marcin