Terraform AWS Modules Route53: Records Management and DNS Infrastructure Patterns

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
evaluate
target_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:

  1. 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

  1. 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.

Sources

  1. TerraformFoundation/terraform-aws-route53-records
  2. deepwiki.com/terraform-aws-modules/terraform-aws-route53
  3. mrkaran.dev/posts/terraform-route53-import
  4. bard.sh/posts/route53-auto-detecting-terraform
  5. terraform-aws-modules/terraform-aws-route53

Related Posts