Skip to content
v2.273.0

Amazon Route53 Construct Library ​

To add a public hosted zone:

ts
new route53.PublicHostedZone(this, 'HostedZone', {
  zoneName: 'fully.qualified.domain.com',
});
python
route53.PublicHostedZone(self, "HostedZone",
    zone_name="fully.qualified.domain.com"
)
java
PublicHostedZone.Builder.create(this, "HostedZone")
        .zoneName("fully.qualified.domain.com")
        .build();
csharp
new PublicHostedZone(this, "HostedZone", new PublicHostedZoneProps {
    ZoneName = "fully.qualified.domain.com"
});
go
route53.NewPublicHostedZone(this, jsii.String("HostedZone"), &PublicHostedZoneProps{
	ZoneName: jsii.String("fully.qualified.domain.com"),
})

To add a private hosted zone, use PrivateHostedZone. Note that enableDnsHostnames and enableDnsSupport must have been enabled for the VPC you're configuring for private hosted zones.

ts
declare const vpc: ec2.Vpc;

const zone = new route53.PrivateHostedZone(this, 'HostedZone', {
  zoneName: 'fully.qualified.domain.com',
  vpc,    // At least one VPC has to be added to a Private Hosted Zone.
});
python
# vpc: ec2.Vpc


zone = route53.PrivateHostedZone(self, "HostedZone",
    zone_name="fully.qualified.domain.com",
    vpc=vpc
)
java
Vpc vpc;


PrivateHostedZone zone = PrivateHostedZone.Builder.create(this, "HostedZone")
        .zoneName("fully.qualified.domain.com")
        .vpc(vpc)
        .build();
csharp
Vpc vpc;


var zone = new PrivateHostedZone(this, "HostedZone", new PrivateHostedZoneProps {
    ZoneName = "fully.qualified.domain.com",
    Vpc = vpc
});
go
var vpc Vpc


zone := route53.NewPrivateHostedZone(this, jsii.String("HostedZone"), &PrivateHostedZoneProps{
	ZoneName: jsii.String("fully.qualified.domain.com"),
	Vpc: Vpc,
})

Additional VPCs can be added with zone.addVpc().

Adding Records ​

To add a TXT record to your zone:

ts
declare const myZone: route53.HostedZone;

new route53.TxtRecord(this, 'TXTRecord', {
  zone: myZone,
  recordName: '_foo',  // If the name ends with a ".", it will be used as-is;
                       // if it ends with a "." followed by the zone name, a trailing "." will be added automatically;
                       // otherwise, a ".", the zone name, and a trailing "." will be added automatically.
                       // Defaults to zone root if not specified.
  values: [            // Will be quoted for you, and " will be escaped automatically.
    'Bar!',
    'Baz?',
  ],
  ttl: Duration.minutes(90),       // Optional - default is 30 minutes
});
python
# my_zone: route53.HostedZone


route53.TxtRecord(self, "TXTRecord",
    zone=my_zone,
    record_name="_foo",  # If the name ends with a ".", it will be used as-is;
    # if it ends with a "." followed by the zone name, a trailing "." will be added automatically;
    # otherwise, a ".", the zone name, and a trailing "." will be added automatically.
    # Defaults to zone root if not specified.
    values=["Bar!", "Baz?"],
    ttl=Duration.minutes(90)
)
java
HostedZone myZone;


TxtRecord.Builder.create(this, "TXTRecord")
        .zone(myZone)
        .recordName("_foo") // If the name ends with a ".", it will be used as-is;
        // if it ends with a "." followed by the zone name, a trailing "." will be added automatically;
        // otherwise, a ".", the zone name, and a trailing "." will be added automatically.
        // Defaults to zone root if not specified.
        .values(List.of("Bar!", "Baz?"))
        .ttl(Duration.minutes(90))
        .build();
csharp
HostedZone myZone;


new TxtRecord(this, "TXTRecord", new TxtRecordProps {
    Zone = myZone,
    RecordName = "_foo",  // If the name ends with a ".", it will be used as-is;
    // if it ends with a "." followed by the zone name, a trailing "." will be added automatically;
    // otherwise, a ".", the zone name, and a trailing "." will be added automatically.
    // Defaults to zone root if not specified.
    Values = new [] { "Bar!", "Baz?" },
    Ttl = Duration.Minutes(90)
});
go
var myZone HostedZone


route53.NewTxtRecord(this, jsii.String("TXTRecord"), &TxtRecordProps{
	Zone: myZone,
	RecordName: jsii.String("_foo"),
	 // If the name ends with a ".", it will be used as-is;
	// if it ends with a "." followed by the zone name, a trailing "." will be added automatically;
	// otherwise, a ".", the zone name, and a trailing "." will be added automatically.
	// Defaults to zone root if not specified.
	Values: []*string{
		jsii.String("Bar!"),
		jsii.String("Baz?"),
	},
	Ttl: awscdk.Duration_Minutes(jsii.Number(90)),
})

To add a NS record to your zone:

ts
declare const myZone: route53.HostedZone;

new route53.NsRecord(this, 'NSRecord', {
  zone: myZone,
  recordName: 'foo',
  values: [
    'ns-1.awsdns.co.uk.',
    'ns-2.awsdns.com.',
  ],
  ttl: Duration.minutes(90),       // Optional - default is 30 minutes
});
python
# my_zone: route53.HostedZone


route53.NsRecord(self, "NSRecord",
    zone=my_zone,
    record_name="foo",
    values=["ns-1.awsdns.co.uk.", "ns-2.awsdns.com."
    ],
    ttl=Duration.minutes(90)
)
java
HostedZone myZone;


NsRecord.Builder.create(this, "NSRecord")
        .zone(myZone)
        .recordName("foo")
        .values(List.of("ns-1.awsdns.co.uk.", "ns-2.awsdns.com."))
        .ttl(Duration.minutes(90))
        .build();
csharp
HostedZone myZone;


new NsRecord(this, "NSRecord", new NsRecordProps {
    Zone = myZone,
    RecordName = "foo",
    Values = new [] { "ns-1.awsdns.co.uk.", "ns-2.awsdns.com." },
    Ttl = Duration.Minutes(90)
});
go
var myZone HostedZone


route53.NewNsRecord(this, jsii.String("NSRecord"), &NsRecordProps{
	Zone: myZone,
	RecordName: jsii.String("foo"),
	Values: []*string{
		jsii.String("ns-1.awsdns.co.uk."),
		jsii.String("ns-2.awsdns.com."),
	},
	Ttl: awscdk.Duration_Minutes(jsii.Number(90)),
})

To add a DS record to your zone:

ts
declare const myZone: route53.HostedZone;

new route53.DsRecord(this, 'DSRecord', {
  zone: myZone,
  recordName: 'foo',
  values: [
    '12345 3 1 123456789abcdef67890123456789abcdef67890',
  ],
  ttl: Duration.minutes(90),       // Optional - default is 30 minutes
});
python
# my_zone: route53.HostedZone


route53.DsRecord(self, "DSRecord",
    zone=my_zone,
    record_name="foo",
    values=["12345 3 1 123456789abcdef67890123456789abcdef67890"
    ],
    ttl=Duration.minutes(90)
)
java
HostedZone myZone;


DsRecord.Builder.create(this, "DSRecord")
        .zone(myZone)
        .recordName("foo")
        .values(List.of("12345 3 1 123456789abcdef67890123456789abcdef67890"))
        .ttl(Duration.minutes(90))
        .build();
csharp
HostedZone myZone;


new DsRecord(this, "DSRecord", new DsRecordProps {
    Zone = myZone,
    RecordName = "foo",
    Values = new [] { "12345 3 1 123456789abcdef67890123456789abcdef67890" },
    Ttl = Duration.Minutes(90)
});
go
var myZone HostedZone


route53.NewDsRecord(this, jsii.String("DSRecord"), &DsRecordProps{
	Zone: myZone,
	RecordName: jsii.String("foo"),
	Values: []*string{
		jsii.String("12345 3 1 123456789abcdef67890123456789abcdef67890"),
	},
	Ttl: awscdk.Duration_Minutes(jsii.Number(90)),
})

To add an A record to your zone:

ts
declare const myZone: route53.HostedZone;

new route53.ARecord(this, 'ARecord', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.4', '5.6.7.8'),
});
python
# my_zone: route53.HostedZone


route53.ARecord(self, "ARecord",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.4", "5.6.7.8")
)
java
HostedZone myZone;


ARecord.Builder.create(this, "ARecord")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.4", "5.6.7.8"))
        .build();
csharp
HostedZone myZone;


new ARecord(this, "ARecord", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.4", "5.6.7.8")
});
go
var myZone HostedZone


route53.NewARecord(this, jsii.String("ARecord"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.4"), jsii.String("5.6.7.8")),
})

To add an A record for an EC2 instance with an Elastic IP (EIP) to your zone:

ts
declare const instance: ec2.Instance;

const elasticIp = new ec2.CfnEIP(this, 'EIP', {
  domain: 'vpc',
  instanceId: instance.instanceId,
});

declare const myZone: route53.HostedZone;
new route53.ARecord(this, 'ARecord', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses(elasticIp.ref),
});
python
# instance: ec2.Instance

# my_zone: route53.HostedZone


elastic_ip = ec2.CfnEIP(self, "EIP",
    domain="vpc",
    instance_id=instance.instance_id
)
route53.ARecord(self, "ARecord",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses(elastic_ip.ref)
)
java
Instance instance;

HostedZone myZone;


CfnEIP elasticIp = CfnEIP.Builder.create(this, "EIP")
        .domain("vpc")
        .instanceId(instance.getInstanceId())
        .build();
ARecord.Builder.create(this, "ARecord")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses(elasticIp.getRef()))
        .build();
csharp
Instance instance;

HostedZone myZone;


var elasticIp = new CfnEIP(this, "EIP", new CfnEIPProps {
    Domain = "vpc",
    InstanceId = instance.InstanceId
});
new ARecord(this, "ARecord", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses(elasticIp.Ref)
});
go
var instance Instance

var myZone HostedZone


elasticIp := ec2.NewCfnEIP(this, jsii.String("EIP"), &CfnEIPProps{
	Domain: jsii.String("vpc"),
	InstanceId: instance.InstanceId,
})
route53.NewARecord(this, jsii.String("ARecord"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(elasticIp.ref),
})

To create an A record of type alias with target set to another record created outside CDK:

This function registers the given input i.e. DNS Name(string) of an existing record as an AliasTarget to the new ARecord. To register a target that is created as part of CDK use this instead.

Detailed information can be found in the documentation.

ts
declare const myZone: route53.HostedZone;

const targetRecord = 'existing.record.cdk.local';
const record = route53.ARecord.fromARecordAttributes(this, 'A', {
  zone: myZone,
  recordName: 'test',
  targetDNS: targetRecord,
});
python
# my_zone: route53.HostedZone


target_record = "existing.record.cdk.local"
record = route53.ARecord.from_a_record_attributes(self, "A",
    zone=my_zone,
    record_name="test",
    target_dns=target_record
)
java
HostedZone myZone;


String targetRecord = "existing.record.cdk.local";
ARecord record = ARecord.fromARecordAttributes(this, "A", ARecordAttrs.builder()
        .zone(myZone)
        .recordName("test")
        .targetDNS(targetRecord)
        .build());
csharp
HostedZone myZone;


