I am trying to create multiple storage accounts and then containers, file shares, tables etc. for those storage accounts in azure. In the example, I have 2 storage accounts, the first has 2 containers, the second has none.
This is my variables.tf :
variable "location" {
type = string
default = ""
}
variable "resource_group_name" {
type = string
default = ""
}
variable "storage_account_name" {
type = string
default = ""
}
######################################################################################################################
################### Storage Account
######################################################################################################################
variable "storageAccount" {
type = map(
object({
name = string
owner = string
CreatedBy = string
env = string
change_feed_enabled = bool
container_delete_retention_policy_days = number
delete_retention_policy_days = number
account_tier = string
account_replication_type = string
table_encryption_key_type = string
queue_encryption_key_type = string
infrastructure_encryption_enabled = bool
storageBlobContainers = list(object({
name = string
}))
})
)
default = {
"storageAccount" = {
name = ""
owner = ""
CreatedBy = ""
env = ""
change_feed_enabled = false
container_delete_retention_policy_days = 0
delete_retention_policy_days = 0
account_tier = ""
account_replication_type = ""
table_encryption_key_type = ""
queue_encryption_key_type = ""
infrastructure_encryption_enabled = false
storageBlobContainers = []
}
}
}
######################################################################################################################
################### Storage Account Blob Containers
######################################################################################################################
variable "storageBlobContainer" {
type = map(list(string))
description = "Map of storage account names and associated container names"
}
My tfvars:
location = "northeurope"
resource_group_name = "finance-sandbox"
storageAccount = {
"d365fodev1sbconsstg" = {
name = "d365consstg"
env = "sandbox"
owner = "somsubhra.mukherjee"
CreatedBy = "somsubhra.mukherjee"
account_tier = "Standard"
account_replication_type = "LRS"
table_encryption_key_type = "Account"
queue_encryption_key_type = "Account"
infrastructure_encryption_enabled = false
change_feed_enabled = false
container_delete_retention_policy_days = 7
delete_retention_policy_days = 7
}
"d365fodev1sbfilesstg" = {
name = "d365filesstg",
env = "sandbox",
owner = "somsubhra.mukherjee",
CreatedBy = "somsubhra.mukherjee",
account_tier = "Standard",
account_replication_type = "LRS",
table_encryption_key_type = "Account",
queue_encryption_key_type = "Account",
infrastructure_encryption_enabled = false,
change_feed_enabled = false,
container_delete_retention_policy_days = 7,
delete_retention_policy_days = 7
}
}
storageBlobContainer = {
"d365consstg" = ["azure-webjobs-hosts", "azure-webjobs-secrets"]
"d365consstg" = ["container1"]
}
My storageAccount.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.0"
}
}
}
provider "azurerm" {
features {
key_vault {
recover_soft_deleted_secrets = false
}
}
skip_provider_registration = true
}
############### Storage Account ##########################
resource "azurerm_storage_account" "storageAccount" {
for_each = var.storageAccount
name = each.value.name
resource_group_name = var.resource_group_name
location = var.location
account_tier = each.value.account_tier
account_replication_type = each.value.account_replication_type
table_encryption_key_type = each.value.table_encryption_key_type
queue_encryption_key_type = each.value.queue_encryption_key_type
infrastructure_encryption_enabled = each.value.infrastructure_encryption_enabled
tags = {
env = each.value.env
owner = each.value.owner
CreatedBy = each.value.CreatedBy
}
blob_properties {
change_feed_enabled = each.value.change_feed_enabled
container_delete_retention_policy {
days = each.value.container_delete_retention_policy_days
}
delete_retention_policy {
days = each.value.delete_retention_policy_days
}
}
}
resource "azurerm_storage_container" "storageBlobContainer" {
# count = length(flatten([for containers in values(var.storageBlobContainer) : containers]))
for_each = var.storageBlobContainer
storage_account_name = azurerm_storage_account.storageAccount[each.key].name
name = each.value
}
I am a terraform newbie and cannot seem to create the containers properly. Ideally I would like it to happen automatically as first the storage account gets created and then the containers get created. But not sure how to do that.
Error Received :
Error: Invalid index
│
│ on storageAccount.tf line 59, in resource "azurerm_storage_container" "storageBlobContainer":
│ 59: storage_account_name = azurerm_storage_account.storageAccount[each.key].name
│ ├────────────────
│ │ azurerm_storage_account.storageAccount is object with 2 attributes
│ │ each.key is "storage_account2"
│
│ The given key does not identify an element in this collection value.
╵
╷
│ Error: Incorrect attribute value type
│
│ on storageAccount.tf line 60, in resource "azurerm_storage_container" "storageBlobContainer":
│ 60: name = each.value
│ ├────────────────
│ │ each.value is list of string with 2 elements
│
│ Inappropriate value for attribute "name": string required.
You have made a few mistakes:
Take a look at this configuration:
locals {
storages = {
order = {
name = "orderst"
containers = ["order", "order-logs"]
}
catalog = {
name = "catalogst"
containers = ["catalog", "catalog-logs"]
}
}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "West Europe"
}
resource "azurerm_storage_account" "example" {
for_each = local.storages
name = each.value.name
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "GRS"
tags = {
environment = "staging"
}
}
locals {
storage_account_names = flatten([for key, value in local.storages : [for container in value.containers : {
name = container
storage_account_name = azurerm_storage_account.example[key].name
}]
])
}
resource "azurerm_storage_container" "example" {
for_each = { for storage in local.storage_account_names : storage.name => storage }
name = each.value.name
storage_account_name = each.value.storage_account_name
container_access_type = "private"
}
It will create 2 storage accounts and 4 containers (2 per account).
It first create storage account iterating over variable(here local), and then it flatten configuration to create set of containing storage account name and container name to create containers.