Import existing Azure DNS Zone into Pulumi

Evgeny Borzenin · September 8, 2020

logo

I am currently working on labs for my upcoming Workshop #3: Implement immutable infrastructure on Azure with Pulumi and I spent a lot of time working with Pulumi on Azure. As one of the POCs, I decided to implement CI/CD pipeline for my existing Azure DNS Zone that handles DNS records for my iac-labs.com domain.

Importing Infrastructure

Since my DNS Zone instance was already provisioned manually long before and already contains several DNS record sets, I need to import existing resources so they can be managed by Pulumi.

To adopt existing resources so that Pulumi is able to manage subsequent updates to them, Pulumi offers the import resource option. This option requests that a resource defined in your Pulumi program adopts an existing resource in Azure instead of creating a new one.

In my case, to import DNS Zone, I need to import the following resources:

  • resource group where DNS Zone is deployed
  • DNS Zone instance
  • all DNS record sets (A, CName, NS, TXT, etc…)

For each of the resources you want to import, you need to find it’s Azure resource ID. Normally, you can find this information at the Properties page at the Azure portal, but some of the resources, like DNS record sets, don’t show this information at the portal, but you can always get resource ID with az cli.

The following script gives me my Resource Group ID

az group show -g iac-domains-and-certificates-rg --query id

and this script gives me my DNS Zone ID

az network dns zone show -n iac-labs.com -g iac-domains-and-certificates-rg --query id

and finally, this script gives me the list of all record sets under my DNS Zone

az network dns record-set list --zone-name iac-labs.com -g iac-domains-and-certificates-rg

With ID in place, I need to implement the regular Pulumi stack including resource group, DNS Zone and record sets, and in addition to normal resource specification, I need to specify ImportId for each of the resources I want to import.

Here is the code that imports resource group, Azure DNS Zone instance and TXT, NS and CName records. I am .net guy, so I will use C#, but if you use other languages supported by Pulumi, I hope it will be easy for you to follow…

// Create an Azure Resource Group
var resourceGroup = new ResourceGroup("rg", new ResourceGroupArgs
{
    Name = "iac-domains-and-certificates-rg"
}, new CustomResourceOptions {
    // Import existing resource
    ImportId = "/subscriptions/SUBSCRIPTIONID/resourceGroups/iac-domains-and-certificates-rg"
});

var dnsZone = new Zone("iac-com", new ZoneArgs
{
    Name = "iac-labs.com",
    ResourceGroupName = resourceGroup.Name,
}, new CustomResourceOptions {
    // Import existing resource
    ImportId = "/subscriptions/SUBSCRIPTIONID/resourceGroups/iac-domains-and-certificates-rg/providers/Microsoft.Network/dnszones/iac-labs.com"
});

var nsRecord = new NsRecord("ns", new NsRecordArgs
{
    Name = "@",
    ZoneName = dnsZone.Name,
    ResourceGroupName = resourceGroup.Name,
    Ttl = 172800,
    Records =
    {
        "ns1-08.azure-dns.com.",
        "ns2-08.azure-dns.net.",
        "ns3-08.azure-dns.org.",
        "ns4-08.azure-dns.info.",
    }
}, new CustomResourceOptions {
    ImportId = "/subscriptions/SUBSCRIPTIONID/resourceGroups/iac-domains-and-certificates-rg/providers/Microsoft.Network/dnszones/iac-labs.com/NS/@"
});

new CNameRecord("iac-lab-portal", new CNameRecordArgs
{
    Name = "iac-lab-portal",
    ZoneName = dnsZone.Name,
    ResourceGroupName = resourceGroup.Name,
    Ttl = 300,
    Record = "iac-lab-green-api-agw.westeurope.cloudapp.azure.com"
}, new CustomResourceOptions {
    ImportId = "/subscriptions/SUBSCRIPTIONID/resourceGroups/iac-domains-and-certificates-rg/providers/Microsoft.Network/dnszones/iac-labs.com/CNAME/iac-lab-portal"
});

Running pulumi preview gives me the following information

$ pulumi preview
Previewing update (prod)
...

     Type                         Name            Plan       
 +   pulumi:pulumi:Stack          dns-zone-prod   create     
 =   ├─ azure:core:ResourceGroup  rg              import     
 =   ├─ azure:dns:Zone            iac-com         import     
 =   ├─ azure:dns:CNameRecord     iac-lab-portal  import     
 =   └─ azure:dns:NsRecord        ns              import     
 
Resources:
    + 1 to create
    = 4 to import
    5 changes

That means that if I run pulumi up, a new stack will be cerated and 4 resources will be imported.

After I successfully imported all resources, I can remove new CustomResourceOptions { ImportId = "" } code blocks from the code and continue to work with Pulumi as usual.

SOA record set

Since SOA records are created and deleted with each DNS zone and cannot be created or deleted separately, there is no need to import this resource into your pulumi stack (and I guess, that’s why there is no support for this record type in Pulumi).

In the next weeks I will write how to implement Azure DevOps CD pipeline to deploy changes to DNS Zone maintained with Pulumi. Stay tuned.

If you have any issues/comments/suggestions related to this post, you can reach out to me at evgeny.borzenin@gmail.com.

With that - thanks for reading! :)

LinkedIn