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:
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:
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.