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 :
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 = each.value["SName"]
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
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.
The error you are encountering is due to the way you are iterating over the SAFileShare
list within each storage account. The azurerm_storage_share
resource expects a single string for the name
attribute, but you are providing a list of strings. To resolve this, you need to modify your for_each
to iterate over each file share within each storage account.
Here’s a revised version of your Terraform code that should work:
variable “StorageAccount” {
type = map(object({
SName = string
SAFileShare = list(string)
}))
}
Storage Account
resource “azurerm_storage_account” “Storage” {
for_each = var.StorageAccount
name = each.value.SName
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 = { for sa_key, sa_value in var.StorageAccount : sa_key => sa_value.SAFileShare… }
name = each.value
storage_account_name = azurerm_storage_account.Storage[each.key].name
quota = 50
}
Hii,
here the foreach expresion is correct and for study purpose I ran the code but on fileshare name attribute its giving error as below:
on Az_fileShare.tf line 29, in resource "azurerm_storage_share" "FileShare":
│ 29: name = each.value
│ ├────────────────
│ │ each.value is list of string with 2 elements
│
│ Inappropriate value for attribute "name": string required.
if I give index as each.value[0] its working but in this case he wants fileshare to be for both strings, so how can he do??
Here’s the solution for your situation:
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
}
you can use merge function to loop twice in your map of object and do your iteration.
the result of this merge function is as follow:
Test = {
+ logs1 = "dev"
+ logs2 = "dev"
+ logs3 = "prd"
+ logs4 = "prd"
}
Thank you…