The azure-native:privatedns:PrivateRecordSet resource, part of the Pulumi Azure Native provider, defines DNS records within a Private DNS zone: their type, values, and TTL. This guide focuses on four capabilities: A records for IPv4 resolution, CNAME records for aliasing, MX records for mail routing, and SRV records for service discovery.
Record sets belong to Private DNS zones and reference resource groups that must exist separately. The examples are intentionally small. Combine them with your own Private DNS zones and network infrastructure.
Map hostnames to IPv4 addresses with A records
Most private DNS deployments create A records that map hostnames to IPv4 addresses, enabling internal services to resolve by name.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const privateRecordSet = new azure_native.privatedns.PrivateRecordSet("privateRecordSet", {
aRecords: [{
ipv4Address: "1.2.3.4",
}],
metadata: {
key1: "value1",
},
privateZoneName: "privatezone1.com",
recordType: "A",
relativeRecordSetName: "recordA",
resourceGroupName: "resourceGroup1",
ttl: 3600,
});
import pulumi
import pulumi_azure_native as azure_native
private_record_set = azure_native.privatedns.PrivateRecordSet("privateRecordSet",
a_records=[{
"ipv4_address": "1.2.3.4",
}],
metadata={
"key1": "value1",
},
private_zone_name="privatezone1.com",
record_type="A",
relative_record_set_name="recordA",
resource_group_name="resourceGroup1",
ttl=3600)
package main
import (
privatedns "github.com/pulumi/pulumi-azure-native-sdk/privatedns/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := privatedns.NewPrivateRecordSet(ctx, "privateRecordSet", &privatedns.PrivateRecordSetArgs{
ARecords: privatedns.ARecordArray{
&privatedns.ARecordArgs{
Ipv4Address: pulumi.String("1.2.3.4"),
},
},
Metadata: pulumi.StringMap{
"key1": pulumi.String("value1"),
},
PrivateZoneName: pulumi.String("privatezone1.com"),
RecordType: pulumi.String("A"),
RelativeRecordSetName: pulumi.String("recordA"),
ResourceGroupName: pulumi.String("resourceGroup1"),
Ttl: pulumi.Float64(3600),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var privateRecordSet = new AzureNative.PrivateDns.PrivateRecordSet("privateRecordSet", new()
{
ARecords = new[]
{
new AzureNative.PrivateDns.Inputs.ARecordArgs
{
Ipv4Address = "1.2.3.4",
},
},
Metadata =
{
{ "key1", "value1" },
},
PrivateZoneName = "privatezone1.com",
RecordType = "A",
RelativeRecordSetName = "recordA",
ResourceGroupName = "resourceGroup1",
Ttl = 3600,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.privatedns.PrivateRecordSet;
import com.pulumi.azurenative.privatedns.PrivateRecordSetArgs;
import com.pulumi.azurenative.privatedns.inputs.ARecordArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var privateRecordSet = new PrivateRecordSet("privateRecordSet", PrivateRecordSetArgs.builder()
.aRecords(ARecordArgs.builder()
.ipv4Address("1.2.3.4")
.build())
.metadata(Map.of("key1", "value1"))
.privateZoneName("privatezone1.com")
.recordType("A")
.relativeRecordSetName("recordA")
.resourceGroupName("resourceGroup1")
.ttl(3600.0)
.build());
}
}
resources:
privateRecordSet:
type: azure-native:privatedns:PrivateRecordSet
properties:
aRecords:
- ipv4Address: 1.2.3.4
metadata:
key1: value1
privateZoneName: privatezone1.com
recordType: A
relativeRecordSetName: recordA
resourceGroupName: resourceGroup1
ttl: 3600
When a client queries the hostname, DNS returns the IPv4 address from aRecords. The recordType property specifies “A” for IPv4 address records. The relativeRecordSetName sets the hostname within the zone (e.g., “recordA” becomes “recordA.privatezone1.com”). The ttl property controls how long clients cache the response, measured in seconds.
Create aliases with CNAME records
Applications often need DNS aliases that point one hostname to another, allowing you to change targets without updating clients.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const privateRecordSet = new azure_native.privatedns.PrivateRecordSet("privateRecordSet", {
cnameRecord: {
cname: "contoso.com",
},
metadata: {
key1: "value1",
},
privateZoneName: "privatezone1.com",
recordType: "CNAME",
relativeRecordSetName: "recordCNAME",
resourceGroupName: "resourceGroup1",
ttl: 3600,
});
import pulumi
import pulumi_azure_native as azure_native
private_record_set = azure_native.privatedns.PrivateRecordSet("privateRecordSet",
cname_record={
"cname": "contoso.com",
},
metadata={
"key1": "value1",
},
private_zone_name="privatezone1.com",
record_type="CNAME",
relative_record_set_name="recordCNAME",
resource_group_name="resourceGroup1",
ttl=3600)
package main
import (
privatedns "github.com/pulumi/pulumi-azure-native-sdk/privatedns/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := privatedns.NewPrivateRecordSet(ctx, "privateRecordSet", &privatedns.PrivateRecordSetArgs{
CnameRecord: &privatedns.CnameRecordArgs{
Cname: pulumi.String("contoso.com"),
},
Metadata: pulumi.StringMap{
"key1": pulumi.String("value1"),
},
PrivateZoneName: pulumi.String("privatezone1.com"),
RecordType: pulumi.String("CNAME"),
RelativeRecordSetName: pulumi.String("recordCNAME"),
ResourceGroupName: pulumi.String("resourceGroup1"),
Ttl: pulumi.Float64(3600),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var privateRecordSet = new AzureNative.PrivateDns.PrivateRecordSet("privateRecordSet", new()
{
CnameRecord = new AzureNative.PrivateDns.Inputs.CnameRecordArgs
{
Cname = "contoso.com",
},
Metadata =
{
{ "key1", "value1" },
},
PrivateZoneName = "privatezone1.com",
RecordType = "CNAME",
RelativeRecordSetName = "recordCNAME",
ResourceGroupName = "resourceGroup1",
Ttl = 3600,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.privatedns.PrivateRecordSet;
import com.pulumi.azurenative.privatedns.PrivateRecordSetArgs;
import com.pulumi.azurenative.privatedns.inputs.CnameRecordArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var privateRecordSet = new PrivateRecordSet("privateRecordSet", PrivateRecordSetArgs.builder()
.cnameRecord(CnameRecordArgs.builder()
.cname("contoso.com")
.build())
.metadata(Map.of("key1", "value1"))
.privateZoneName("privatezone1.com")
.recordType("CNAME")
.relativeRecordSetName("recordCNAME")
.resourceGroupName("resourceGroup1")
.ttl(3600.0)
.build());
}
}
resources:
privateRecordSet:
type: azure-native:privatedns:PrivateRecordSet
properties:
cnameRecord:
cname: contoso.com
metadata:
key1: value1
privateZoneName: privatezone1.com
recordType: CNAME
relativeRecordSetName: recordCNAME
resourceGroupName: resourceGroup1
ttl: 3600
The cnameRecord property contains a single cname value that points to the target hostname. CNAME records create aliases; when a client queries the alias, DNS returns the target name, which the client then resolves separately. This indirection lets you update the target without changing the alias.
Route email with MX records
Private zones can include MX records for internal mail routing, directing email to specific mail servers with priority-based failover.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const privateRecordSet = new azure_native.privatedns.PrivateRecordSet("privateRecordSet", {
metadata: {
key1: "value1",
},
mxRecords: [{
exchange: "mail.privatezone1.com",
preference: 0,
}],
privateZoneName: "privatezone1.com",
recordType: "MX",
relativeRecordSetName: "recordMX",
resourceGroupName: "resourceGroup1",
ttl: 3600,
});
import pulumi
import pulumi_azure_native as azure_native
private_record_set = azure_native.privatedns.PrivateRecordSet("privateRecordSet",
metadata={
"key1": "value1",
},
mx_records=[{
"exchange": "mail.privatezone1.com",
"preference": 0,
}],
private_zone_name="privatezone1.com",
record_type="MX",
relative_record_set_name="recordMX",
resource_group_name="resourceGroup1",
ttl=3600)
package main
import (
privatedns "github.com/pulumi/pulumi-azure-native-sdk/privatedns/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := privatedns.NewPrivateRecordSet(ctx, "privateRecordSet", &privatedns.PrivateRecordSetArgs{
Metadata: pulumi.StringMap{
"key1": pulumi.String("value1"),
},
MxRecords: privatedns.MxRecordArray{
&privatedns.MxRecordArgs{
Exchange: pulumi.String("mail.privatezone1.com"),
Preference: pulumi.Int(0),
},
},
PrivateZoneName: pulumi.String("privatezone1.com"),
RecordType: pulumi.String("MX"),
RelativeRecordSetName: pulumi.String("recordMX"),
ResourceGroupName: pulumi.String("resourceGroup1"),
Ttl: pulumi.Float64(3600),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var privateRecordSet = new AzureNative.PrivateDns.PrivateRecordSet("privateRecordSet", new()
{
Metadata =
{
{ "key1", "value1" },
},
MxRecords = new[]
{
new AzureNative.PrivateDns.Inputs.MxRecordArgs
{
Exchange = "mail.privatezone1.com",
Preference = 0,
},
},
PrivateZoneName = "privatezone1.com",
RecordType = "MX",
RelativeRecordSetName = "recordMX",
ResourceGroupName = "resourceGroup1",
Ttl = 3600,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.privatedns.PrivateRecordSet;
import com.pulumi.azurenative.privatedns.PrivateRecordSetArgs;
import com.pulumi.azurenative.privatedns.inputs.MxRecordArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var privateRecordSet = new PrivateRecordSet("privateRecordSet", PrivateRecordSetArgs.builder()
.metadata(Map.of("key1", "value1"))
.mxRecords(MxRecordArgs.builder()
.exchange("mail.privatezone1.com")
.preference(0)
.build())
.privateZoneName("privatezone1.com")
.recordType("MX")
.relativeRecordSetName("recordMX")
.resourceGroupName("resourceGroup1")
.ttl(3600.0)
.build());
}
}
resources:
privateRecordSet:
type: azure-native:privatedns:PrivateRecordSet
properties:
metadata:
key1: value1
mxRecords:
- exchange: mail.privatezone1.com
preference: 0
privateZoneName: privatezone1.com
recordType: MX
relativeRecordSetName: recordMX
resourceGroupName: resourceGroup1
ttl: 3600
The mxRecords array lists mail servers with their exchange hostnames and preference values. Lower preference numbers indicate higher priority; mail clients try servers in priority order. This enables failover: if the primary server is unavailable, clients automatically try the next priority level.
Advertise service locations with SRV records
Service discovery protocols use SRV records to locate services by protocol and domain, encoding port numbers and load distribution.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const privateRecordSet = new azure_native.privatedns.PrivateRecordSet("privateRecordSet", {
metadata: {
key1: "value1",
},
privateZoneName: "privatezone1.com",
recordType: "SRV",
relativeRecordSetName: "recordSRV",
resourceGroupName: "resourceGroup1",
srvRecords: [{
port: 80,
priority: 0,
target: "contoso.com",
weight: 10,
}],
ttl: 3600,
});
import pulumi
import pulumi_azure_native as azure_native
private_record_set = azure_native.privatedns.PrivateRecordSet("privateRecordSet",
metadata={
"key1": "value1",
},
private_zone_name="privatezone1.com",
record_type="SRV",
relative_record_set_name="recordSRV",
resource_group_name="resourceGroup1",
srv_records=[{
"port": 80,
"priority": 0,
"target": "contoso.com",
"weight": 10,
}],
ttl=3600)
package main
import (
privatedns "github.com/pulumi/pulumi-azure-native-sdk/privatedns/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := privatedns.NewPrivateRecordSet(ctx, "privateRecordSet", &privatedns.PrivateRecordSetArgs{
Metadata: pulumi.StringMap{
"key1": pulumi.String("value1"),
},
PrivateZoneName: pulumi.String("privatezone1.com"),
RecordType: pulumi.String("SRV"),
RelativeRecordSetName: pulumi.String("recordSRV"),
ResourceGroupName: pulumi.String("resourceGroup1"),
SrvRecords: privatedns.SrvRecordArray{
&privatedns.SrvRecordArgs{
Port: pulumi.Int(80),
Priority: pulumi.Int(0),
Target: pulumi.String("contoso.com"),
Weight: pulumi.Int(10),
},
},
Ttl: pulumi.Float64(3600),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var privateRecordSet = new AzureNative.PrivateDns.PrivateRecordSet("privateRecordSet", new()
{
Metadata =
{
{ "key1", "value1" },
},
PrivateZoneName = "privatezone1.com",
RecordType = "SRV",
RelativeRecordSetName = "recordSRV",
ResourceGroupName = "resourceGroup1",
SrvRecords = new[]
{
new AzureNative.PrivateDns.Inputs.SrvRecordArgs
{
Port = 80,
Priority = 0,
Target = "contoso.com",
Weight = 10,
},
},
Ttl = 3600,
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.privatedns.PrivateRecordSet;
import com.pulumi.azurenative.privatedns.PrivateRecordSetArgs;
import com.pulumi.azurenative.privatedns.inputs.SrvRecordArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var privateRecordSet = new PrivateRecordSet("privateRecordSet", PrivateRecordSetArgs.builder()
.metadata(Map.of("key1", "value1"))
.privateZoneName("privatezone1.com")
.recordType("SRV")
.relativeRecordSetName("recordSRV")
.resourceGroupName("resourceGroup1")
.srvRecords(SrvRecordArgs.builder()
.port(80)
.priority(0)
.target("contoso.com")
.weight(10)
.build())
.ttl(3600.0)
.build());
}
}
resources:
privateRecordSet:
type: azure-native:privatedns:PrivateRecordSet
properties:
metadata:
key1: value1
privateZoneName: privatezone1.com
recordType: SRV
relativeRecordSetName: recordSRV
resourceGroupName: resourceGroup1
srvRecords:
- port: 80
priority: 0
target: contoso.com
weight: 10
ttl: 3600
The srvRecords array defines service endpoints with port, priority, target, and weight properties. Priority controls failover order (lower values first). Weight enables load distribution among servers with the same priority; higher weights receive proportionally more traffic. The target specifies the hostname, and port indicates which TCP or UDP port the service listens on.
Beyond these examples
These snippets focus on specific record set features: DNS record types (A, CNAME, MX, SRV) and TTL and metadata configuration. They’re intentionally minimal rather than complete DNS zone configurations.
The examples reference pre-existing infrastructure such as Private DNS zones (privateZoneName) and Azure resource groups. They focus on configuring individual record sets rather than provisioning the surrounding DNS infrastructure.
To keep things focused, common record types are omitted, including:
- AAAA records for IPv6 addressing
- PTR records for reverse DNS lookups
- SOA records for zone authority configuration
- TXT records for verification and SPF
These omissions are intentional: the goal is to illustrate how each record type is wired, not provide drop-in DNS modules. See the Private DNS PrivateRecordSet resource reference for all available configuration options.
Let's configure Azure Private DNS Record Sets
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Record Types & Configuration
recordType to your desired type (A, AAAA, CNAME, MX, PTR, SOA, SRV, or TXT) and configure the corresponding property. For example, use aRecords for A records, cnameRecord for CNAME, or mxRecords for MX records.cnameRecord) because DNS allows only one CNAME per name. Other record types like A, AAAA, MX, PTR, SRV, and TXT use arrays (aRecords, mxRecords, etc.) to support multiple values.ttl property to specify time-to-live in seconds. Examples in the schema use 3600 (1 hour).Immutability & Updates
privateZoneName, recordType, relativeRecordSetName, and resourceGroupName properties are immutable. Changing any of these requires destroying and recreating the resource.recordType is immutable. To change the type, you must delete the existing record set and create a new one with the desired type.Special Record Types
recordType to “SOA” and relativeRecordSetName to “@”. Configure the soaRecord object with email, host, expireTime, minimumTtl, refreshTime, retryTime, and serialNumber.