Skip to main content

Route53 Record Set

The Route53RecordSet resource allows you to create and manage DNS records (resource record sets) in AWS Route53 using native Kubernetes resources.

Overview​

Route53 Record Sets define how traffic is routed to resources (servers, load balancers, etc.). It supports all standard DNS record types and advanced routing policies.

Use Cases:

  • Simple DNS records (A, AAAA, CNAME, TXT, MX)
  • Alias records for AWS resources (ELB, CloudFront, S3)
  • Weight-based, latency-based, or geolocation-based routing
  • Automatic failover with health checks
  • Declarative DNS management via GitOps

Supported Record Types​

  • A - IPv4 address
  • AAAA - IPv6 address
  • CNAME - Canonical name
  • MX - Mail exchange
  • TXT - Text record
  • PTR - Pointer record
  • SRV - Service locator
  • SPF - Sender Policy Framework
  • NS - Name server
  • SOA - Start of authority
  • CAA - Certification Authority Authorization
  • NAPTR - Name Authority Pointer

Basic Examples​

Simple A Record​

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: www-record
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: www.example.com
type: A
ttl: 300
resourceRecords:
- 192.0.2.1
- 192.0.2.2

CNAME Record​

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: blog-cname
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: blog.example.com
type: CNAME
ttl: 300
resourceRecords:
- www.example.com

Alias Record (Load Balancer)​

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: api-alias
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: api.example.com
type: A
aliasTarget:
hostedZoneID: Z215JYRZR1TBD5 # ELB hosted zone
dnsName: my-lb-123.us-east-1.elb.amazonaws.com
evaluateTargetHealth: true

Spec Fields​

FieldTypeRequiredDescription
providerRefProviderReferenceYesReference to AWSProvider
hostedZoneIDstringYesHosted zone ID
namestringYesFull DNS name (FQDN)
typestringYesRecord type (A, AAAA, CNAME, etc.)
ttl*int64ConditionalTTL in seconds (required for non-alias)
resourceRecords[]stringConditionalRecord values (required for non-alias)
aliasTarget*AliasTargetConditionalTarget for alias records
setIdentifierstringConditionalIdentifier for routing policies
weight*int64NoWeight (0-255) for weighted routing
regionstringNoRegion for latency-based routing
geoLocation*GeoLocationNoLocation for geolocation routing
failoverstringNoPRIMARY or SECONDARY
multiValueAnswerboolNoEnable multivalue answer
healthCheckIDstringNoHealth check ID
deletionPolicystringNoDelete or Retain (default: Delete)

Routing Policies​

1. Simple Routing (Default)​

A single record with one or more values:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: simple-a-record
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: app.example.com
type: A
ttl: 300
resourceRecords:
- 192.0.2.1
- 192.0.2.2
- 192.0.2.3

2. Weighted Routing​

Distributes traffic based on weights:

---
# 70% of traffic
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: app-server-1
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: app.example.com
type: A
ttl: 60
resourceRecords:
- 192.0.2.10
setIdentifier: "server-1"
weight: 70

---
# 30% of traffic
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: app-server-2
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: app.example.com
type: A
ttl: 60
resourceRecords:
- 192.0.2.20
setIdentifier: "server-2"
weight: 30

3. Latency-Based Routing​

Routes to region with lowest latency:

---
# US East
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: global-us-east
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: global.example.com
type: A
ttl: 60
resourceRecords:
- 192.0.2.10
setIdentifier: "us-east-1"
region: us-east-1

---
# EU West
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: global-eu-west
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: global.example.com
type: A
ttl: 60
resourceRecords:
- 192.0.2.20
setIdentifier: "eu-west-1"
region: eu-west-1

4. Geolocation Routing​

Routes based on user location:

---
# US users
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: geo-us
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: geo.example.com
type: A
ttl: 300
resourceRecords:
- 192.0.2.10
setIdentifier: "us-users"
geoLocation:
countryCode: US

---
# European users
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: geo-eu
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: geo.example.com
type: A
ttl: 300
resourceRecords:
- 192.0.2.20
setIdentifier: "eu-users"
geoLocation:
continentCode: EU

---
# Default (rest of the world)
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: geo-default
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: geo.example.com
type: A
ttl: 300
resourceRecords:
- 192.0.2.30
setIdentifier: "default-location"
geoLocation:
continentCode: "*"

5. Failover Routing​

Active/passive configuration:

---
# Primary
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: failover-primary
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: app.example.com
type: A
ttl: 60
resourceRecords:
- 192.0.2.10
setIdentifier: "primary"
failover: PRIMARY
healthCheckID: abc123-health-check

