How to hook up child DNS zone into parent by updating its NS records using ARM template

Imagine a scenario: you have one global DNS zone in Prod subscription and several child DNS zones for each environment in their own subscriptions, e.g.:

  • infra.example.com
    • Subscription: Prod
  • dev.infra.examle.com
    • Subscription: Dev
  • test.infra.example.com
    • Subscription: Test
  • prod.infra.example.com
    • Subscription: Prod

Each zone is created using its own ARM template. But in order a child zone to start working you need to hook it up into the parent zone by updating its NS record, e.g.:

  • dev.infra.example.com
    • NS
      • ns1-01.azure-dns.com.
      • ns1-01.azure-dns.net
      • ns1-01.azure-dns.org.
      • ns1-09.azure-dns.info.
  • infra.example.com
    • dev
      • NS
        • the records must be inserted here

Here’s how to achieve that using ARM template:

{
  "$schema": "http://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "environment": {
      "type": "string"
    },
    "globalSecretsSubscriptionId": {
      "type": "string"
    },
    "globalSecretsResourceGroupName": {
      "type": "string"
    },
    "globalDnsZoneName": {
      "type": "string"
    },
    "envDnsZoneName": {
      "type": "string"
    }
  },
  "variables": {
    "deploymentApiVersion": "2019-09-01",
    "dnsApiVersion": "2018-05-01"
  },
  "resources": [
    {
      "name": "[parameters('envDnsZoneName')]",
      "type": "Microsoft.Network/dnsZones",
      "apiVersion": "[variables('dnsApiVersion')]",
      "location": "global"
    },
    {
      "name": "[format('DNS-Global-{0}', parameters('environment'))]",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "[variables('deploymentApiVersion')]",
      "subscriptionId": "[parameters('globalSecretsSubscriptionId')]",
      "resourceGroup": "[parameters('globalResourceGroupName')]",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "name": "[format('{0}/{1}', parameters('globalDnsZoneName'), parameters('environment'))]",
              "type": "Microsoft.Network/dnsZones/NS",
              "apiVersion": "[variables('dnsApiVersion')]",
              "properties": {
                "TTL": 3600,
                "NSRecords": "[reference(resourceId('Microsoft.Network/dnszones/NS', parameters('envDnsZoneName'), '@'), variables('dnsApiVersion')).NSRecords]"
              }
            }
          ]
        }
      },
      "dependsOn": [
        "[concat('Microsoft.Network/dnsZones/', parameters('envDnsZoneName'))]"
      ]
    }
  ]
}

Here’s what it does:

  1. Creates a child zone in current subscription and resource group
  2. Updates the parent zone in its own subscription and resource group, creates NS record with the value of NS records of the child zone

Happy deployment!

This entry was posted in Infrastructure and tagged , . Bookmark the permalink.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.