Reputation: 9
I have used for_each loops to create a number of subnets and a number of storage accounts. I am trying now to allow all traffic on some storage accounts, while simultaneously allowing others to be accessed only from certain subnets.
In my main.tf file:
resource "azurerm_subnet" "subnets" {
for_each = var.subnets
name = each.key
resource_group_name = var.rgname
virtual_network_name = each.value.virtual_network_name
address_prefixes = each.value.address_prefixes
service_endpoints = ["Microsoft.Storage"]
depends_on = [ azurerm_virtual_network.vnet_apps, azurerm_virtual_network.vnet_main ]
}
resource "azurerm_storage_account" "storage_accounts" {
for_each = var.storage_accounts
name = each.key
resource_group_name = var.rgname
location = var.location
account_replication_type = "LRS"
account_tier = "Standard"
network_rules {
default_action = each.value.network_action
virtual_network_subnet_ids = [azurerm_subnet.subnets[each.value.subnetids].id]
}
}
In my variables.tf file:
variable "subnets" {
type = map(object({
virtual_network_name = string
address_prefixes = list(string)
route_table = string
}))
}
variable "storage_accounts" {
type = map(object({
network_action = string
subnetids = list(string)
}))
}
In my .tfvars file:
subnets = {
vm_subnet = {
virtual_network_name = "vnet_main"
address_prefixes = ["10.1.1.0/25"]
route_table = "vm_rt"
}
sql_subnet = {
virtual_network_name = "vnet_main"
address_prefixes = ["10.1.1.128/25"]
route_table = "vm_rt"
}
app1_subnet = {
virtual_network_name = "vnet_apps"
address_prefixes = ["10.1.2.0/25"]
route_table = "vm_rt"
}
app2_subnet = {
virtual_network_name = "vnet_apps"
address_prefixes = ["10.1.2.128/25"]
route_table = "app_rt"
}
}
storage_accounts = {
mynamedefaultstorage57 = {
network_action = "Allow"
subnetids = ["app1_subnet"]
}
mynamedefaultstorage108 = {
network_action = "Deny"
subnetids = ["vm_subnet", "app2_subnet"]
}
}
If I change subnetids to a string (rather than a list of strings) and change the tfvars file to only allow one subnet, it will work properly. But that doesn't allow me to do multiple subnets at once, and if I try it is as I have laid out here, I get this error:
on main.tf line 114, in resource "azurerm_storage_account" "storage_accounts":
│ 114: virtual_network_subnet_ids = [azurerm_subnet.subnets[each.value.subnetids].id]
│ ├────────────────
│ │ azurerm_subnet.subnets is object with 4 attributes
│ │ each.value.subnetids is list of string with 1 element
│
│ The given key does not identify an element in this collection value: string required.
Thanks in advance for any assistance you can offer.
Upvotes: 0
Views: 682
Reputation: 17664
Here is a sample using dynamic blocks ... I think that should work but I have not tested
resource "azurerm_storage_account" "storage_accounts" {
for_each = var.storage_accounts
name = each.key
resource_group_name = var.rgname
location = var.location
account_replication_type = "LRS"
account_tier = "Standard"
dynamic "network_rules" {
for_each = each.value.subnetids
default_action = each.value.network_action
virtual_network_subnet_ids = [azurerm_subnet.subnets[network_rules.value].id]
}
}
Looking at the documentation for azurerm_storage_account there is a note:
Network Rules can be defined either directly on the azurerm_storage_account resource, or using the azurerm_storage_account_network_rules resource - but the two cannot be used together. If both are used against the same Storage Account, spurious changes will occur. When managing Network Rules using this resource, to change from a default_action of Deny to Allow requires defining, rather than removing, the block.
Maybe you should move to using the azurerm_storage_account_network_rules
Upvotes: 0