Create multiple Azure Storage Account with Multiple FileShare under each Storage Account

119 Views Asked by At

I am trying to create multiple Azure Storage accounts with specific Azure File shares under each account using the variable type as map:object. I have created the following terraform code but getting the error message:

  • CODE
StorageAccount = {
  "dev" = {
    SName       = "test"
    SAFileShare = [logs1", "Logs3"]
  }
  "prd" = {
    SName       = "test1"
    SAFileShare = ["Logs3", "logs4"]

  }
}

variable "StorageAccount" {
  type = map(object({
    SName       = string
    SAFileShare = list(string)
    SABlob      = list(string)
  }))
}


# Storage Account
resource "azurerm_storage_account" "Storage" {
  for_each                 = var.StorageAccount
  name                     = lower(join("", [var.AppShortName, join(each.value["SName"], [var.EnvironmentType, "sa"])]))
  location                 = var.Location
  resource_group_name      = azurerm_resource_group.ResourceGroup.name
  account_tier             = var.accountTier
  account_replication_type = var.accountReplicationType
}

# File Share 
resource "azurerm_storage_share" "FileShare" {
  for_each             = var.StorageAccount
  name                 = each.value["SAFileShare"]
  storage_account_name = azurerm_storage_account.Storage[each.key].name
  quota                = 50
}

  • Error Message
Error: Incorrect attribute value type
│
│   on main.tf line 4, in resource "azurerm_storage_share" "FileShare":
│    4:   name                 = each.value["SAFileShare"]
│     ├────────────────
│     │ each.value["SAFileShare"] is list of string with 2 elements
│
│ Inappropriate value for attribute "name": string required.

2

There are 2 best solutions below

1
Vinay B On

I tried to Create multiple Azure Storage Account with Multiple FileShare under each Storage Account using Terraform and I was able to provision the requirement successfully

You are getting this error because of how you are creating the Azure File Shares. The name attribute of the azurerm_storage_share resource requires a string, but you are giving it a list of strings with each.value["SAFileShare"]. Terraform will not create multiple file shares by looping over this list automatically.

I was having trouble with the for_each expression and the dynamic property, so I tried this solution, which seems to meet the requirement for now.

My demo terraform configruation:

provider "azurerm" {
  features {}
}

variable "resource_group_name" {
  type    = string
  default = "demorg-vkvk"  # Replace with your resource group name
}

variable "location" {
  type    = string
  default = "East US"  # Replace with your preferred location
}

variable "storage_accounts" {
  description = "List of storage account names"
  type        = list(string)
  default     = ["storageaccountvk1", "storageaccountvk2"]  # Replace with your unique storage account names
}

resource "azurerm_resource_group" "rg" {
  name     = var.resource_group_name
  location = var.location
}

resource "azurerm_storage_account" "storage_account" {
  for_each                = toset(var.storage_accounts)
  name                    = each.value
  resource_group_name     = azurerm_resource_group.rg.name
  location                = azurerm_resource_group.rg.location
  account_tier            = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_storage_share" "file_share1" {
  count                 = length(var.storage_accounts)
  name                  = "${var.storage_accounts[count.index]}-fileshare1"
  storage_account_name  = azurerm_storage_account.storage_account[var.storage_accounts[count.index]].name
  quota                 = 50
}

resource "azurerm_storage_share" "file_share2" {
  count                 = length(var.storage_accounts)
  name                  = "${var.storage_accounts[count.index]}-fileshare2"
  storage_account_name  = azurerm_storage_account.storage_account[var.storage_accounts[count.index]].name
  quota                 = 50
}

Output:

enter image description here

enter image description here

enter image description here

0
debugWithRam On

you can use merge function for looping twice in map of objects. here's what you can do:

resource "azurerm_storage_share" "FileShare" {
for_each             = merge([ for sa_key, sa_value in var.StorageAccount: { for val in sa_value["SAFileShare"] : val => sa_key }]...)
name                 = each.key
storage_account_name = azurerm_storage_account.Storage[each.value].name
quota                = 50
}

This can be used to create multiple file share in certain storage accounts as you wanted.