Chanafot
Chanafot

Reputation: 796

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.

Upvotes: 2

Views: 2034

Answers (1)

Marcin
Marcin

Reputation: 238309

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.

Upvotes: 5

Related Questions