Terraform AWS Modules Route53 provides a structured, reusable approach to managing DNS infrastructure in AWS. The ecosystem spans community modules for single record creation and the comprehensive terraform-aws-route53 collection that abstracts the complexity of Route53 API interactions while maintaining fine-grained control over DNS resources. Understanding both the single-record module and the modular collection is essential for infrastructure engineers building scalable DNS configurations.
Introduction
Route53 is central to AWS networking and application delivery, yet direct resource configuration using raw aws_route53_record can become repetitive and error-prone at scale. Terraform modules address this by encapsulating best practices, supporting routing policy variants, and enabling import workflows for brownfield environments. The two dominant reference implementations are the TerraformFoundation terraform-aws-route53-records module focused on flexible record creation, and the terraform-aws-modules/terraform-aws-route53 collection that organizes hosted zones, records, delegation sets, resolver endpoints, and cross-account associations as independent submodules.
Core Record Module Capabilities
The TerraformFoundation module creates a Route53 record in AWS with a flexible way to configure various types of routing policies for DNS records.
The module creates a Route53 record with the specified zone ID, name, type, TTL, and records. It supports optional attributes and supports different routing policies including geolocation, failover, latency, weighted, and CIDR-based routing. It provides the option for alias records that can point to AWS resources using their AWS resource name. The module allows only one routing policy block to be supplied and adheres to security best practices by leveraging automated scanning with Checkov.
Minimum Example Configuration
A minimal usage pattern is shown in the reference material:
hcl
module "minimum_example" {
source = "boldlink/route53-records/aws"
version = "insert_latest_version"
zone_id = local.zone_id
name = var.name
type = var.type
ttl = var.ttl
records = var.records
}
Provider Requirements and Resources
| Name | Version |
|---|---|
| terraform | >= 0.14.11 |
| aws | >= 4.65.0 |
| Name | Version |
|---|---|
| aws | 5.23.1 |
No modules.
| Name | Type |
|---|---|
| awsroute53record.main | resource |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| alias | (Optional) An alias block. Conflicts with ttl & records. | any | {} | no |
| allow_overwrite | Allow creation of this record in Terraform to overwrite an existing record, if any |
The module is designed for a single aws_route53_record.main resource and exposes parameters for zone identification, record name, type, TTL, and records. Alias configuration conflicts with TTL and records, reflecting the Route53 constraint that alias records cannot coexist with standard record values.
Routing Policy Support
Support for different routing policies is a distinguishing feature:
- geolocation
- failover
- latency
- weighted
- CIDR-based routing
The module allows only one routing policy block to be supplied per record, enforcing AWS validation rules. Alias records can point to AWS resources using their AWS resource name, enabling integration with load balancers, CloudFront distributions, and S3 website endpoints without hardcoding DNS names.
Terraform AWS Modules Route53 Collection Architecture
The terraform-aws-route53 module is a comprehensive Terraform implementation for managing AWS Route53 resources. This module provides a structured approach to define, deploy, and manage DNS infrastructure on AWS, including hosted zones, records, resolver endpoints, and cross-account associations.
The module is designed to be modular, reusable, and maintainable, following Terraform best practices. It enables infrastructure engineers to declaratively manage their DNS configuration using Terraform. It abstracts the complexity of AWS Route53 API interactions while providing fine-grained control over DNS resources.
The terraform-aws-route53 module is organized as a collection of independent submodules, each focused on a specific Route53 resource type.
Submodule Structure and Dependencies
| Submodule | Purpose | Primary Resources |
|---|---|---|
| zones | Manages Route53 hosted zones (public or private) | awsroute53zone |
| records | Creates and manages DNS records within zones | awsroute53record |
| delegation-sets | Manages reusable delegation sets | awsroute53delegation_set |
| resolver-endpoints | Creates DNS resolver endpoints for hybrid environments | awsroute53resolver_endpoint |
| resolver-rule-associations | Associates resolver rules with VPCs | awsroute53resolverruleassociation |
| zone-cross-account-vpc-association | Associates zones with VPCs across AWS accounts | awsroute53vpcassociationauthorization, awsroute53zone_association |
Sources: README.md7-14
Additional independent sub-modules are available:
- delegation-sets creates AWS Route53 Delegation Sets
- resolver-endpoint creates an AWS Route53 Resolver Endpoint and associated resources
- resolver-firewall-rule-group creates an AWS Route53 Resolver Firewall Rule Group and associated resources
The module structure separates concerns so teams can adopt only the components they need, reducing dependency surface area and allowing independent versioning.
Typical Implementation Workflow
The terraform-aws-route53 module supports a wide range of DNS configuration capabilities. A typical implementation workflow involves defining hosted zones first, then creating records within those zones, and optionally configuring resolver endpoints for hybrid DNS, delegation sets for name server reuse, and cross-account VPC associations.
The terraform-aws-route53 module has evolved significantly since its initial release, with major feature additions including:
The most recent major version v5.0.0 added support for timeouts, CIDR routing policy, and
The module continues to expand to cover emerging Route53 features while maintaining backward compatibility for core record and zone management.
Record Module Example with Multiple Record Types
The terraform-aws-modules/terraform-aws-route53 collection demonstrates record handling through a records map parameter that accepts heterogeneous record definitions.
hcl
module "zone" {
source = "terraform-aws-modules/route53/aws"
name = "terraform-aws-modules-example.com"
comment = "Public zone for terraform-aws-modules example"
records = {
s3 = {
name = "s3-bucket-z1bkctxd74ezpe.terraform-aws-modules-example.com"
type = "A"
alias = {
name = "s3-website-eu-west-1.amazonaws.com"
zone_id = "Z1BKCTXD74EZPE"
}
}
mail = {
full_name = "terraform-aws-modules-example.com"
type = "MX"
ttl = 3600
records = [
"1 aspmx.l.google.com",
"5 alt1.aspmx.l.google.com",
"5 alt2.aspmx.l.google.com",
"10 alt3.aspmx.l.google.com",
"10 alt4.aspmx.l.google.com",
]
}
geo = {
type = "CNAME"
ttl = 5
records = ["europe.test.example.com."]
set_identifier = "europe"
geolocation_routing_policy = {
continent = "EU"
}
}
geoproximity-aws-region = {
type = "CNAME"
ttl = 5
records = ["us-east-1.test.example.com."]
set_identifier = "us-east-1-region"
geoproximity_routing_policy = {
aws_region = "us-east-1"
bias = 0
}
}
geoproximity-coordinates = {
type = "CNAME"
ttl = 5
records = ["nyc.test.example.com."]
set_identifier = "nyc"
geoproximity_routing_policy = {
coordinates = [{
latitude = "40.71"
longitude = "-74.01"
}]
}
}
cloudfront_ipv4 = {
name = "cloudfront"
type = "A"
alias = {
name = "d3778kt32cqdww.cloudfront.net"
zone_id = "EF3T6981F7M1"
}
}
cloudfront_ipv6 = {
name = "cloudfront"
type = "AAAA"
alias = {
name = "d3778kt32cqdww.cloudfront.net"
zone_id = "EF3T6981F7M1"
}
}
blue = {
name = "test"
type = "CNAME"
ttl =
}
}
The example illustrates alias records for S3 and CloudFront, MX records with multiple values, and geolocation and geoproximity routing policies with set identifiers.
Zone and DNSSEC Resources
| Name | Type |
|---|---|
| awsroute53hostedzonednssec.this | resource |
| awsroute53keysigningkey.this | resource |
| awsroute53record.this | resource |
| awsroute53vpcassociationauthorization.this | resource |
| awsroute53zone.ignore_vpc | resource |
| awsroute53zone.this | resource |
| awsroute53zone.this | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| comment | A comment for the hosted zone |
Provider constraints for the collection are:
| Name | Version |
|---|---|
| terraform | >= 1.5.7 |
| aws | >= 6.28 |
| Name | Version |
|---|---|
| aws | >= 6.28 |
| Name | Source | Version |
|---|---|---|
| route53dnsseckms | terraform-aws-modules/kms/aws | 4.0.0 |
Auto-Detection and Zone Lookup Patterns
Every Route53 record in plain Terraform means a zone lookup, an explicit type, and for load balancers a separate data source just to wire the alias.
The traditional pattern requires explicit data sources:
```hcl
data "awsroute53zone" "this" {
name = "api.example.com."
}
data "aws_lb" "api" {
name = "api-nlb"
}
resource "awsroute53record" "api" {
zoneid = data.awsroute53zone.this.zoneid
name = "api.example.com"
type = "A"
alias {
name = data.awslb.api.dnsname
zoneid = data.awslb.api.zoneid
evaluatetarget_health = true
}
}
```
With a module that infers everything, the same record becomes simplified:
hcl
inputs = {
name = "api.example.com"
records = "api-nlb-1234567890.elb.eu-west-1.amazonaws.com"
}
Zone auto-detection works by splitting the FQDN, dropping the first label, and querying Route53 for the hosted zone:
name = "api.example.com"
│
└─ strip first label
│
▼
"example.com" ──► awsroute53zone lookup
This reduces boilerplate and avoids manual zone ID management, especially useful when records are defined across many subdomains.
Importing Existing Route53 Records
Import existing Route53 records in Terraform. Terraform has a straightforward way of importing existing records managed outside Terraform via terraform import command. The usage is documented and works well if you have a handful of records to import. However when you work with custom Terraform modules and have a whole bunch of records to be imported, you would look out for ways to script the entire workflow.
The described workflow consists of three parts:
- Import all existing records in a hosted zone using AWS CLI
bash
aws route53 list-resource-record-sets --hosted-zone-id XXX > data/company-tld.json
Loads the zone records in a dict
python
def load_records(zone_file=ZONE_FILE):
with open(zone_file) as record_file:
data = json.load(record_file)
return data
- Import the record in Terraform state
To do this, Terraform CLI comes with an import command
The approach enables bulk import of brownfield DNS configurations into Terraform state, preserving existing Route53 records while bringing them under infrastructure-as-code management.
Operational Considerations
The module adheres to security best practices by leveraging automated scanning with Checkov. Allow creation of this record in Terraform to overwrite an existing record, if any is exposed as a configurable flag to prevent accidental drift.
Examples available here use the latest version of this module. The examples use the latest version of this module, encouraging teams to stay current with provider changes and new routing policy capabilities.
When using the terraform-aws-modules/route53 collection, the module abstracts the complexity of AWS Route53 API interactions while providing fine-grained control over DNS resources. The collection supports timeouts, CIDR routing policy, and advanced geoproximity configurations as of v5.0.0.
Conclusion
Terraform AWS Modules Route53 records deliver two complementary paths for DNS management. The focused record module provides a flexible way to configure various types of routing policies for your DNS records with alias support, optional attributes, and security scanning. The comprehensive terraform-aws-route53 collection organizes hosted zones, records, delegation sets, resolver endpoints, and cross-account associations into independent submodules that follow Terraform best practices.
Auto-detection of zones reduces boilerplate for teams managing many subdomains, while scripted import workflows enable brownfield adoption. The module ecosystem supports geolocation, failover, latency, weighted, CIDR-based routing, and geoproximity policies, with examples covering S3 website aliases, CloudFront distributions, MX records, and resolver configurations.
Adopting these modules allows infrastructure engineers to declaratively manage DNS infrastructure on AWS with maintainable, reusable configurations that align with Route53 API capabilities and operational best practices.