---
# Secondary (backup)
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: failover-secondary
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: app.example.com
type: A
ttl: 60
resourceRecords:
- 192.0.2.20
setIdentifier: "secondary"
failover: SECONDARY

6. Multivalue Answer Routing​

Returns multiple values with health checks:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: multivalue-1
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: multi.example.com
type: A
ttl: 60
resourceRecords:
- 192.0.2.10
setIdentifier: "server-1"
multiValueAnswer: true
healthCheckID: health-check-1

Special Records​

MX (Mail Exchange)​

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: mx-record
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: example.com
type: MX
ttl: 3600
resourceRecords:
- 10 mail1.example.com
- 20 mail2.example.com
- 30 mail3.example.com

TXT (SPF, DKIM, DMARC)​

Example:

---
# SPF Record
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: spf-record
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: example.com
type: TXT
ttl: 300
resourceRecords:
- '"v=spf1 include:_spf.google.com ~all"'

---
# DMARC Record
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: dmarc-record
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: _dmarc.example.com
type: TXT
ttl: 300
resourceRecords:
- '"v=DMARC1; p=quarantine; rua=mailto:[email protected]"'

SRV (Service Records)​

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: srv-record
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: _service._tcp.example.com
type: SRV
ttl: 300
resourceRecords:
- 10 60 5060 sipserver.example.com

Alias Records for AWS Resources​

Application Load Balancer (ALB)​

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: alb-alias
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: app.example.com
type: A
aliasTarget:
hostedZoneID: Z35SXDOTRQ7X7K # ALB hosted zone (us-east-1)
dnsName: my-alb-123.us-east-1.elb.amazonaws.com
evaluateTargetHealth: true

CloudFront Distribution​

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: cloudfront-alias
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: cdn.example.com
type: A
aliasTarget:
hostedZoneID: Z2FDTNDATAQYW2 # CloudFront hosted zone
dnsName: d123abc.cloudfront.net
evaluateTargetHealth: false

S3 Website Endpoint​

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: Route53RecordSet
metadata:
name: s3-website-alias
spec:
providerRef:
name: aws-provider
hostedZoneID: Z1234567890ABC
name: static.example.com
type: A
aliasTarget:
hostedZoneID: Z3AQBSTGFYJSTF # S3 website hosted zone (us-east-1)
dnsName: mybucket.s3-website-us-east-1.amazonaws.com
evaluateTargetHealth: false

Operations​

Create Record​

Command:

kubectl apply -f recordset.yaml

Check Status​

Command:

# List records
kubectl get route53recordset
kubectl get r53rs # shortname

# Details
kubectl describe route53recordset www-record

# View change status
kubectl get route53recordset www-record -o jsonpath='{.status.changeStatus}'

Update Record​

Example:

spec:
ttl: 600 # Update TTL
resourceRecords:
- 192.0.2.100 # New IP

Command:

kubectl apply -f recordset.yaml

Delete Record​

Command:

kubectl delete route53recordset www-record

Troubleshooting​

Record Not Ready​

Solutions:

  1. Check hosted zone exists
  2. Check IAM permissions
  3. Validate record type and values
  4. Check controller logs

Validation Error​

Problem: Alias target and resource records cannot coexist

Solution: Use only one:

# Either aliasTarget
spec:
aliasTarget:
hostedZoneID: Z123
dnsName: lb.example.com

# OR resourceRecords + ttl
spec:
ttl: 300
resourceRecords:
- 192.0.2.1

Change Status PENDING​

Normal: DNS changes can take up to 60 seconds to propagate

Check:

kubectl get route53recordset my-record -w

IAM Permissions​

Example:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets",
"route53:GetChange",
"route53:ListResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/*",
"arn:aws:route53:::change/*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:GetHostedZone",
"route53:ListHostedZones"
],
"Resource": "*"
}
]
}

Best Practices​

Best Practices
  • Set appropriate TTL — Development: 60-300s, Production: 300-3600s, reduce before changes
  • Use alias records for AWS resources — Free, faster resolution for ALB/CloudFront/S3
  • Implement health checks — Enable failover routing for high availability
  • Document record purposes — Clear naming conventions and descriptions
  • Use routing policies wisely — Simple for basic, weighted for A/B, failover for DR

AWS Resource Hosted Zone IDs​

ELB/ALB by Region​

  • us-east-1: Z35SXDOTRQ7X7K
  • us-west-2: Z1H1FL5HABSF5
  • eu-west-1: Z32O12XQLNTSW2

CloudFront​

  • Global: Z2FDTNDATAQYW2

S3 Website by Region​

  • us-east-1: Z3AQBSTGFYJSTF
  • us-west-2: Z3BJ6K6RIION7M

Complete list in AWS documentation

References​