.netazurednsazure-resource-managerazure-sdk

C#/.NET: How do I create a DNS record in an Azure DNS zone using the new ARM SDK?


I need to programmatically create a TXT DNS record in an Azure DNS zone. Using the Azure.Management.Dns package, this could be achieved like this:

using Azure.Identity;
using Azure.Management.Dns;

var dnsClient = new DnsManagementClient(new DefaultAzureCredential()){SubscriptionId="mySubscriptionId"};
...
await dnsClient.RecordSets.CreateOrUpdateAsync(resourceGroupName, zoneName, recordSetName, RecordType.TXT, recordSet);

Now MS has marked the Azure.Management.Dns package as deprecated and recommends to use the Azure.ResourceManager.Dns package instead. Microsoft's own documentation however still uses the deprecated package, including examples.

Unfortunately, I don't really see where the documentation of the corresponding new ARM models explains how to create a new TXT record, and sadly MS does not provide any examples with that one.

Could someone please point me in the right direction?

Edit: Originally claimed the ARM package would be in beta, turns out it is not.


Solution

  • The new (post-2019) Azure.ResourceManager.* NuGet package libraries have adopted newer C# features like IAsyncEnumerable, which makes some operations nonobvious for discovery by those (like us) who expect a more conventional API design (so it actually took me a while to figure out how to answer your question).

    But you'll want something like this:

    Step 1: Get an authenticated ArmClient instance and your target SubscriptionResource:

    This works for me in Linqpad and console programs, though obviously you'll want to use DefaultAzureCredential in deployed code:

    //#define ARGH_ITS_NOT_WORKING // Uncomment this if you're having AAD/Entra authX problems.
    
    const String TENANT_ID       = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";
    const String SUBSCRIPTION_ID = "ffffffff-1111-2222-3333-444444444444";
    
    #if ARGH_ITS_NOT_WORKING
    using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();
    #endif
    
    InteractiveBrowserCredentialOptions credsOpts = new InteractiveBrowserCredentialOptions()
    {
        DisableAutomaticAuthentication = true,
        TenantId = TENANT_ID
    };
    
    #if ARGH_ITS_NOT_WORKING
    credsOpts.Diagnostics.IsAccountIdentifierLoggingEnabled = true;
    #endif
    
    InteractiveBrowserCredential creds = new InteractiveBrowserCredential( credsOpts );
    AuthenticationRecord authRecord = await creds.AuthenticateAsync();
    
    ArmClient armClient = new ArmClient( creds );
    
    //
    
    SubscriptionResource sub = await armClient.GetDefaultSubscriptionAsync();
    if( sub.Id.SubscriptionId != SUBSCRIPTION_ID ) throw new InvalidOperationException( "Unexpected default Subscription." );
    

    Step 2: Get the Zone, add records, submit:

    using Azure.ResourceManager;
    using Azure.ResourceManager.Dns;
    
    //
    
    List<DnsZoneResource> dnsZones = await sub.GetDnsZonesAsync().ToListAsync();
    DnsZoneResource zone0 = dnsZones.First().Dump();
    
    DnsTxtRecordCollection txtRecords = zone0.GetDnsTxtRecords();
    
    DnsTxtRecordData newTxtRecordValues = new DnsTxtRecordData()
    {
        TtlInSeconds = 300, You must set a non-null TTL or the request will be rejected.
        DnsTxtRecords = 
        {
            new DnsTxtRecordInfo()
            {
                Values = 
                {
                    "foo",
                    "bar"
                }
            }
        }
    };
    
    ArmOperation<DnsTxtRecordResource> newResourceOp = await txtRecords.CreateOrUpdateAsync( WaitUntil.Completed, txtRecordName: "baz", data: newTxtRecordValues );
    DnsTxtRecordResource newResource = newResourceOp.Value;
    
    newResource.Dump();
    

    Screenshot proof:

    enter image description here