Skip to content

Monitor Diagnostic Setting

Overview

The monitor_diagnostic_setting module wires Azure resources to one or more diagnostic destinations (Log Analytics Workspace, Storage Account, Event Hub, or a partner solution) so their platform logs and metrics flow into a queryable store. It is intentionally a low-level module: it is not configured directly in tfvars. Instead, each supported resource type exposes a diagnostic_settings map on its own input variable, and the module projects those per-resource maps into the diagnostic setting resources.

This keeps the user-facing configuration close to the resource being monitored (the diagnostic settings live on the vault entry, the storage account entry, and so on), while a single module creates the actual azurerm_monitor_diagnostic_setting resources.

Each entry in diagnostic_settings produces a separate azurerm_monitor_diagnostic_setting resource, so a single Azure resource can have multiple settings — for example, one routing logs to a workspace and another routing them to a storage account for long-term retention.

Module Structure

Module Azure Resource Purpose
monitor_diagnostic_setting azurerm_monitor_diagnostic_setting Routes platform logs/metrics for a target resource to one or more destinations
log_analytics_workspace azurerm_log_analytics_workspace Workspace destination, referenced by key — see Log Analytics Workspace
storage_account azurerm_storage_account Storage destination, referenced by key

Supported Resource Types

The following root variables accept a diagnostic_settings map on each entry.

Root Variable Module Composite Key Prefix Log Categories
recovery_services_vault recovery_services_vault recovery_services_vault.<vault_key>.<setting_key> CoreAzureBackup, AddonAzureBackupAlerts, AddonAzureBackupJobs, AddonAzureBackupPolicy, AddonAzureBackupProtectedInstance, AddonAzureBackupStorage
key_vault key_vault key_vault.<vault_key>.<setting_key> AuditEvent, AzurePolicyEvaluationDetails
automation_account automation_account automation_account.<account_key>.<setting_key> JobLogs, JobStreams, DscNodeStatus, AuditEvent

When additional resource types are wired through this module, they will be added to this table. See Adding Diagnostic Settings to a New Resource Type for the procedure.

How It Is Wired

The root file src/main.monitor_diagnostic_setting.tf only passes inputs into the module — it contains no transform logic:

module "monitor_diagnostic_setting" {
  source                      = "./modules/monitor_diagnostic_setting"
  var_recovery_services_vault = var.recovery_services_vault
  var_key_vault               = var.key_vault
  var_automation_account      = var.automation_account
  mod_recovery_services_vault = module.recovery_services_vault.recovery_services_vault
  mod_key_vault               = module.key_vault.key_vault
  mod_automation_account      = module.automation_account.automation_account
  mod_log_analytics_workspace = module.log_analytics_workspace.log_analytics_workspace
  mod_storage_account         = module.storage_account.resource
}

The projection from each resource's diagnostic_settings map into the shape azurerm_monitor_diagnostic_setting expects lives inside the module at src/modules/monitor_diagnostic_setting/locals.tf. One flattening per supported resource type produces a list whose elements key as "<resource_type>.<resource_key>.<setting_key>", then a single resource block iterates the list:

locals {
  diagnostic_setting_recovery_services_vault = flatten([
    for k, v in var.var_recovery_services_vault : [
      for diag_key, diag in v.diagnostic_settings : {
        key                = "recovery_services_vault.${k}.${diag_key}"
        target_resource_id = var.mod_recovery_services_vault[k].id
        # ... destination + log fields
      }
    ]
  ])
}

The triple-segment key (<resource_type>.<resource_key>.<setting_key>) keeps diagnostic setting keys unique across resource types and across multiple settings on the same target resource.

Adding Diagnostic Settings to a New Resource Type

Use this procedure to wire diagnostic settings into a module that does not yet support them. The goal is that an operator can opt into diagnostics by adding a diagnostic_settings map to a single entry in tfvars — no other wiring required.

1. Add the diagnostic_settings Map to the Root Variable

In src/variables.<resource>.tf, add a diagnostic_settings field to the object. Use this exact shape so every resource type stays consistent:

diagnostic_settings = optional(map(object({
  name                           = optional(string)
  workspace                      = optional(string)
  log_analytics_destination_type = optional(string)
  storage_account                = optional(string)
  eventhub_authorization_rule_id = optional(string)
  eventhub_name                  = optional(string)
  partner_solution_id            = optional(string)
  enabled_logs                   = optional(object({
    categories      = optional(list(string), [])
    category_groups = optional(list(string), [])
  }), {})
  enabled_metrics                = optional(list(string))
})), {})

2. Pass the New Resource Into the Module

In src/main.monitor_diagnostic_setting.tf, add a var_* input for the new resource's tfvars map and a mod_* input for its module output:

module "monitor_diagnostic_setting" {
  source                          = "./modules/monitor_diagnostic_setting"
  var_recovery_services_vault     = var.recovery_services_vault
  mod_recovery_services_vault     = module.recovery_services_vault.recovery_services_vault
  var_<root_variable>             = var.<root_variable>             # <- new
  mod_<resource_module>           = module.<resource_module>.<resource_output>  # <- new
  mod_log_analytics_workspace     = module.log_analytics_workspace.log_analytics_workspace
  mod_storage_account             = module.storage_account.resource
}

3. Declare the New Inputs Inside the Module

In src/modules/monitor_diagnostic_setting/variables.tf, add matching declarations. var_* inputs hold tfvars maps; mod_* inputs receive module outputs and must be type = any:

variable "var_<root_variable>" {
  type = map
}

variable "mod_<resource_module>" {
  type = any
}

4. Project Entries Into the Diagnostic-Setting Shape

In src/modules/monitor_diagnostic_setting/locals.tf, add a flatten block that converts the new resource's entries into the shape azurerm_monitor_diagnostic_setting expects, then concatenate it into diagnostic_setting_recovery_services_vault-style local lists. Key each entry as "<resource_type>.<resource_key>.<setting_key>".

5. Document the Resource Type

Add a row to the Supported Resource Types table above, including the valid log category names for that Azure resource. The authoritative list is the Azure Monitor supported categories table, or run:

az monitor diagnostic-settings categories list --resource <resource_id>

Per-Entry Diagnostic Setting Block

This is the shape consumed on supported resource entries. At least one destination must be set — either workspace, storage_account, eventhub_authorization_rule_id, or partner_solution_id.

Field Type Description Default
name string Override the diagnostic setting name "<resource_type>-<resource_key>-<setting_key>"
workspace string log_analytics_workspace key (workspace destination) null
log_analytics_destination_type string "Dedicated" (resource-specific tables) or "AzureDiagnostics" (legacy single table). Leave unset for the resource default. null
storage_account string storage_account key (storage destination for archive/retention) null
eventhub_authorization_rule_id string Full Event Hub namespace authorization rule ID. Pair with eventhub_name. null
eventhub_name string Event Hub name within the namespace referenced by eventhub_authorization_rule_id null
partner_solution_id string Full resource ID of a partner monitoring solution destination null
enabled_logs object Log categories and category groups to enable (see below) {}
enabled_metrics list(string) Metric category names to enable null

enabled_logs

Field Type Description Default
categories list(string) Individual log category names to enable []
category_groups list(string) Category groups to enable (e.g. "audit", "allLogs") []

Note: For a given setting, categories and category_groups are mutually exclusive — pick one approach. Available category names and groups are resource-specific.

Note: A single diagnostic setting can fan out to multiple destination types simultaneously (workspace + storage + event hub on one setting). To send to two workspaces or two storage accounts, define two separate entries in diagnostic_settings.

Tip: Prefer log_analytics_destination_type = "Dedicated" on new workspaces. It writes logs to per-resource tables (for example AddonAzureBackupJobs) instead of the legacy single AzureDiagnostics table, which keeps queries simpler and aligns with current Azure guidance.

Example: Recovery Vault With Multiple Settings

The full vault configuration lives in Backup. The diagnostic part of the entry can define multiple settings — for example, one to a workspace and another to a storage account for long-term retention:

recovery_services_vault = {
  epic = {
    resource_group    = "recoveryvault"
    storage_mode_type = "GeoRedundant"
    diagnostic_settings = {
      law = {
        workspace                      = "shared"
        log_analytics_destination_type = "Dedicated"
        enabled_logs = {
          categories = [
            "CoreAzureBackup",
            "AddonAzureBackupAlerts",
            "AddonAzureBackupJobs",
            "AddonAzureBackupPolicy",
            "AddonAzureBackupProtectedInstance",
            "AddonAzureBackupStorage",
          ]
        }
      }
      archive = {
        storage_account = "auditarchive"
        enabled_logs = {
          category_groups = ["allLogs"]
        }
      }
    }
  }
}

This produces two azurerm_monitor_diagnostic_setting resources keyed recovery_services_vault.epic.law and recovery_services_vault.epic.archive.

Naming Convention

monitor_diagnostic_setting does not use name_prefixes / name_suffixes. The name comes from the setting entry's name, or defaults to "<resource_type>-<resource_key>-<setting_key>" (for example recovery_services_vault-epic-law). The resource-type prefix is included in the default so two resources of different types that share a key (e.g. a vault and a key vault both named epic) don't produce duplicate diagnostic setting names.