var targetRecord = "existing.record.cdk.local";
var record = ARecord.FromARecordAttributes(this, "A", new ARecordAttrs {
    Zone = myZone,
    RecordName = "test",
    TargetDNS = targetRecord
});
go
var myZone HostedZone


targetRecord := "existing.record.cdk.local"
record := route53.ARecord_FromARecordAttributes(this, jsii.String("A"), &ARecordAttrs{
	Zone: myZone,
	RecordName: jsii.String("test"),
	TargetDNS: targetRecord,
})

To add an AAAA record pointing to a CloudFront distribution:

ts
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';

declare const myZone: route53.HostedZone;
declare const distribution: cloudfront.CloudFrontWebDistribution;
new route53.AaaaRecord(this, 'Alias', {
  zone: myZone,
  target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(distribution)),
});
python
import aws_cdk.aws_cloudfront as cloudfront

# my_zone: route53.HostedZone
# distribution: cloudfront.CloudFrontWebDistribution

route53.AaaaRecord(self, "Alias",
    zone=my_zone,
    target=route53.RecordTarget.from_alias(targets.CloudFrontTarget(distribution))
)
java
import software.amazon.awscdk.services.cloudfront.*;

HostedZone myZone;
CloudFrontWebDistribution distribution;

AaaaRecord.Builder.create(this, "Alias")
        .zone(myZone)
        .target(RecordTarget.fromAlias(new CloudFrontTarget(distribution)))
        .build();
csharp
using Amazon.CDK.AWS.CloudFront;

HostedZone myZone;
CloudFrontWebDistribution distribution;

new AaaaRecord(this, "Alias", new AaaaRecordProps {
    Zone = myZone,
    Target = RecordTarget.FromAlias(new CloudFrontTarget(distribution))
});
go
import cloudfront "github.com/aws/aws-cdk-go/awscdk"

var myZone HostedZone
var distribution CloudFrontWebDistribution

route53.NewAaaaRecord(this, jsii.String("Alias"), &AaaaRecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromAlias(targets.NewCloudFrontTarget(distribution)),
})

To add an HTTPS record:

ts
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';

declare const myZone: route53.HostedZone;
declare const distribution: cloudfront.CloudFrontWebDistribution;
// Alias to CloudFront target
new route53.HttpsRecord(this, 'HttpsRecord-CloudFrontAlias', {
  zone: myZone,
  target: route53.RecordTarget.fromAlias(new targets.CloudFrontTarget(distribution)),
});
// ServiceMode (priority >= 1)
new route53.HttpsRecord(this, 'HttpsRecord-ServiceMode', {
  zone: myZone,
  values: [route53.HttpsRecordValue.service({ alpn: [route53.Alpn.H3, route53.Alpn.H2] })],
});
// AliasMode (priority = 0)
new route53.HttpsRecord(this, 'HttpsRecord-AliasMode', {
  zone: myZone,
  values: [route53.HttpsRecordValue.alias('service.example.com')],
});
python
import aws_cdk.aws_cloudfront as cloudfront

# my_zone: route53.HostedZone
# distribution: cloudfront.CloudFrontWebDistribution

# Alias to CloudFront target
route53.HttpsRecord(self, "HttpsRecord-CloudFrontAlias",
    zone=my_zone,
    target=route53.RecordTarget.from_alias(targets.CloudFrontTarget(distribution))
)
# ServiceMode (priority >= 1)
route53.HttpsRecord(self, "HttpsRecord-ServiceMode",
    zone=my_zone,
    values=[route53.HttpsRecordValue.service(alpn=[route53.Alpn.H3, route53.Alpn.H2])]
)
# AliasMode (priority = 0)
route53.HttpsRecord(self, "HttpsRecord-AliasMode",
    zone=my_zone,
    values=[route53.HttpsRecordValue.alias("service.example.com")]
)
java
import software.amazon.awscdk.services.cloudfront.*;

HostedZone myZone;
CloudFrontWebDistribution distribution;

// Alias to CloudFront target
// Alias to CloudFront target
HttpsRecord.Builder.create(this, "HttpsRecord-CloudFrontAlias")
        .zone(myZone)
        .target(RecordTarget.fromAlias(new CloudFrontTarget(distribution)))
        .build();
// ServiceMode (priority >= 1)
// ServiceMode (priority >= 1)
HttpsRecord.Builder.create(this, "HttpsRecord-ServiceMode")
        .zone(myZone)
        .values(List.of(HttpsRecordValue.service(HttpsRecordServiceModeProps.builder().alpn(List.of(Alpn.H3, Alpn.H2)).build())))
        .build();
// AliasMode (priority = 0)
// AliasMode (priority = 0)
HttpsRecord.Builder.create(this, "HttpsRecord-AliasMode")
        .zone(myZone)
        .values(List.of(HttpsRecordValue.alias("service.example.com")))
        .build();
csharp
using Amazon.CDK.AWS.CloudFront;

HostedZone myZone;
CloudFrontWebDistribution distribution;

// Alias to CloudFront target
// Alias to CloudFront target
new HttpsRecord(this, "HttpsRecord-CloudFrontAlias", new HttpsRecordProps {
    Zone = myZone,
    Target = RecordTarget.FromAlias(new CloudFrontTarget(distribution))
});
// ServiceMode (priority >= 1)
// ServiceMode (priority >= 1)
new HttpsRecord(this, "HttpsRecord-ServiceMode", new HttpsRecordProps {
    Zone = myZone,
    Values = new [] { HttpsRecordValue.Service(new HttpsRecordServiceModeProps { Alpn = new [] { Alpn.H3, Alpn.H2 } }) }
});
// AliasMode (priority = 0)
// AliasMode (priority = 0)
new HttpsRecord(this, "HttpsRecord-AliasMode", new HttpsRecordProps {
    Zone = myZone,
    Values = new [] { HttpsRecordValue.Alias("service.example.com") }
});
go
import cloudfront "github.com/aws/aws-cdk-go/awscdk"

var myZone HostedZone
var distribution CloudFrontWebDistribution

// Alias to CloudFront target
// Alias to CloudFront target
route53.NewHttpsRecord(this, jsii.String("HttpsRecord-CloudFrontAlias"), &HttpsRecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromAlias(targets.NewCloudFrontTarget(distribution)),
})
// ServiceMode (priority >= 1)
// ServiceMode (priority >= 1)
route53.NewHttpsRecord(this, jsii.String("HttpsRecord-ServiceMode"), &HttpsRecordProps{
	Zone: myZone,
	Values: []HttpsRecordValue{
		route53.HttpsRecordValue_Service(&HttpsRecordServiceModeProps{
			Alpn: []Alpn{
				route53.Alpn_H3(),
				route53.Alpn_H2(),
			},
		}),
	},
})
// AliasMode (priority = 0)
// AliasMode (priority = 0)
route53.NewHttpsRecord(this, jsii.String("HttpsRecord-AliasMode"), &HttpsRecordProps{
	Zone: myZone,
	Values: []HttpsRecordValue{
		route53.HttpsRecordValue_Alias(jsii.String("service.example.com")),
	},
})

Geolocation routing can be enabled for continent, country or subdivision:

ts
declare const myZone: route53.HostedZone;

// continent
new route53.ARecord(this, 'ARecordGeoLocationContinent', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.0', '5.6.7.0'),
  geoLocation: route53.GeoLocation.continent(route53.Continent.EUROPE),
});

// country
new route53.ARecord(this, 'ARecordGeoLocationCountry', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.1', '5.6.7.1'),
  geoLocation: route53.GeoLocation.country('DE'), // Germany
});

// subdivision
new route53.ARecord(this, 'ARecordGeoLocationSubDividion', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.2', '5.6.7.2'),
  geoLocation: route53.GeoLocation.subdivision('WA'), // Washington
});

// default (wildcard record if no specific record is found)
new route53.ARecord(this, 'ARecordGeoLocationDefault', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.3', '5.6.7.3'),
  geoLocation: route53.GeoLocation.default(),
});
python
# my_zone: route53.HostedZone


# continent
route53.ARecord(self, "ARecordGeoLocationContinent",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.0", "5.6.7.0"),
    geo_location=route53.GeoLocation.continent(route53.Continent.EUROPE)
)

# country
route53.ARecord(self, "ARecordGeoLocationCountry",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.1", "5.6.7.1"),
    geo_location=route53.GeoLocation.country("DE")
)

# subdivision
route53.ARecord(self, "ARecordGeoLocationSubDividion",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.2", "5.6.7.2"),
    geo_location=route53.GeoLocation.subdivision("WA")
)

# default (wildcard record if no specific record is found)
route53.ARecord(self, "ARecordGeoLocationDefault",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.3", "5.6.7.3"),
    geo_location=route53.GeoLocation.default()
)
java
HostedZone myZone;


// continent
// continent
ARecord.Builder.create(this, "ARecordGeoLocationContinent")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.0", "5.6.7.0"))
        .geoLocation(GeoLocation.continent(Continent.EUROPE))
        .build();

// country
// country
ARecord.Builder.create(this, "ARecordGeoLocationCountry")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.1", "5.6.7.1"))
        .geoLocation(GeoLocation.country("DE"))
        .build();

// subdivision
// subdivision
ARecord.Builder.create(this, "ARecordGeoLocationSubDividion")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.2", "5.6.7.2"))
        .geoLocation(GeoLocation.subdivision("WA"))
        .build();

// default (wildcard record if no specific record is found)
// default (wildcard record if no specific record is found)
ARecord.Builder.create(this, "ARecordGeoLocationDefault")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.3", "5.6.7.3"))
        .geoLocation(GeoLocation.default())
        .build();
csharp
HostedZone myZone;


// continent
// continent
new ARecord(this, "ARecordGeoLocationContinent", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.0", "5.6.7.0"),
    GeoLocation = GeoLocation.Continent(Continent.EUROPE)
});

// country
// country
new ARecord(this, "ARecordGeoLocationCountry", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.1", "5.6.7.1"),
    GeoLocation = GeoLocation.Country("DE")
});

// subdivision
// subdivision
new ARecord(this, "ARecordGeoLocationSubDividion", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.2", "5.6.7.2"),
    GeoLocation = GeoLocation.Subdivision("WA")
});

// default (wildcard record if no specific record is found)
// default (wildcard record if no specific record is found)
new ARecord(this, "ARecordGeoLocationDefault", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.3", "5.6.7.3"),
    GeoLocation = GeoLocation.Default()
});
go
var myZone HostedZone


// continent
// continent
route53.NewARecord(this, jsii.String("ARecordGeoLocationContinent"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.0"), jsii.String("5.6.7.0")),
	GeoLocation: route53.GeoLocation_Continent(route53.Continent_EUROPE),
})

// country
// country
route53.NewARecord(this, jsii.String("ARecordGeoLocationCountry"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_*FromIpAddresses(jsii.String("1.2.3.1"), jsii.String("5.6.7.1")),
	GeoLocation: route53.GeoLocation_Country(jsii.String("DE")),
})

// subdivision
// subdivision
route53.NewARecord(this, jsii.String("ARecordGeoLocationSubDividion"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_*FromIpAddresses(jsii.String("1.2.3.2"), jsii.String("5.6.7.2")),
	GeoLocation: route53.GeoLocation_Subdivision(jsii.String("WA")),
})

// default (wildcard record if no specific record is found)
// default (wildcard record if no specific record is found)
route53.NewARecord(this, jsii.String("ARecordGeoLocationDefault"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_*FromIpAddresses(jsii.String("1.2.3.3"), jsii.String("5.6.7.3")),
	GeoLocation: route53.GeoLocation_Default(),
})

To enable weighted routing, use the weight parameter:

ts
declare const myZone: route53.HostedZone;

new route53.ARecord(this, 'ARecordWeighted1', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.4'),
  weight: 10,
});
python
# my_zone: route53.HostedZone


route53.ARecord(self, "ARecordWeighted1",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.4"),
    weight=10
)
java
HostedZone myZone;


ARecord.Builder.create(this, "ARecordWeighted1")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.4"))
        .weight(10)
        .build();
csharp
HostedZone myZone;


new ARecord(this, "ARecordWeighted1", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.4"),
    Weight = 10
});
go
var myZone HostedZone


route53.NewARecord(this, jsii.String("ARecordWeighted1"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.4")),
	Weight: jsii.Number(10),
})

To enable latency based routing, use the region parameter:

ts
declare const myZone: route53.HostedZone;

new route53.ARecord(this, 'ARecordLatency1', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.4'),
  region: 'us-east-1',
});
python
# my_zone: route53.HostedZone


route53.ARecord(self, "ARecordLatency1",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.4"),
    region="us-east-1"
)
java
HostedZone myZone;


ARecord.Builder.create(this, "ARecordLatency1")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.4"))
        .region("us-east-1")
        .build();
csharp
HostedZone myZone;


new ARecord(this, "ARecordLatency1", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.4"),
    Region = "us-east-1"
});
go
var myZone HostedZone


route53.NewARecord(this, jsii.String("ARecordLatency1"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.4")),
	Region: jsii.String("us-east-1"),
})

To enable failover routing, use the failover parameter:

ts
declare const myZone: route53.HostedZone;

const healthCheck = new route53.HealthCheck(this, 'HealthCheck', {
  type: route53.HealthCheckType.HTTP,
  fqdn: 'example.com',
  port: 80,
  resourcePath: '/health',
  failureThreshold: 3,
  requestInterval: Duration.seconds(30),
});

new route53.ARecord(this, 'ARecordFailoverPrimary', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.4'),
  failover: route53.Failover.PRIMARY,
  healthCheck,
  setIdentifier: 'failover-primary',
});

new route53.ARecord(this, 'ARecordFailoverSecondary', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('5.6.7.8'),
  failover: route53.Failover.SECONDARY,
  setIdentifier: 'failover-secondary',
});
python
# my_zone: route53.HostedZone


health_check = route53.HealthCheck(self, "HealthCheck",
    type=route53.HealthCheckType.HTTP,
    fqdn="example.com",
    port=80,
    resource_path="/health",
    failure_threshold=3,
    request_interval=Duration.seconds(30)
)

route53.ARecord(self, "ARecordFailoverPrimary",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.4"),
    failover=route53.Failover.PRIMARY,
    health_check=health_check,
    set_identifier="failover-primary"
)

route53.ARecord(self, "ARecordFailoverSecondary",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("5.6.7.8"),
    failover=route53.Failover.SECONDARY,
    set_identifier="failover-secondary"
)
java
HostedZone myZone;


HealthCheck healthCheck = HealthCheck.Builder.create(this, "HealthCheck")
        .type(HealthCheckType.HTTP)
        .fqdn("example.com")
        .port(80)
        .resourcePath("/health")
        .failureThreshold(3)
        .requestInterval(Duration.seconds(30))
        .build();

ARecord.Builder.create(this, "ARecordFailoverPrimary")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.4"))
        .failover(Failover.PRIMARY)
        .healthCheck(healthCheck)
        .setIdentifier("failover-primary")
        .build();

ARecord.Builder.create(this, "ARecordFailoverSecondary")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("5.6.7.8"))
        .failover(Failover.SECONDARY)
        .setIdentifier("failover-secondary")
        .build();
csharp
HostedZone myZone;


var healthCheck = new HealthCheck(this, "HealthCheck", new HealthCheckProps {
    Type = HealthCheckType.HTTP,
    Fqdn = "example.com",
    Port = 80,
    ResourcePath = "/health",
    FailureThreshold = 3,
    RequestInterval = Duration.Seconds(30)
});

new ARecord(this, "ARecordFailoverPrimary", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.4"),
    Failover = Failover.PRIMARY,
    HealthCheck = healthCheck,
    SetIdentifier = "failover-primary"
});

new ARecord(this, "ARecordFailoverSecondary", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("5.6.7.8"),
    Failover = Failover.SECONDARY,
    SetIdentifier = "failover-secondary"
});
go
var myZone HostedZone


healthCheck := route53.NewHealthCheck(this, jsii.String("HealthCheck"), &HealthCheckProps{
	Type: route53.HealthCheckType_HTTP,
	Fqdn: jsii.String("example.com"),
	Port: jsii.Number(80),
	ResourcePath: jsii.String("/health"),
	FailureThreshold: jsii.Number(3),
	RequestInterval: awscdk.Duration_Seconds(jsii.Number(30)),
})

route53.NewARecord(this, jsii.String("ARecordFailoverPrimary"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.4")),
	Failover: route53.Failover_PRIMARY,
	HealthCheck: HealthCheck,
	SetIdentifier: jsii.String("failover-primary"),
})

route53.NewARecord(this, jsii.String("ARecordFailoverSecondary"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_*FromIpAddresses(jsii.String("5.6.7.8")),
	Failover: route53.Failover_SECONDARY,
	SetIdentifier: jsii.String("failover-secondary"),
})

To enable multivalue answer routing, use the multivalueAnswer parameter:

ts
declare const myZone: route53.HostedZone;

new route53.ARecord(this, 'ARecordMultiValue1', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.4'),
  multiValueAnswer: true,
});
python
# my_zone: route53.HostedZone


route53.ARecord(self, "ARecordMultiValue1",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.4"),
    multi_value_answer=True
)
java
HostedZone myZone;


ARecord.Builder.create(this, "ARecordMultiValue1")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.4"))
        .multiValueAnswer(true)
        .build();
csharp
HostedZone myZone;


new ARecord(this, "ARecordMultiValue1", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.4"),
    MultiValueAnswer = true
});
go
var myZone HostedZone


route53.NewARecord(this, jsii.String("ARecordMultiValue1"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.4")),
	MultiValueAnswer: jsii.Boolean(true),
})

To enable IP-based routing, use the cidrRoutingConfig parameter:

ts
declare const myZone: route53.HostedZone;

const cidrCollection = new route53.CfnCidrCollection(this, 'CidrCollection', {
  name: 'test-collection',
  locations: [{
    cidrList: ['192.168.1.0/24'],
    locationName: 'my_location',
  }]
});

new route53.ARecord(this, 'CidrRoutingConfig', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.4'),
  setIdentifier: 'test',
  cidrRoutingConfig: route53.CidrRoutingConfig.create({
    collectionId: cidrCollection.attrId,
    locationName: 'test_location'
  }),
});
python
# my_zone: route53.HostedZone


cidr_collection = route53.CfnCidrCollection(self, "CidrCollection",
    name="test-collection",
    locations=[route53.CfnCidrCollection.LocationProperty(
        cidr_list=["192.168.1.0/24"],
        location_name="my_location"
    )]
)

route53.ARecord(self, "CidrRoutingConfig",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.4"),
    set_identifier="test",
    cidr_routing_config=route53.CidrRoutingConfig.create(
        collection_id=cidr_collection.attr_id,
        location_name="test_location"
    )
)
java
HostedZone myZone;


CfnCidrCollection cidrCollection = CfnCidrCollection.Builder.create(this, "CidrCollection")
        .name("test-collection")
        .locations(List.of(LocationProperty.builder()
                .cidrList(List.of("192.168.1.0/24"))
                .locationName("my_location")
                .build()))
        .build();

ARecord.Builder.create(this, "CidrRoutingConfig")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.4"))
        .setIdentifier("test")
        .cidrRoutingConfig(CidrRoutingConfig.create(CidrRoutingConfigProps.builder()
                .collectionId(cidrCollection.getAttrId())
                .locationName("test_location")
                .build()))
        .build();
csharp
HostedZone myZone;


var cidrCollection = new CfnCidrCollection(this, "CidrCollection", new CfnCidrCollectionProps {
    Name = "test-collection",
    Locations = new [] { new LocationProperty {
        CidrList = new [] { "192.168.1.0/24" },
        LocationName = "my_location"
    } }
});

new ARecord(this, "CidrRoutingConfig", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.4"),
    SetIdentifier = "test",
    CidrRoutingConfig = CidrRoutingConfig.Create(new CidrRoutingConfigProps {
        CollectionId = cidrCollection.AttrId,
        LocationName = "test_location"
    })
});
go
var myZone HostedZone


cidrCollection := route53.NewCfnCidrCollection(this, jsii.String("CidrCollection"), &CfnCidrCollectionProps{
	Name: jsii.String("test-collection"),
	Locations: []interface{}{
		&LocationProperty{
			CidrList: []*string{
				jsii.String("192.168.1.0/24"),
			},
			LocationName: jsii.String("my_location"),
		},
	},
})

route53.NewARecord(this, jsii.String("CidrRoutingConfig"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.4")),
	SetIdentifier: jsii.String("test"),
	CidrRoutingConfig: route53.CidrRoutingConfig_Create(&CidrRoutingConfigProps{
		CollectionId: cidrCollection.attrId,
		LocationName: jsii.String("test_location"),
	}),
})

To use the default CIDR record, call the route53.CidrRoutingConfig.default. This sets the locationName to *. The collectionId is still required.

ts
declare const myZone: route53.HostedZone;

const cidrCollection = new route53.CfnCidrCollection(this, 'CidrCollection', {
  name: 'test-collection',
  locations: [{
    cidrList: ['192.168.1.0/24'],
    locationName: 'my_location',
  }]
});

new route53.ARecord(this, 'DefaultCidrRoutingConfig', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('5.6.7.8'),
  setIdentifier: 'default',
  cidrRoutingConfig: route53.CidrRoutingConfig.withDefaultLocationName(cidrCollection.attrId),
});
python
# my_zone: route53.HostedZone


cidr_collection = route53.CfnCidrCollection(self, "CidrCollection",
    name="test-collection",
    locations=[route53.CfnCidrCollection.LocationProperty(
        cidr_list=["192.168.1.0/24"],
        location_name="my_location"
    )]
)

route53.ARecord(self, "DefaultCidrRoutingConfig",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("5.6.7.8"),
    set_identifier="default",
    cidr_routing_config=route53.CidrRoutingConfig.with_default_location_name(cidr_collection.attr_id)
)
java
HostedZone myZone;


CfnCidrCollection cidrCollection = CfnCidrCollection.Builder.create(this, "CidrCollection")
        .name("test-collection")
        .locations(List.of(LocationProperty.builder()
                .cidrList(List.of("192.168.1.0/24"))
                .locationName("my_location")
                .build()))
        .build();

ARecord.Builder.create(this, "DefaultCidrRoutingConfig")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("5.6.7.8"))
        .setIdentifier("default")
        .cidrRoutingConfig(CidrRoutingConfig.withDefaultLocationName(cidrCollection.getAttrId()))
        .build();
csharp
HostedZone myZone;


var cidrCollection = new CfnCidrCollection(this, "CidrCollection", new CfnCidrCollectionProps {
    Name = "test-collection",
    Locations = new [] { new LocationProperty {
        CidrList = new [] { "192.168.1.0/24" },
        LocationName = "my_location"
    } }
});

new ARecord(this, "DefaultCidrRoutingConfig", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("5.6.7.8"),
    SetIdentifier = "default",
    CidrRoutingConfig = CidrRoutingConfig.WithDefaultLocationName(cidrCollection.AttrId)
});
go
var myZone HostedZone


cidrCollection := route53.NewCfnCidrCollection(this, jsii.String("CidrCollection"), &CfnCidrCollectionProps{
	Name: jsii.String("test-collection"),
	Locations: []interface{}{
		&LocationProperty{
			CidrList: []*string{
				jsii.String("192.168.1.0/24"),
			},
			LocationName: jsii.String("my_location"),
		},
	},
})

route53.NewARecord(this, jsii.String("DefaultCidrRoutingConfig"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("5.6.7.8")),
	SetIdentifier: jsii.String("default"),
	CidrRoutingConfig: route53.CidrRoutingConfig_WithDefaultLocationName(cidrCollection.attrId),
})

To specify a unique identifier to differentiate among multiple resource record sets that have the same combination of name and type, use the setIdentifier parameter:

ts
declare const myZone: route53.HostedZone;

new route53.ARecord(this, 'ARecordWeighted1', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.4'),
  weight: 10,
  setIdentifier: 'weighted-record-id',
});
python
# my_zone: route53.HostedZone


route53.ARecord(self, "ARecordWeighted1",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.4"),
    weight=10,
    set_identifier="weighted-record-id"
)
java
HostedZone myZone;


ARecord.Builder.create(this, "ARecordWeighted1")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.4"))
        .weight(10)
        .setIdentifier("weighted-record-id")
        .build();
csharp
HostedZone myZone;


new ARecord(this, "ARecordWeighted1", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.4"),
    Weight = 10,
    SetIdentifier = "weighted-record-id"
});
go
var myZone HostedZone


route53.NewARecord(this, jsii.String("ARecordWeighted1"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.4")),
	Weight: jsii.Number(10),
	SetIdentifier: jsii.String("weighted-record-id"),
})

Warning It is not possible to specify setIdentifier for a simple routing policy.

Constructs are available for A, AAAA, CAA, CNAME, MX, NS, SRV and TXT records.

Use the CaaAmazonRecord construct to easily restrict certificate authorities allowed to issue certificates for a domain to Amazon only.

Health Checks ​

See the Route 53 Health Checks documentation for possible types of health checks.

Route 53 has the ability to monitor the health of your application and only return records for healthy endpoints. This is done using a HealthCheck construct.

In the following example, the ARecord will be returned by Route 53 in response to DNS queries only if the HTTP requests to the example.com/health endpoint return a 2XX or 3XX status code.

In case, when the endpoint is not healthy, the ARecord2 will be returned by Route 53 in response to DNS queries.

ts
declare const myZone: route53.HostedZone;

const healthCheck = new route53.HealthCheck(this, 'HealthCheck', {
  type: route53.HealthCheckType.HTTP,
  fqdn: 'example.com',
  port: 80,
  resourcePath: '/health',
  failureThreshold: 3,
  requestInterval: Duration.seconds(30),
});

new route53.ARecord(this, 'ARecord', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.4'),
  healthCheck,
  weight: 100,
});
new route53.ARecord(this, 'ARecord2', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('5.6.7.8'),
  weight: 0,
});
python
# my_zone: route53.HostedZone


health_check = route53.HealthCheck(self, "HealthCheck",
    type=route53.HealthCheckType.HTTP,
    fqdn="example.com",
    port=80,
    resource_path="/health",
    failure_threshold=3,
    request_interval=Duration.seconds(30)
)

route53.ARecord(self, "ARecord",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.4"),
    health_check=health_check,
    weight=100
)
route53.ARecord(self, "ARecord2",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("5.6.7.8"),
    weight=0
)
java
HostedZone myZone;


HealthCheck healthCheck = HealthCheck.Builder.create(this, "HealthCheck")
        .type(HealthCheckType.HTTP)
        .fqdn("example.com")
        .port(80)
        .resourcePath("/health")
        .failureThreshold(3)
        .requestInterval(Duration.seconds(30))
        .build();

ARecord.Builder.create(this, "ARecord")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.4"))
        .healthCheck(healthCheck)
        .weight(100)
        .build();
ARecord.Builder.create(this, "ARecord2")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("5.6.7.8"))
        .weight(0)
        .build();
csharp
HostedZone myZone;


var healthCheck = new HealthCheck(this, "HealthCheck", new HealthCheckProps {
    Type = HealthCheckType.HTTP,
    Fqdn = "example.com",
    Port = 80,
    ResourcePath = "/health",
    FailureThreshold = 3,
    RequestInterval = Duration.Seconds(30)
});

new ARecord(this, "ARecord", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.4"),
    HealthCheck = healthCheck,
    Weight = 100
});
new ARecord(this, "ARecord2", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("5.6.7.8"),
    Weight = 0
});
go
var myZone HostedZone


healthCheck := route53.NewHealthCheck(this, jsii.String("HealthCheck"), &HealthCheckProps{
	Type: route53.HealthCheckType_HTTP,
	Fqdn: jsii.String("example.com"),
	Port: jsii.Number(80),
	ResourcePath: jsii.String("/health"),
	FailureThreshold: jsii.Number(3),
	RequestInterval: awscdk.Duration_Seconds(jsii.Number(30)),
})

route53.NewARecord(this, jsii.String("ARecord"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.4")),
	HealthCheck: HealthCheck,
	Weight: jsii.Number(100),
})
route53.NewARecord(this, jsii.String("ARecord2"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_*FromIpAddresses(jsii.String("5.6.7.8")),
	Weight: jsii.Number(0),
})

Replacing existing record sets (dangerous!) ​

Use the deleteExisting prop to delete an existing record set before deploying the new one. This is useful if you want to minimize downtime and avoid "manual" actions while deploying a stack with a record set that already exists. This is typically the case for record sets that are not already "owned" by CloudFormation or "owned" by another stack or construct that is going to be deleted (migration).

N.B.: this feature is dangerous, use with caution! It can only be used safely when deleteExisting is set to true as soon as the resource is added to the stack. Changing an existing Record Set's deleteExisting property from false -> true after deployment will delete the record!

ts
declare const myZone: route53.HostedZone;

new route53.ARecord(this, 'ARecord', {
  zone: myZone,
  target: route53.RecordTarget.fromIpAddresses('1.2.3.4', '5.6.7.8'),
  deleteExisting: true,
});
python
# my_zone: route53.HostedZone


route53.ARecord(self, "ARecord",
    zone=my_zone,
    target=route53.RecordTarget.from_ip_addresses("1.2.3.4", "5.6.7.8"),
    delete_existing=True
)
java
HostedZone myZone;


ARecord.Builder.create(this, "ARecord")
        .zone(myZone)
        .target(RecordTarget.fromIpAddresses("1.2.3.4", "5.6.7.8"))
        .deleteExisting(true)
        .build();
csharp
HostedZone myZone;


new ARecord(this, "ARecord", new ARecordProps {
    Zone = myZone,
    Target = RecordTarget.FromIpAddresses("1.2.3.4", "5.6.7.8"),
    DeleteExisting = true
});
go
var myZone HostedZone


route53.NewARecord(this, jsii.String("ARecord"), &ARecordProps{
	Zone: myZone,
	Target: route53.RecordTarget_FromIpAddresses(jsii.String("1.2.3.4"), jsii.String("5.6.7.8")),
	DeleteExisting: jsii.Boolean(true),
})

Cross Account Zone Delegation ​

If you want to have your root domain hosted zone in one account and your subdomain hosted zone in a different one, you can use CrossAccountZoneDelegationRecord to set up delegation between them.

In the account containing the parent hosted zone:

ts
const parentZone = new route53.PublicHostedZone(this, 'HostedZone', {
  zoneName: 'someexample.com',
});
const crossAccountRole = new iam.Role(this, 'CrossAccountRole', {
  // The role name must be predictable
  roleName: 'MyDelegationRole',
  // The other account
  assumedBy: new iam.AccountPrincipal('12345678901'),
});
parentZone.grantDelegation(crossAccountRole);
python
parent_zone = route53.PublicHostedZone(self, "HostedZone",
    zone_name="someexample.com"
)
cross_account_role = iam.Role(self, "CrossAccountRole",
    # The role name must be predictable
    role_name="MyDelegationRole",
    # The other account
    assumed_by=iam.AccountPrincipal("12345678901")
)
parent_zone.grant_delegation(cross_account_role)
java
PublicHostedZone parentZone = PublicHostedZone.Builder.create(this, "HostedZone")
        .zoneName("someexample.com")
        .build();
Role crossAccountRole = Role.Builder.create(this, "CrossAccountRole")
        // The role name must be predictable
        .roleName("MyDelegationRole")
        // The other account
        .assumedBy(new AccountPrincipal("12345678901"))
        .build();
parentZone.grantDelegation(crossAccountRole);
csharp
var parentZone = new PublicHostedZone(this, "HostedZone", new PublicHostedZoneProps {
    ZoneName = "someexample.com"
});
var crossAccountRole = new Role(this, "CrossAccountRole", new RoleProps {
    // The role name must be predictable
    RoleName = "MyDelegationRole",
    // The other account
    AssumedBy = new AccountPrincipal("12345678901")
});
parentZone.GrantDelegation(crossAccountRole);
go
parentZone := route53.NewPublicHostedZone(this, jsii.String("HostedZone"), &PublicHostedZoneProps{
	ZoneName: jsii.String("someexample.com"),
})
crossAccountRole := iam.NewRole(this, jsii.String("CrossAccountRole"), &RoleProps{
	// The role name must be predictable
	RoleName: jsii.String("MyDelegationRole"),
	// The other account
	AssumedBy: iam.NewAccountPrincipal(jsii.String("12345678901")),
})
parentZone.GrantDelegation(crossAccountRole)

To restrict the records that can be created with the delegation IAM role, use the optional delegatedZoneNames property in the delegation options, which enforces the route53:ChangeResourceRecordSetsNormalizedRecordNames condition key for record names that match those hosted zone names. The delegatedZoneNames list may only consist of hosted zones names that are subzones of the parent hosted zone.

If the delegated zone name contains an unresolved token, it must resolve to a zone name that satisfies the requirements according to the documentation: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/specifying-conditions-route53.html#route53_rrset_conditionkeys_normalization

All letters must be lowercase. The DNS name must be without the trailing dot. Characters other than a–z, 0–9, - (hyphen), _ (underscore), and . (period, as a delimiter between labels) must use escape codes in the format \three-digit octal code. For example, \052 is the octal code for character *.

This feature allows you to better follow the minimum permissions privilege principle:

ts
const parentZone = new route53.PublicHostedZone(this, 'HostedZone', {
  zoneName: 'someexample.com',
});

declare const betaCrossAccountRole: iam.Role;
parentZone.grantDelegation(betaCrossAccountRole, {
    delegatedZoneNames: ['beta.someexample.com'],
});

declare const prodCrossAccountRole: iam.Role;
parentZone.grantDelegation(prodCrossAccountRole, {
    delegatedZoneNames: ['prod.someexample.com'],
});
python
# beta_cross_account_role: iam.Role

# prod_cross_account_role: iam.Role
parent_zone = route53.PublicHostedZone(self, "HostedZone",
    zone_name="someexample.com"
)
parent_zone.grant_delegation(beta_cross_account_role,
    delegated_zone_names=["beta.someexample.com"]
)
parent_zone.grant_delegation(prod_cross_account_role,
    delegated_zone_names=["prod.someexample.com"]
)
java
Role betaCrossAccountRole;

