I secretly automated my whole job with PowerShell

How to update the TTL for all A records in a zone at once in Azure?

4 min read.

Every now and then there comes a time when you need to fiddle with DNS. It’s not that you want to do it, but sometimes you just can’t avoid it. This article explains a convenient way of using PowerShell to apply a change for all A records (these are essentially host names) in a zone (which you could usually simply call a domain). Applying changes like this programmatically enables you to automate them as a part of a script (like in a pipeline), or simply reduce human errors by making the steps easily reproducible exactly the same way every time you need to perform them.

Anyways. Enough talk about what I’ll be talking about. Let’s get to talking about the topic.

Background

Every now and then comes a day when you need to make changes to you cloud configuration – be it fiddling around with custom domains configured to your different services, email stuff or AKS cluster upgrades (I mean – migrating to a new cluster, because that’s the only way to have an upgrade path with a rollback on Azure), that might include stuff changing IP addresses and that means you’ll need to deal with DNS.

Or maybe you’re just crazy enough to host your DNS on Azure because you actually like it. It’s not wrong. Not even that weird. So why not?

Anyway – if your moving the cheese enough that its IP address changes, you’ll start getting odd errors if your DNS entries point to the old IP address. And you don’t want that, do you?

So, one way to make sure your DNS record updates get propagated quickly (even if you’re changing them manually, since you don’t want the old settings to live too long on intermediary name servers or end users’ computers) is to set the entries’ TTL (Time-to-live) values to be something low.

This value is set in seconds, and it’s 3600 by default. That amounts to an hour. An you don’t want that if you know your IP addresses are going to be changing :)

So, what can we do to counter that?

Solution

One way to resolve the issue is to set the TTL to something much lower. You likely still don’t want it to be mere seconds – otherwise all clients will need to constantly ping your name servers and that’s no bueno – but something like a minute might make sense temporarily.

This change can be done with az cli, of course. All of the DNS record commands can be found from az network dns record-set, but to modify any records we need to use the –set key=value -syntax which is a bit devious.

Luckily, for TTL it’s fairly straightforward.

Time needed: 5 minutes

How to change the TTL for all DNS records in one zone using az CLI?

  1. Connect to Azure

    The first step is to make AZ CLI aware of your subscription. This can sometimes be a bit of a bother, but let’s skip the convoluted stuff and assume you are using what I assume to be a fairly common scenario – you have a service principal you want to log in to. I’ll have that script below for you, and a link to other options in the references!

    az login --service-principal -u <app-id> -p <password-or-cert> --tenant <tenant>

  2. Define your zone and resource group

    Next we’ll set up a couple of variables we’ll need later, namely, the zone (domain) we’re targeting and the resource group it’s in:

    $zone = "koskila.net"
    $rg = "koskilanet-rg"


    All values corresponding to real-life instances of any services are, as usual, purely coincidental and should be considered purely works of fiction.

  3. Fetch your records

    Now we can run az network dns record-set a list to fetch any “a” records (short for “address” I presume, stores the IP address where the record should point to) for a given zone:

    $records = az network dns record-set a list -z $zone -g $rg | ConvertFrom-JSON

    Well parse it from JSON and store as objects into our $records collection.

  4. Update your records

    Now comes the nifty one-liner to iterate through a collection and update the TTL value foe each – the key is to pass a recognized attribute in the –set parameter. I’ll add a link to all accepted values in the references-section of the page, as the last I tried, az cli couldn’t list them for you.

    $records | Foreach-object { az network dns record-set a update -g $($_.resourceGroup) -n $($_.name) -z $zone --set ttl=60 }

  5. … Wait

    Now it’s time to wait in order for the changes to actually take hold. You can clear local DNS cache by running:

    ipconfig /flushdns

    But that won’t clear the record from any servers out there – they’ll cache it for as long as the TTL dictates (or as long as they want).

    Well, it’s not like that should be very important for a TTL change… But thought I’d write it down anyway! 😅

Script Sample

Did you think I’d leave you putting the script together based on the steps above? Nope, see for an actual sample below!

The whole script will look something like below:

$zone = "koskila.net"
$rg = "koskilanet-rg"

$records = az network dns record-set a list -z $zone -g $rg | ConvertFrom-JSON

$records | Foreach-object { az network dns record-set a update -g $($_.resourceGroup) -n $($_.name) -z $zone --set ttl=60  }

References

mm
0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments