Regions, discovery and subnets with Terraform
Region-aware load balancing needs to know which region a client and each backend belong to. These resources provide that data. See regions and subnet mapping for the concepts.
Subnet mappings
Section titled “Subnet mappings”dtm_subnet_mapping (role: editor or admin) ties a CIDR to a region.
There is no update path; every attribute forces replacement.
resource "dtm_subnet_mapping" "ne" { subnet = "10.100.0.0/16" region_id = "northeurope"}
resource "dtm_subnet_mapping" "we" { subnet = "10.20.0.0/16" region_id = "westeurope"}| Attribute | Required | Description |
|---|---|---|
subnet |
Yes | CIDR block, e.g. 10.100.0.0/16. |
region_id |
Yes | Region tag, e.g. northeurope. |
priority |
No | Higher priority wins when CIDRs overlap. Default 0 (most-specific prefix wins). |
source |
No | Must be manual (the default). Discovered mappings get azure-api from the server itself; declaring it here fails at apply with a clear diagnostic, since a mapping that merely claims to be discovered would be pruned by the next discovery cycle. |
Azure region discovery
Section titled “Azure region discovery”dtm_discovery_scope (role: admin) tells DTM which Azure subscription (and
optionally which resource group) to walk to auto-generate subnet mappings, using
its managed identity’s read access.
resource "dtm_discovery_scope" "prod" { subscription_id = "00000000-0000-0000-0000-000000000000" resource_group = "rg-network" # optional; omit to scope the whole subscription display_name = "Production networking" enabled = true}| Attribute | Required | Description |
|---|---|---|
kind |
No | subscription (default) or management-group. Changing it replaces the resource. |
subscription_id |
For subscription scopes | Azure subscription ID (UUID form). Must be empty on a management-group scope. Changing it replaces the resource. |
resource_group |
No | Narrow a subscription scope to one resource group. Changing it replaces the resource. |
management_group_id |
For management-group scopes | The management-group name segment. Changing it replaces the resource. |
expanded_subscription_ids |
For management-group scopes | The subscriptions the scope covers. Required: DTM never expands a group on its own. |
display_name |
No | Label shown in the UI. |
enabled |
No | Defaults to true. |
A management-group scope authorises whole subscriptions, listed explicitly:
resource "dtm_discovery_scope" "corp" { kind = "management-group" management_group_id = "contoso-root"
expanded_subscription_ids = [ "11111111-1111-1111-1111-111111111111", "33333333-3333-3333-3333-333333333333", ]}expanded_subscription_ids is the authorisation: the reviewed Terraform
plan is the confirmation step, and git is the audit trail. Because the list
is declared here, DTM reports membership drift on this scope but never
applies it, even under region_discovery_auto_apply; otherwise DTM’s
apply and your next terraform apply would silently revert each other
forever. When the group’s membership changes, GET /api/v1/discovery/status
says so; you update the list and apply.
To decide what to authorise, use the dtm_management_group_expansion data
source (role: admin):
data "dtm_management_group_expansion" "corp" { management_group_id = "contoso-root" verify = true # issue the read discovery actually makes}
output "cannot_scan" { value = data.dtm_management_group_expansion.corp.unreadable_subscription_ids}verify = true costs one Azure call per subscription and is worth it:
without it, “readable” only means the identity holds some role there, and
Reader on a single resource group is enough to look readable while the
subscription-wide read discovery needs still fails.
Discovered mappings appear with source = "azure-api"; you can add manual
mappings alongside them.
Region-discovery backend
Section titled “Region-discovery backend”dtm_region_discovery_config (role: admin) selects how DTM enumerates
your Azure networks: arm-list (the default, walking the scopes directly) or
resource-graph (an Azure Resource Graph query, better suited to large
estates).
resource "dtm_region_discovery_config" "this" { mode = "resource-graph"}- The change applies live, with no restart, and the applied value is loaded over the server-config seed at boot, so a switch survives restarts.
resource-graphrequires the nodes’ managed identity to be able to read Azure Resource Graph. Switching to a backend the identity cannot use fails closed: the discovery cycle logs the error and prunes nothing, and you recover by switching back, with no redeploy.- Singleton: import with ID
region-discovery; removing the resource resets the backend toarm-list.
Read the known regions
Section titled “Read the known regions”The dtm_regions data source returns the deduplicated set of region IDs in use:
data "dtm_regions" "all" {}
output "regions" { value = data.dtm_regions.all.ids}