Role prodCrossAccountRole;
PublicHostedZone parentZone = PublicHostedZone.Builder.create(this, "HostedZone")
        .zoneName("someexample.com")
        .build();
parentZone.grantDelegation(betaCrossAccountRole, GrantDelegationOptions.builder()
        .delegatedZoneNames(List.of("beta.someexample.com"))
        .build());
parentZone.grantDelegation(prodCrossAccountRole, GrantDelegationOptions.builder()
        .delegatedZoneNames(List.of("prod.someexample.com"))
        .build());
csharp
Role betaCrossAccountRole;

Role prodCrossAccountRole;
var parentZone = new PublicHostedZone(this, "HostedZone", new PublicHostedZoneProps {
    ZoneName = "someexample.com"
});
parentZone.GrantDelegation(betaCrossAccountRole, new GrantDelegationOptions {
    DelegatedZoneNames = new [] { "beta.someexample.com" }
});
parentZone.GrantDelegation(prodCrossAccountRole, new GrantDelegationOptions {
    DelegatedZoneNames = new [] { "prod.someexample.com" }
});
go
var betaCrossAccountRole Role

var prodCrossAccountRole Role
parentZone := route53.NewPublicHostedZone(this, jsii.String("HostedZone"), &PublicHostedZoneProps{
	ZoneName: jsii.String("someexample.com"),
})
parentZone.GrantDelegation(betaCrossAccountRole, &GrantDelegationOptions{
	DelegatedZoneNames: []*string{
		jsii.String("beta.someexample.com"),
	},
})
parentZone.GrantDelegation(prodCrossAccountRole, &GrantDelegationOptions{
	DelegatedZoneNames: []*string{
		jsii.String("prod.someexample.com"),
	},
})

In the account containing the child zone to be delegated:

ts
const subZone = new route53.PublicHostedZone(this, 'SubZone', {
  zoneName: 'sub.someexample.com',
});

// import the delegation role by constructing the roleArn
const delegationRoleArn = Stack.of(this).formatArn({
  region: '', // IAM is global in each partition
  service: 'iam',
  account: 'parent-account-id',
  resource: 'role',
  resourceName: 'MyDelegationRole',
});
const delegationRole = iam.Role.fromRoleArn(this, 'DelegationRole', delegationRoleArn);

// create the record
new route53.CrossAccountZoneDelegationRecord(this, 'delegate', {
  delegatedZone: subZone,
  parentHostedZoneName: 'someexample.com', // or you can use parentHostedZoneId
  delegationRole,
});
python
sub_zone = route53.PublicHostedZone(self, "SubZone",
    zone_name="sub.someexample.com"
)

# import the delegation role by constructing the roleArn
delegation_role_arn = Stack.of(self).format_arn(
    region="",  # IAM is global in each partition
    service="iam",
    account="parent-account-id",
    resource="role",
    resource_name="MyDelegationRole"
)
delegation_role = iam.Role.from_role_arn(self, "DelegationRole", delegation_role_arn)

# create the record
route53.CrossAccountZoneDelegationRecord(self, "delegate",
    delegated_zone=sub_zone,
    parent_hosted_zone_name="someexample.com",  # or you can use parentHostedZoneId
    delegation_role=delegation_role
)
java
PublicHostedZone subZone = PublicHostedZone.Builder.create(this, "SubZone")
        .zoneName("sub.someexample.com")
        .build();

// import the delegation role by constructing the roleArn
String delegationRoleArn = Stack.of(this).formatArn(ArnComponents.builder()
        .region("") // IAM is global in each partition
        .service("iam")
        .account("parent-account-id")
        .resource("role")
        .resourceName("MyDelegationRole")
        .build());
IRole delegationRole = Role.fromRoleArn(this, "DelegationRole", delegationRoleArn);

// create the record
// create the record
CrossAccountZoneDelegationRecord.Builder.create(this, "delegate")
        .delegatedZone(subZone)
        .parentHostedZoneName("someexample.com") // or you can use parentHostedZoneId
        .delegationRole(delegationRole)
        .build();
csharp
var subZone = new PublicHostedZone(this, "SubZone", new PublicHostedZoneProps {
    ZoneName = "sub.someexample.com"
});

// import the delegation role by constructing the roleArn
var delegationRoleArn = Stack.Of(this).FormatArn(new ArnComponents {
    Region = "",  // IAM is global in each partition
    Service = "iam",
    Account = "parent-account-id",
    Resource = "role",
    ResourceName = "MyDelegationRole"
});
var delegationRole = Role.FromRoleArn(this, "DelegationRole", delegationRoleArn);

// create the record
// create the record
new CrossAccountZoneDelegationRecord(this, "delegate", new CrossAccountZoneDelegationRecordProps {
    DelegatedZone = subZone,
    ParentHostedZoneName = "someexample.com",  // or you can use parentHostedZoneId
    DelegationRole = delegationRole
});
go
subZone := route53.NewPublicHostedZone(this, jsii.String("SubZone"), &PublicHostedZoneProps{
	ZoneName: jsii.String("sub.someexample.com"),
})

// import the delegation role by constructing the roleArn
delegationRoleArn := awscdk.stack_Of(this).FormatArn(&ArnComponents{
	Region: jsii.String(""),
	 // IAM is global in each partition
	Service: jsii.String("iam"),
	Account: jsii.String("parent-account-id"),
	Resource: jsii.String("role"),
	ResourceName: jsii.String("MyDelegationRole"),
})
delegationRole := iam.Role_FromRoleArn(this, jsii.String("DelegationRole"), delegationRoleArn)

// create the record
// create the record
route53.NewCrossAccountZoneDelegationRecord(this, jsii.String("delegate"), &CrossAccountZoneDelegationRecordProps{
	DelegatedZone: subZone,
	ParentHostedZoneName: jsii.String("someexample.com"),
	 // or you can use parentHostedZoneId
	DelegationRole: DelegationRole,
})

Delegating the hosted zone requires assuming a role in the parent hosted zone's account. In order for the assumed credentials to be valid, the resource must assume the role using an STS endpoint in a region where both the subdomain's account and the parent's account are opted-in. By default, this region is determined automatically, but if you need to change the region used for the AssumeRole call, specify assumeRoleRegion:

ts
const subZone = new route53.PublicHostedZone(this, 'SubZone', {
  zoneName: 'sub.someexample.com',
});

// import the delegation role by constructing the roleArn
const delegationRoleArn = Stack.of(this).formatArn({
  region: '', // IAM is global in each partition
  service: 'iam',
  account: 'parent-account-id',
  resource: 'role',
  resourceName: 'MyDelegationRole',
});
const delegationRole = iam.Role.fromRoleArn(this, 'DelegationRole', delegationRoleArn);

new route53.CrossAccountZoneDelegationRecord(this, 'delegate', {
  delegatedZone: subZone,
  parentHostedZoneName: 'someexample.com', // or you can use parentHostedZoneId
  delegationRole,
  assumeRoleRegion: "us-east-1",
});
python
sub_zone = route53.PublicHostedZone(self, "SubZone",
    zone_name="sub.someexample.com"
)

# import the delegation role by constructing the roleArn
delegation_role_arn = Stack.of(self).format_arn(
    region="",  # IAM is global in each partition
    service="iam",
    account="parent-account-id",
    resource="role",
    resource_name="MyDelegationRole"
)
delegation_role = iam.Role.from_role_arn(self, "DelegationRole", delegation_role_arn)

route53.CrossAccountZoneDelegationRecord(self, "delegate",
    delegated_zone=sub_zone,
    parent_hosted_zone_name="someexample.com",  # or you can use parentHostedZoneId
    delegation_role=delegation_role,
    assume_role_region="us-east-1"
)
java
PublicHostedZone subZone = PublicHostedZone.Builder.create(this, "SubZone")
        .zoneName("sub.someexample.com")
        .build();

// import the delegation role by constructing the roleArn
String delegationRoleArn = Stack.of(this).formatArn(ArnComponents.builder()
        .region("") // IAM is global in each partition
        .service("iam")
        .account("parent-account-id")
        .resource("role")
        .resourceName("MyDelegationRole")
        .build());
IRole delegationRole = Role.fromRoleArn(this, "DelegationRole", delegationRoleArn);

CrossAccountZoneDelegationRecord.Builder.create(this, "delegate")
        .delegatedZone(subZone)
        .parentHostedZoneName("someexample.com") // or you can use parentHostedZoneId
        .delegationRole(delegationRole)
        .assumeRoleRegion("us-east-1")
        .build();
csharp
var subZone = new PublicHostedZone(this, "SubZone", new PublicHostedZoneProps {
    ZoneName = "sub.someexample.com"
});

// import the delegation role by constructing the roleArn
var delegationRoleArn = Stack.Of(this).FormatArn(new ArnComponents {
    Region = "",  // IAM is global in each partition
    Service = "iam",
    Account = "parent-account-id",
    Resource = "role",
    ResourceName = "MyDelegationRole"
});
var delegationRole = Role.FromRoleArn(this, "DelegationRole", delegationRoleArn);

new CrossAccountZoneDelegationRecord(this, "delegate", new CrossAccountZoneDelegationRecordProps {
    DelegatedZone = subZone,
    ParentHostedZoneName = "someexample.com",  // or you can use parentHostedZoneId
    DelegationRole = delegationRole,
    AssumeRoleRegion = "us-east-1"
});
go
subZone := route53.NewPublicHostedZone(this, jsii.String("SubZone"), &PublicHostedZoneProps{
	ZoneName: jsii.String("sub.someexample.com"),
})

// import the delegation role by constructing the roleArn
delegationRoleArn := awscdk.stack_Of(this).FormatArn(&ArnComponents{
	Region: jsii.String(""),
	 // IAM is global in each partition
	Service: jsii.String("iam"),
	Account: jsii.String("parent-account-id"),
	Resource: jsii.String("role"),
	ResourceName: jsii.String("MyDelegationRole"),
})
delegationRole := iam.Role_FromRoleArn(this, jsii.String("DelegationRole"), delegationRoleArn)

route53.NewCrossAccountZoneDelegationRecord(this, jsii.String("delegate"), &CrossAccountZoneDelegationRecordProps{
	DelegatedZone: subZone,
	ParentHostedZoneName: jsii.String("someexample.com"),
	 // or you can use parentHostedZoneId
	DelegationRole: DelegationRole,
	AssumeRoleRegion: jsii.String("us-east-1"),
})

Add Trailing Dot to Domain Names ​

In order to continue managing existing domain names with trailing dots using CDK, you can set addTrailingDot: false to prevent the Construct from adding a dot at the end of the domain name.

ts
new route53.PublicHostedZone(this, 'HostedZone', {
  zoneName: 'fully.qualified.domain.com.',
  addTrailingDot: false,
});
python
route53.PublicHostedZone(self, "HostedZone",
    zone_name="fully.qualified.domain.com.",
    add_trailing_dot=False
)
java
PublicHostedZone.Builder.create(this, "HostedZone")
        .zoneName("fully.qualified.domain.com.")
        .addTrailingDot(false)
        .build();
csharp
new PublicHostedZone(this, "HostedZone", new PublicHostedZoneProps {
    ZoneName = "fully.qualified.domain.com.",
    AddTrailingDot = false
});
go
route53.NewPublicHostedZone(this, jsii.String("HostedZone"), &PublicHostedZoneProps{
	ZoneName: jsii.String("fully.qualified.domain.com."),
	AddTrailingDot: jsii.Boolean(false),
})

Enabling DNSSEC ​

DNSSEC can be enabled for Hosted Zones. For detailed information, see Configuring DNSSEC signing in Amazon Route 53.

Enabling DNSSEC requires an asymmetric KMS Customer-Managed Key using the ECC_NIST_P256 key spec. Additionally, that KMS key must be in us-east-1.

ts
const kmsKey = new kms.Key(this, 'KmsCMK', {
  keySpec: kms.KeySpec.ECC_NIST_P256,
  keyUsage: kms.KeyUsage.SIGN_VERIFY,
});
const hostedZone = new route53.HostedZone(this, 'HostedZone', {
  zoneName: 'example.com',
});
// Enable DNSSEC signing for the zone
hostedZone.enableDnssec({ kmsKey });
python
kms_key = kms.Key(self, "KmsCMK",
    key_spec=kms.KeySpec.ECC_NIST_P256,
    key_usage=kms.KeyUsage.SIGN_VERIFY
)
hosted_zone = route53.HostedZone(self, "HostedZone",
    zone_name="example.com"
)
# Enable DNSSEC signing for the zone
hosted_zone.enable_dnssec(kms_key=kms_key)
java
Key kmsKey = Key.Builder.create(this, "KmsCMK")
        .keySpec(KeySpec.ECC_NIST_P256)
        .keyUsage(KeyUsage.SIGN_VERIFY)
        .build();
HostedZone hostedZone = HostedZone.Builder.create(this, "HostedZone")
        .zoneName("example.com")
        .build();
// Enable DNSSEC signing for the zone
hostedZone.enableDnssec(ZoneSigningOptions.builder().kmsKey(kmsKey).build());
csharp
var kmsKey = new Key(this, "KmsCMK", new KeyProps {
    KeySpec = KeySpec.ECC_NIST_P256,
    KeyUsage = KeyUsage.SIGN_VERIFY
});
var hostedZone = new HostedZone(this, "HostedZone", new HostedZoneProps {
    ZoneName = "example.com"
});
// Enable DNSSEC signing for the zone
hostedZone.EnableDnssec(new ZoneSigningOptions { KmsKey = kmsKey });
go
kmsKey := kms.NewKey(this, jsii.String("KmsCMK"), &KeyProps{
	KeySpec: kms.KeySpec_ECC_NIST_P256,
	KeyUsage: kms.KeyUsage_SIGN_VERIFY,
})
hostedZone := route53.NewHostedZone(this, jsii.String("HostedZone"), &HostedZoneProps{
	ZoneName: jsii.String("example.com"),
})
// Enable DNSSEC signing for the zone
hostedZone.EnableDnssec(&ZoneSigningOptions{
	KmsKey: KmsKey,
})

The necessary permissions for Route 53 to use the key will automatically be added when using this configuration. If it is necessary to create a key signing key manually, that can be done using the KeySigningKey construct:

ts
declare const hostedZone: route53.HostedZone;
declare const kmsKey: kms.Key;
new route53.KeySigningKey(this, 'KeySigningKey', {
  hostedZone,
  kmsKey,
  keySigningKeyName: 'ksk',
  status: route53.KeySigningKeyStatus.ACTIVE,
});
python
# hosted_zone: route53.HostedZone
# kms_key: kms.Key

route53.KeySigningKey(self, "KeySigningKey",
    hosted_zone=hosted_zone,
    kms_key=kms_key,
    key_signing_key_name="ksk",
    status=route53.KeySigningKeyStatus.ACTIVE
)
java
HostedZone hostedZone;
Key kmsKey;

KeySigningKey.Builder.create(this, "KeySigningKey")
        .hostedZone(hostedZone)
        .kmsKey(kmsKey)
        .keySigningKeyName("ksk")
        .status(KeySigningKeyStatus.ACTIVE)
        .build();
csharp
HostedZone hostedZone;
Key kmsKey;

new KeySigningKey(this, "KeySigningKey", new KeySigningKeyProps {
    HostedZone = hostedZone,
    KmsKey = kmsKey,
    KeySigningKeyName = "ksk",
    Status = KeySigningKeyStatus.ACTIVE
});
go
var hostedZone HostedZone
var kmsKey Key

route53.NewKeySigningKey(this, jsii.String("KeySigningKey"), &KeySigningKeyProps{
	HostedZone: HostedZone,
	KmsKey: KmsKey,
	KeySigningKeyName: jsii.String("ksk"),
	Status: route53.KeySigningKeyStatus_ACTIVE,
})

When directly constructing the KeySigningKey resource, enabling DNSSEC signing for the hosted zone will be need to be done explicitly (either using the CfnDNSSEC construct or via another means).

Accelerated Recovery ​

Route 53 accelerated recovery for managing public DNS records is designed to achieve a 60-minute Recovery Time Objective (RTO) in the event of service unavailability in the US East (N. Virginia) Region. When enabled on a Route 53 public hosted zone, you will be able to resume making changes to DNS records in the public hosted zone within approximately 60 minutes after AWS detects that operations in the US East (N. Virginia) Region are impaired.

This feature is only available for public hosted zones.

ts
new route53.PublicHostedZone(this, 'HostedZone', {
  zoneName: 'example.com',
  acceleratedRecoveryEnabled: true,
});
python
route53.PublicHostedZone(self, "HostedZone",
    zone_name="example.com",
    accelerated_recovery_enabled=True
)
java
PublicHostedZone.Builder.create(this, "HostedZone")
        .zoneName("example.com")
        .acceleratedRecoveryEnabled(true)
        .build();
csharp
new PublicHostedZone(this, "HostedZone", new PublicHostedZoneProps {
    ZoneName = "example.com",
    AcceleratedRecoveryEnabled = true
});
go
route53.NewPublicHostedZone(this, jsii.String("HostedZone"), &PublicHostedZoneProps{
	ZoneName: jsii.String("example.com"),
	AcceleratedRecoveryEnabled: jsii.Boolean(true),
})

For more information, see Enabling accelerated recovery for managing public DNS records.

Imports ​

If you don't know the ID of the Hosted Zone to import, you can use the HostedZone.fromLookup:

ts
route53.HostedZone.fromLookup(this, 'MyZone', {
  domainName: 'example.com',
});
python
route53.HostedZone.from_lookup(self, "MyZone",
    domain_name="example.com"
)
java
HostedZone.fromLookup(this, "MyZone", HostedZoneProviderProps.builder()
        .domainName("example.com")
        .build());
csharp
HostedZone.FromLookup(this, "MyZone", new HostedZoneProviderProps {
    DomainName = "example.com"
});
go
route53.HostedZone_FromLookup(this, jsii.String("MyZone"), &HostedZoneProviderProps{
	DomainName: jsii.String("example.com"),
})

HostedZone.fromLookup requires an environment to be configured. Check out the documentation for more documentation and examples. CDK automatically looks into your ~/.aws/config file for the [default] profile. If you want to specify a different account run cdk deploy --profile [profile].

text
new MyDevStack(app, 'dev', {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION,
  },
});

If you know the ID and Name of a Hosted Zone, you can import it directly:

ts
const zone = route53.HostedZone.fromHostedZoneAttributes(this, 'MyZone', {
  zoneName: 'example.com',
  hostedZoneId: 'ZOJJZC49E0EPZ',
});
python
zone = route53.HostedZone.from_hosted_zone_attributes(self, "MyZone",
    zone_name="example.com",
    hosted_zone_id="ZOJJZC49E0EPZ"
)
java
IHostedZone zone = HostedZone.fromHostedZoneAttributes(this, "MyZone", HostedZoneAttributes.builder()
        .zoneName("example.com")
        .hostedZoneId("ZOJJZC49E0EPZ")
        .build());
csharp
var zone = HostedZone.FromHostedZoneAttributes(this, "MyZone", new HostedZoneAttributes {
    ZoneName = "example.com",
    HostedZoneId = "ZOJJZC49E0EPZ"
});
go
zone := route53.HostedZone_FromHostedZoneAttributes(this, jsii.String("MyZone"), &HostedZoneAttributes{
	ZoneName: jsii.String("example.com"),
	HostedZoneId: jsii.String("ZOJJZC49E0EPZ"),
})

Alternatively, use the HostedZone.fromHostedZoneId to import hosted zones if you know the ID and the retrieval for the zoneName is undesirable. Note that any records created with a hosted zone obtained this way must have their name be fully qualified

ts
const zone = route53.HostedZone.fromHostedZoneId(this, 'MyZone', 'ZOJJZC49E0EPZ');
python
zone = route53.HostedZone.from_hosted_zone_id(self, "MyZone", "ZOJJZC49E0EPZ")
java
IHostedZone zone = HostedZone.fromHostedZoneId(this, "MyZone", "ZOJJZC49E0EPZ");
csharp
var zone = HostedZone.FromHostedZoneId(this, "MyZone", "ZOJJZC49E0EPZ");
go
zone := route53.HostedZone_FromHostedZoneId(this, jsii.String("MyZone"), jsii.String("ZOJJZC49E0EPZ"))

You can import a Public Hosted Zone as well with the similar PublicHostedZone.fromPublicHostedZoneId and PublicHostedZone.fromPublicHostedZoneAttributes methods:

ts
const zoneFromAttributes = route53.PublicHostedZone.fromPublicHostedZoneAttributes(this, 'MyZone', {
  zoneName: 'example.com',
  hostedZoneId: 'ZOJJZC49E0EPZ',
});

// Does not know zoneName
const zoneFromId = route53.PublicHostedZone.fromPublicHostedZoneId(this, 'MyZone', 'ZOJJZC49E0EPZ');
python
zone_from_attributes = route53.PublicHostedZone.from_public_hosted_zone_attributes(self, "MyZone",
    zone_name="example.com",
    hosted_zone_id="ZOJJZC49E0EPZ"
)

# Does not know zoneName
zone_from_id = route53.PublicHostedZone.from_public_hosted_zone_id(self, "MyZone", "ZOJJZC49E0EPZ")
java
IPublicHostedZone zoneFromAttributes = PublicHostedZone.fromPublicHostedZoneAttributes(this, "MyZone", PublicHostedZoneAttributes.builder()
        .zoneName("example.com")
        .hostedZoneId("ZOJJZC49E0EPZ")
        .build());

// Does not know zoneName
IPublicHostedZone zoneFromId = PublicHostedZone.fromPublicHostedZoneId(this, "MyZone", "ZOJJZC49E0EPZ");
csharp
var zoneFromAttributes = PublicHostedZone.FromPublicHostedZoneAttributes(this, "MyZone", new PublicHostedZoneAttributes {
    ZoneName = "example.com",
    HostedZoneId = "ZOJJZC49E0EPZ"
});

// Does not know zoneName
var zoneFromId = PublicHostedZone.FromPublicHostedZoneId(this, "MyZone", "ZOJJZC49E0EPZ");
go
zoneFromAttributes := route53.PublicHostedZone_FromPublicHostedZoneAttributes(this, jsii.String("MyZone"), &PublicHostedZoneAttributes{
	ZoneName: jsii.String("example.com"),
	HostedZoneId: jsii.String("ZOJJZC49E0EPZ"),
})

// Does not know zoneName
zoneFromId := route53.PublicHostedZone_FromPublicHostedZoneId(this, jsii.String("MyZone"), jsii.String("ZOJJZC49E0EPZ"))

