Azure / terraform-azurerm-avm-res-network-virtualnetwork

Azure Verified Module for Virtual Network
https://registry.terraform.io/modules/Azure/avm-res-network-virtualnetwork
MIT License
17 stars 14 forks source link

[AVM Module Issue]: Plan fails because for_each loop on diagnostic setting is empty due to Log Analytics workspace ID not known until Apply #67

Closed philipstreet closed 2 months ago

philipstreet commented 2 months ago

Check for previous/existing GitHub issues

Issue Type?

I'm not sure

(Optional) Module Version

v0.1.4

(Optional) Correlation Id

No response

Description

I am trying to create a Virtual Network and Log Analytics workspace using their respective AVMs. I am trying to pass the ID of the LAW as part of the diagnostic settings configuration for the vnet but the Terraform Plan fails with the following error;

Error: Invalid for_each argument

on main.tf line 70, in resource "azurerm_monitor_diagnostic_setting" "example": 70: for_each = { 71: for key, value in var.diagnostic_settings : key => value 72: if value.workspace_resource_id != null || value.storage_account_resource_id != null || >value.event_hub_authorization_rule_resource_id != null 73: } ├──────────────── │ var.diagnostic_settings is map of object with 1 element

Example code:

resource "azurerm_resource_group" "name" {
  location = "uksouth"
  name     = "rg-test"
}

module "law" {
  source                                             = "Azure/avm-res-operationalinsights-workspace/azurerm"
  location                                           = azurerm_resource_group.name.location
  name                                               ="law-test"
  resource_group_name                    = azurerm_resource_group.name.name
}

module "vnet001" {
  source                        = "Azure/avm-res-network-virtualnetwork/azurerm"
  location                      = azurerm_resource_group.name.location
  name                          = "vnet-001"
  resource_group_name           = azurerm_resource_group.name.name
  virtual_network_address_space = ["10.0.0.0/24"]
  subnets = {
    "subnet-001" = {
      address_prefixes = ["10.0.0.0/24"]
    }
  }
  diagnostic_settings = {
    sendToLogAnalytics = {
      name                           = "sendToLogAnalytics"
      workspace_resource_id          = module.law.resource.id
      log_analytics_destination_type = "AzureDiagnostics"
    }
  }
}

Expected behaviour: The AVM module should respect the "(known after apply)" availability of values passed as inputs.

Or am I doing something wrong? Thanks

philipstreet commented 2 months ago

I have resolved my issue, as per the technique described by @matt-FFFFFF in his video (https://youtu.be/6OkdaPDphz4?si=Mgq9-Ml5WupKb4xc).

The actual code experiencing the issue differs from the original example, as I was passing the LAW ID into a local module that then created a collection of resources, including the diagnostic setting.

So, instead of;

module "common-001" {
  source                     = "./modules/common"
  environment                = var.environment
  application                = var.application
  location                   = var.primary_location
  address_space_prefix       = "10.1"
  tags                       = local.tags
  key_vault_role_assignments = local.common_role_assignments
  log_analytics_workspace_id = resource_id = module.law.resource.id
}

I now do this;

module "common-001" {
  source                     = "./modules/common"
  environment                = var.environment
  application                = var.application
  location                   = var.primary_location
  address_space_prefix       = "10.1"
  tags                       = local.tags
  key_vault_role_assignments = local.common_role_assignments
  log_analytics_workspace_id = {
    resource_id = module.law.resource.id
  }
}
matt-FFFFFF commented 2 months ago

Glad you found the video useful!!