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 Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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