You can import a Private Hosted Zone with PrivateHostedZone.fromPrivateHostedZoneId and PrivateHostedZone.fromPrivateHostedZoneAttributes methods:

ts
const privateZoneFromAttributes = route53.PrivateHostedZone.fromPrivateHostedZoneAttributes(this, 'MyPrivateZone', {
  zoneName: 'example.local',
  hostedZoneId: 'ZOJJZC49E0EPZ',
});

// Does not know zoneName
const privateZoneFromId = route53.PrivateHostedZone.fromPrivateHostedZoneId(this, 'MyPrivateZone', 'ZOJJZC49E0EPZ');
python
private_zone_from_attributes = route53.PrivateHostedZone.from_private_hosted_zone_attributes(self, "MyPrivateZone",
    zone_name="example.local",
    hosted_zone_id="ZOJJZC49E0EPZ"
)

# Does not know zoneName
private_zone_from_id = route53.PrivateHostedZone.from_private_hosted_zone_id(self, "MyPrivateZone", "ZOJJZC49E0EPZ")
java
IPrivateHostedZone privateZoneFromAttributes = PrivateHostedZone.fromPrivateHostedZoneAttributes(this, "MyPrivateZone", PrivateHostedZoneAttributes.builder()
        .zoneName("example.local")
        .hostedZoneId("ZOJJZC49E0EPZ")
        .build());

// Does not know zoneName
IPrivateHostedZone privateZoneFromId = PrivateHostedZone.fromPrivateHostedZoneId(this, "MyPrivateZone", "ZOJJZC49E0EPZ");
csharp
var privateZoneFromAttributes = PrivateHostedZone.FromPrivateHostedZoneAttributes(this, "MyPrivateZone", new PrivateHostedZoneAttributes {
    ZoneName = "example.local",
    HostedZoneId = "ZOJJZC49E0EPZ"
});

// Does not know zoneName
var privateZoneFromId = PrivateHostedZone.FromPrivateHostedZoneId(this, "MyPrivateZone", "ZOJJZC49E0EPZ");
go
privateZoneFromAttributes := route53.PrivateHostedZone_FromPrivateHostedZoneAttributes(this, jsii.String("MyPrivateZone"), &PrivateHostedZoneAttributes{
	ZoneName: jsii.String("example.local"),
	HostedZoneId: jsii.String("ZOJJZC49E0EPZ"),
})

// Does not know zoneName
privateZoneFromId := route53.PrivateHostedZone_FromPrivateHostedZoneId(this, jsii.String("MyPrivateZone"), jsii.String("ZOJJZC49E0EPZ"))

You can use CrossAccountZoneDelegationRecord on imported Hosted Zones with the grantDelegation method:

ts
const crossAccountRole = new iam.Role(this, 'CrossAccountRole', {
  // The role name must be predictable
  roleName: 'MyDelegationRole',
  // The other account
  assumedBy: new iam.AccountPrincipal('12345678901'),
});

const zoneFromId = route53.HostedZone.fromHostedZoneId(this, 'MyZone', 'zone-id');
zoneFromId.grantDelegation(crossAccountRole);

const publicZoneFromId = route53.PublicHostedZone.fromPublicHostedZoneId(this, 'MyPublicZone', 'public-zone-id');
publicZoneFromId.grantDelegation(crossAccountRole);

const privateZoneFromId = route53.PrivateHostedZone.fromPrivateHostedZoneId(this, 'MyPrivateZone', 'private-zone-id');
privateZoneFromId.grantDelegation(crossAccountRole);
python
cross_account_role = iam.Role(self, "CrossAccountRole",
    # The role name must be predictable
    role_name="MyDelegationRole",
    # The other account
    assumed_by=iam.AccountPrincipal("12345678901")
)

zone_from_id = route53.HostedZone.from_hosted_zone_id(self, "MyZone", "zone-id")
zone_from_id.grant_delegation(cross_account_role)

public_zone_from_id = route53.PublicHostedZone.from_public_hosted_zone_id(self, "MyPublicZone", "public-zone-id")
public_zone_from_id.grant_delegation(cross_account_role)

private_zone_from_id = route53.PrivateHostedZone.from_private_hosted_zone_id(self, "MyPrivateZone", "private-zone-id")
private_zone_from_id.grant_delegation(cross_account_role)
java
Role crossAccountRole = Role.Builder.create(this, "CrossAccountRole")
        // The role name must be predictable
        .roleName("MyDelegationRole")
        // The other account
        .assumedBy(new AccountPrincipal("12345678901"))
        .build();

IHostedZone zoneFromId = HostedZone.fromHostedZoneId(this, "MyZone", "zone-id");
zoneFromId.grantDelegation(crossAccountRole);

IPublicHostedZone publicZoneFromId = PublicHostedZone.fromPublicHostedZoneId(this, "MyPublicZone", "public-zone-id");
publicZoneFromId.grantDelegation(crossAccountRole);

IPrivateHostedZone privateZoneFromId = PrivateHostedZone.fromPrivateHostedZoneId(this, "MyPrivateZone", "private-zone-id");
privateZoneFromId.grantDelegation(crossAccountRole);
csharp
var crossAccountRole = new Role(this, "CrossAccountRole", new RoleProps {
    // The role name must be predictable
    RoleName = "MyDelegationRole",
    // The other account
    AssumedBy = new AccountPrincipal("12345678901")
});

var zoneFromId = HostedZone.FromHostedZoneId(this, "MyZone", "zone-id");
zoneFromId.GrantDelegation(crossAccountRole);

var publicZoneFromId = PublicHostedZone.FromPublicHostedZoneId(this, "MyPublicZone", "public-zone-id");
publicZoneFromId.GrantDelegation(crossAccountRole);

var privateZoneFromId = PrivateHostedZone.FromPrivateHostedZoneId(this, "MyPrivateZone", "private-zone-id");
privateZoneFromId.GrantDelegation(crossAccountRole);
go
crossAccountRole := iam.NewRole(this, jsii.String("CrossAccountRole"), &RoleProps{
	// The role name must be predictable
	RoleName: jsii.String("MyDelegationRole"),
	// The other account
	AssumedBy: iam.NewAccountPrincipal(jsii.String("12345678901")),
})

zoneFromId := route53.HostedZone_FromHostedZoneId(this, jsii.String("MyZone"), jsii.String("zone-id"))
zoneFromId.GrantDelegation(crossAccountRole)

publicZoneFromId := route53.PublicHostedZone_FromPublicHostedZoneId(this, jsii.String("MyPublicZone"), jsii.String("public-zone-id"))
publicZoneFromId.GrantDelegation(crossAccountRole)

privateZoneFromId := route53.PrivateHostedZone_FromPrivateHostedZoneId(this, jsii.String("MyPrivateZone"), jsii.String("private-zone-id"))
privateZoneFromId.GrantDelegation(crossAccountRole)

VPC Endpoint Service Private DNS ​

When you create a VPC endpoint service, AWS generates endpoint-specific DNS hostnames that consumers use to communicate with the service. For example, vpce-1234-abcdev-us-east-1.vpce-svc-123345.us-east-1.vpce.amazonaws.com. By default, your consumers access the service with that DNS name. This can cause problems with HTTPS traffic because the DNS will not match the backend certificate:

console
curl: (60) SSL: no alternative certificate subject name matches target host name 'vpce-abcdefghijklmnopq-rstuvwx.vpce-svc-abcdefghijklmnopq.us-east-1.vpce.amazonaws.com'

Effectively, the endpoint appears untrustworthy. To mitigate this, clients have to create an alias for this DNS name in Route53.

Private DNS for an endpoint service lets you configure a private DNS name so consumers can access the service using an existing DNS name without creating this Route53 DNS alias This DNS name can also be guaranteed to match up with the backend certificate.

Before consumers can use the private DNS name, you must verify that you have control of the domain/subdomain.

Assuming your account has ownership of the particular domain/subdomain, this construct sets up the private DNS configuration on the endpoint service, creates all the necessary Route53 entries, and verifies domain ownership.

ts
import { NetworkLoadBalancer } from 'aws-cdk-lib/aws-elasticloadbalancingv2';

const vpc = new ec2.Vpc(this, 'VPC');
const nlb = new NetworkLoadBalancer(this, 'NLB', {
  vpc,
});
const vpces = new ec2.VpcEndpointService(this, 'VPCES', {
  vpcEndpointServiceLoadBalancers: [nlb],
});
// You must use a public hosted zone so domain ownership can be verified
const zone = new route53.PublicHostedZone(this, 'PHZ', {
  zoneName: 'aws-cdk.dev',
});
new route53.VpcEndpointServiceDomainName(this, 'EndpointDomain', {
  endpointService: vpces,
  domainName: 'my-stuff.aws-cdk.dev',
  publicHostedZone: zone,
});
python
from aws_cdk.aws_elasticloadbalancingv2 import NetworkLoadBalancer


vpc = ec2.Vpc(self, "VPC")
nlb = NetworkLoadBalancer(self, "NLB",
    vpc=vpc
)
vpces = ec2.VpcEndpointService(self, "VPCES",
    vpc_endpoint_service_load_balancers=[nlb]
)
# You must use a public hosted zone so domain ownership can be verified
zone = route53.PublicHostedZone(self, "PHZ",
    zone_name="aws-cdk.dev"
)
route53.VpcEndpointServiceDomainName(self, "EndpointDomain",
    endpoint_service=vpces,
    domain_name="my-stuff.aws-cdk.dev",
    public_hosted_zone=zone
)
java
import software.amazon.awscdk.services.elasticloadbalancingv2.NetworkLoadBalancer;


Vpc vpc = new Vpc(this, "VPC");
NetworkLoadBalancer nlb = NetworkLoadBalancer.Builder.create(this, "NLB")
        .vpc(vpc)
        .build();
VpcEndpointService vpces = VpcEndpointService.Builder.create(this, "VPCES")
        .vpcEndpointServiceLoadBalancers(List.of(nlb))
        .build();
// You must use a public hosted zone so domain ownership can be verified
PublicHostedZone zone = PublicHostedZone.Builder.create(this, "PHZ")
        .zoneName("aws-cdk.dev")
        .build();
VpcEndpointServiceDomainName.Builder.create(this, "EndpointDomain")
        .endpointService(vpces)
        .domainName("my-stuff.aws-cdk.dev")
        .publicHostedZone(zone)
        .build();
csharp
using Amazon.CDK.AWS.ElasticLoadBalancingV2;


var vpc = new Vpc(this, "VPC");
var nlb = new NetworkLoadBalancer(this, "NLB", new NetworkLoadBalancerProps {
    Vpc = vpc
});
var vpces = new VpcEndpointService(this, "VPCES", new VpcEndpointServiceProps {
    VpcEndpointServiceLoadBalancers = new [] { nlb }
});
// You must use a public hosted zone so domain ownership can be verified
var zone = new PublicHostedZone(this, "PHZ", new PublicHostedZoneProps {
    ZoneName = "aws-cdk.dev"
});
new VpcEndpointServiceDomainName(this, "EndpointDomain", new VpcEndpointServiceDomainNameProps {
    EndpointService = vpces,
    DomainName = "my-stuff.aws-cdk.dev",
    PublicHostedZone = zone
});
go
import "github.com/aws/aws-cdk-go/awscdk"


vpc := ec2.NewVpc(this, jsii.String("VPC"))
nlb := awscdk.NewNetworkLoadBalancer(this, jsii.String("NLB"), &NetworkLoadBalancerProps{
	Vpc: Vpc,
})
vpces := ec2.NewVpcEndpointService(this, jsii.String("VPCES"), &VpcEndpointServiceProps{
	VpcEndpointServiceLoadBalancers: []IVpcEndpointServiceLoadBalancer{
		nlb,
	},
})
// You must use a public hosted zone so domain ownership can be verified
zone := route53.NewPublicHostedZone(this, jsii.String("PHZ"), &PublicHostedZoneProps{
	ZoneName: jsii.String("aws-cdk.dev"),
})
route53.NewVpcEndpointServiceDomainName(this, jsii.String("EndpointDomain"), &VpcEndpointServiceDomainNameProps{
	EndpointService: vpces,
	DomainName: jsii.String("my-stuff.aws-cdk.dev"),
	PublicHostedZone: zone,
})

Types ​

NameKindSummary
AaaaRecordConstruct (L2)A DNS AAAA record.
ARecordConstruct (L2)A DNS A record.
CaaAmazonRecordConstruct (L2)A DNS Amazon CAA record.
CaaRecordConstruct (L2)A DNS CAA record.
CnameRecordConstruct (L2)A DNS CNAME record.
DsRecordConstruct (L2)A DNS DS record.
HealthCheckConstruct (L2)Amazon Route 53 health checks monitor the health and performance of your web applications, web servers, and other resources.
HostedZoneConstruct (L2)Container for records, and records contain information about how to route traffic for a specific domain, such as example.com and its subdomains (acme.example.com, zenith.example.com).
HttpsRecordConstruct (L2)A DNS HTTPS record.
KeySigningKeyConstruct (L2)A Key Signing Key for a Route 53 Hosted Zone.
MxRecordConstruct (L2)A DNS MX record.
NsRecordConstruct (L2)A DNS NS record.
PrivateHostedZoneConstruct (L2)Create a Route53 private hosted zone for use in one or more VPCs.
PublicHostedZoneConstruct (L2)Create a Route53 public hosted zone.
RecordSetConstruct (L2)A record set.
SrvRecordConstruct (L2)A DNS SRV record.
SvcbRecordConstruct (L2)A DNS SVCB record.
TxtRecordConstruct (L2)A DNS TXT record.
ZoneDelegationRecordConstruct (L2)A record to delegate further lookups to a different set of name servers.
CfnCidrCollectionConstruct (L1)Creates a CIDR collection in the current AWS account.
CfnDelegationSetConstruct (L1)Resource Type definition for AWS::Route53::DelegationSet.
CfnDNSSECConstruct (L1)The AWS::Route53::DNSSEC resource is used to enable DNSSEC signing in a hosted zone.
CfnHealthCheckConstruct (L1)The AWS::Route53::HealthCheck resource is a Route 53 resource type that contains settings for a Route 53 health check.
CfnHostedZoneConstruct (L1)Creates a new public or private hosted zone.
CfnKeySigningKeyConstruct (L1)The AWS::Route53::KeySigningKey resource creates a new key-signing key (KSK) in a hosted zone.
CfnQueryLoggingConfigConstruct (L1)Resource Type definition for AWS::Route53::QueryLoggingConfig.
CfnRecordSetConstruct (L1)Information about the record that you want to create.
CfnRecordSetGroupConstruct (L1)A complex type that contains an optional comment, the name and ID of the hosted zone that you want to make changes in, and values for the records that you want to create.
CfnTrafficPolicyConstruct (L1)Resource Type definition for AWS::Route53::TrafficPolicy.
CfnTrafficPolicyInstanceConstruct (L1)Resource Type definition for AWS::Route53::TrafficPolicyInstance.
AaaaRecordPropsStructConstruction properties for a AaaaRecord.
AlarmIdentifierStructA CloudWatch alarm that you want Amazon Route 53 health checker to use to determine whether this health check is healthy.
AliasRecordTargetConfigStructRepresents the properties of an alias target destination.
AlpnClassThe ALPN protocol identifier.
ARecordAttrsStructConstruction properties to import existing ARecord as target.
ARecordPropsStructConstruction properties for a ARecord.
CaaAmazonRecordPropsStructConstruction properties for a CaaAmazonRecord.
CaaRecordPropsStructConstruction properties for a CaaRecord.
CaaRecordValueStructProperties for a CAA record value.
CaaTagEnumThe CAA tag.
CfnCidrCollection.LocationPropertyStructSpecifies the list of CIDR blocks for a CIDR location.
CfnCidrCollectionPropsStructProperties for defining a CfnCidrCollection.
CfnDelegationSetPropsStructProperties for defining a CfnDelegationSet.
CfnDNSSECPropsStructProperties for defining a CfnDNSSEC.
CfnHealthCheck.AlarmIdentifierPropertyStructA complex type that identifies the CloudWatch alarm that you want Amazon Route 53 health checkers to use to determine whether the specified health check is healthy.
CfnHealthCheck.HealthCheckConfigPropertyStructA complex type that contains information about the health check.
CfnHealthCheck.HealthCheckTagPropertyStructThe HealthCheckTag property describes one key-value pair that is associated with an AWS::Route53::HealthCheck resource.
CfnHealthCheckPropsStructProperties for defining a CfnHealthCheck.
CfnHostedZone.HostedZoneConfigPropertyStructA complex type that contains an optional comment about your hosted zone.
CfnHostedZone.HostedZoneFeaturesPropertyStructRepresents the features configuration for a hosted zone, including the status of various features and any associated failure reasons.
CfnHostedZone.HostedZoneTagPropertyStructA complex type that contains information about a tag that you want to add or edit for the specified health check or hosted zone.
CfnHostedZone.QueryLoggingConfigPropertyStructA complex type that contains information about a configuration for DNS query logging.
CfnHostedZone.VPCPropertyStructPrivate hosted zones only: A complex type that contains information about an Amazon VPC.
CfnHostedZonePropsStructProperties for defining a CfnHostedZone.
CfnKeySigningKeyPropsStructProperties for defining a CfnKeySigningKey.
CfnQueryLoggingConfigPropsStructProperties for defining a CfnQueryLoggingConfig.
CfnRecordSet.AliasTargetPropertyStructAlias records only: Information about the AWS resource, such as a CloudFront distribution or an Amazon S3 bucket, that you want to route traffic to.
CfnRecordSet.CidrRoutingConfigPropertyStructThe object that is specified in resource record set object when you are linking a resource record set to a CIDR location.
CfnRecordSet.GeoLocationPropertyStructA complex type that contains information about a geographic location.
CfnRecordSetGroup.AliasTargetPropertyStructAlias records only: Information about the AWS resource, such as a CloudFront distribution or an Amazon S3 bucket, that you want to route traffic to.
CfnRecordSetGroup.CidrRoutingConfigPropertyStructThe object that is specified in resource record set object when you are linking a resource record set to a CIDR location.
CfnRecordSetGroup.CoordinatesPropertyStructA complex type that lists the coordinates for a geoproximity resource record.
CfnRecordSetGroup.GeoLocationPropertyStructA complex type that contains information about a geographic location.
CfnRecordSetGroup.GeoProximityLocationPropertyStruct(Resource record sets only): A complex type that lets you specify where your resources are located.
CfnRecordSetGroup.RecordSetPropertyStructInformation about one record that you want to create.
CfnRecordSetGroupPropsStructProperties for defining a CfnRecordSetGroup.
CfnRecordSetPropsStructProperties for defining a CfnRecordSet.
CfnTrafficPolicyInstancePropsStructProperties for defining a CfnTrafficPolicyInstance.
CfnTrafficPolicyPropsStructProperties for defining a CfnTrafficPolicy.
CidrRoutingConfigClassConfiguration for CIDR routing in Route 53 resource record set objects.
CidrRoutingConfigPropsStructProperties for configuring CIDR routing in Route 53 resource record set objects.
CnameRecordPropsStructConstruction properties for a CnameRecord.
CommonHostedZonePropsStructCommon properties to create a Route 53 hosted zone.
ContinentEnumContinents for geolocation routing.
CrossAccountZoneDelegationRecordConstructA Cross Account Zone Delegation record.
CrossAccountZoneDelegationRecordPropsStructConstruction properties for a CrossAccountZoneDelegationRecord.
DsRecordPropsStructConstruction properties for a DSRecord.
FailoverEnumThe failover policy.
GeoLocationClassRouting based on geographical location.
GrantDelegationOptionsStructOptions for the delegation permissions granted.
HealthCheckPropsStructProperties for a new health check.
HealthCheckTypeEnumThe type of health check to be associated with the record.
HostedZoneAttributesStructReference to a hosted zone.
HostedZoneGrantsFacadeCollection of grant methods for a INamedHostedZoneRef.
HostedZonePropsStructProperties of a new hosted zone.
HostedZoneProviderPropsStructZone properties for looking up the Hosted Zone.
HttpsRecordPropsStructConstruction properties for an HttpsRecord.
HttpsRecordServiceModePropsStructProperties of an HTTPS ServiceMode record.
HttpsRecordValueClassRepresents an HTTPS record value.
IAliasRecordTargetInterfaceClasses that are valid alias record targets, like CloudFront distributions and load balancers, should implement this interface.
IHealthCheckInterfaceImported or created health check.
IHostedZoneInterfaceImported or created hosted zone.
IKeySigningKeyInterfaceA Key Signing Key for a Route 53 Hosted Zone.
INamedHostedZoneRefInterface
InsufficientDataHealthStatusEnumEnumThe status of the health check when CloudWatch has insufficient data about the state of associated alarm.
IPrivateHostedZoneInterfaceRepresents a Route 53 private hosted zone.
IPublicHostedZoneInterfaceRepresents a Route 53 public hosted zone.
IRecordSetInterfaceA record set.
KeySigningKeyAttributesStructThe attributes of a key signing key.
KeySigningKeyPropsStructProperties for constructing a Key Signing Key.
KeySigningKeyStatusEnumThe status for a Key Signing Key.
MxRecordPropsStructConstruction properties for a MxRecord.
MxRecordValueStructProperties for a MX record value.
NsRecordPropsStructConstruction properties for a NSRecord.
PrivateHostedZoneAttributesStructReference to a private hosted zone.
PrivateHostedZonePropsStructProperties to create a Route 53 private hosted zone.
PublicHostedZoneAttributesStructReference to a public hosted zone.
PublicHostedZonePropsStructConstruction properties for a PublicHostedZone.
RecordSetOptionsStructOptions for a RecordSet.
RecordSetPropsStructConstruction properties for a RecordSet.
RecordTargetClassType union for a record that accepts multiple types of target.
RecordTypeEnumThe record type.
SrvRecordPropsStructConstruction properties for a SrvRecord.
SrvRecordValueStructProperties for a SRV record value.
SvcbRecordPropsStructConstruction properties for an SvcbRecord.
SvcbRecordServiceModePropsStructBase properties of an SVCB ServiceMode record value.
SvcbRecordValueClassRepresents an SVCB record value.
TxtRecordPropsStructConstruction properties for a TxtRecord.
VpcEndpointServiceDomainNameConstructA Private DNS configuration for a VPC endpoint service.
VpcEndpointServiceDomainNamePropsStructProperties to configure a VPC Endpoint Service domain name.
ZoneDelegationOptionsStructOptions available when creating a delegation relationship from one PublicHostedZone to another.
ZoneDelegationRecordPropsStructConstruction properties for a ZoneDelegationRecord.
ZoneSigningOptionsStructOptions for enabling key signing from a hosted zone.