I need to create a sub module for each sub resource for Storage Account. I am working on Queue and looking for a way to reference arguments foreach module.
Variable
variable "queues" {
type = map(object({
metadata = optional(map(string))
name = string
role_assignments = optional(map(object({
role_definition_id_or_name = string
principal_id = string
description = optional(string, null)
skip_service_principal_aad_check = optional(bool, false)
condition = optional(string, null)
condition_version = optional(string, null)
delegated_managed_identity_resource_id = optional(string, null)
})), {})
timeouts = optional(object({
create = optional(string)
delete = optional(string)
read = optional(string)
update = optional(string)
}))
}))
default = {}
}
resource "azapi_resource" "queue" {
for_each = var.queues
type = "Microsoft.Storage/storageAccounts/queueServices/queues@2023-01-01"
body = jsonencode({
properties = {
# metadata = each.value.metadata
}
})
name = each.value.name
parent_id = "${azurerm_storage_account.this.id}/queueServices/default"
schema_validation_enabled = false
dynamic "timeouts" {
for_each = each.value.timeouts == null ? [] : [each.value.timeouts]
content {
create = timeouts.value.create
delete = timeouts.value.delete
read = timeouts.value.read
}
}
}
module "storage_queue" {
source = "./modules/storage_queue"
for_each = var.queues
name = each.value.name (
}
Error i get when i trying to add name:
Unexpected attribute: An attribute named "name" is not expected here Terraform
During the Validation shows following error
│
│ on ../../main.queues.tf line 8, in module "storage_queue":
│ 8: name = each.value
│
│ An argument named "name" is not expected here. ```
Configure Storage Account with Sub Modules for each category using terraform.
To define a sub-module/child-modules using for-each sub-resource and referencing arguments inside a storage account we need to follow the specific sequence while doing so as the parameters are depending on each other.
The general understanding for sub-module we need to start writing the sub-module configuration first and then with following up root configuration. So, during sometimes reversing the sequence may also cause the issue you're facing.
I tried a terraform configuration of your requirement by adding name under module configuration of queue and I was able to overcome the issue and I was able to achieve the requirement successfully using azapi resource for storage queue
Terraform configuration:
main.tf:
provider "azurerm" {
features {}
}
variable "queues" {
type = map(object({
metadata = optional(map(string))
name = string
role_assignments = optional(map(object({
role_definition_id_or_name = string
principal_id = string
description = optional(string, null)
skip_service_principal_aad_check = optional(bool, false)
condition = optional(string, null)
condition_version = optional(string, null)
delegated_managed_identity_resource_id = optional(string, null)
})), {})
timeouts = optional(object({
create = optional(string)
delete = optional(string)
read = optional(string)
update = optional(string)
}))
}))
default = {}
}
resource "azurerm_resource_group" "example" {
name = "sampletestvk-rg"
location = "East US"
}
resource "azurerm_storage_account" "example" {
name = "exvksbstrageacct"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
}
module "storage_queue" {
source = "./modules/storage_queue"
for_each = var.queues
name = each.value.name
metadata = lookup(each.value, "metadata", {})
storage_account_id = azurerm_storage_account.example.id
timeouts = lookup(each.value, "timeouts", null)
}
module/storage_queue/main.tf
terraform {
required_providers {
azapi = {
source = "azure/azapi"
}
}
}
variable "name" {
description = "The name of the queue."
type = string
}
variable "metadata" {
description = "Metadata info for the queue."
type = map(string)
default = {}
}
variable "storage_account_id" {
description = "The ID of the storage account."
type = string
}
variable "timeouts" {
description = "Timeouts of the queue."
type = object({
create = optional(string)
delete = optional(string)
read = optional(string)
})
default = null
}
resource "azapi_resource" "queue" {
type = "Microsoft.Storage/storageAccounts/queueServices/queues@2023-01-01"
body = jsonencode({
properties = {
metadata = var.metadata
}
})
name = var.name
parent_id = "${var.storage_account_id}/queueServices/default"
schema_validation_enabled = false
dynamic "timeouts" {
for_each = var.timeouts == null ? [] : [var.timeouts]
content {
create = timeouts.value.create
delete = timeouts.value.delete
read = timeouts.value.read
}
}
}
Deployment succeeded: