Introduction
Terraform management of Amazon Route 53 DNS records represents a foundational capability for infrastructure as code teams operating within AWS. The awsroute53record resource provides direct control over the creation, update, and deletion of DNS records inside a hosted zone. The resource accepts a zone identifier, a fully qualified domain name, a record type, and either a list of record values or an alias block that points to an AWS resource. The module wrapper around this resource adds a flexible interface for configuring various routing policies including geolocation, failover, latency, weighted, and CIDR-based routing. The module allows only one routing policy block to be supplied per record and provides the option for alias records that can point to AWS resources using their AWS resource name. The module adheres to security best practices by leveraging automated scanning with Checkov. A minimal configuration to get started requires only a name argument, with the registry documenting all available arguments for a complete implementation. Real world deployments extend this minimal shape with set identifiers, health check associations, and routing policy blocks to enable traffic distribution strategies that align with availability, performance, and deployment safety goals.
Module Definition and Provider Requirements
The Terraform module that creates a Route53 record in AWS is referenced in examples with a source of boldlink/route53-records/aws and a version placeholder for insertlatestversion. The module interface exposes zone_id, name, type, ttl, and records as primary inputs. The module supports optional attributes and conflicts between alias blocks and ttl and records.
Provider version constraints are documented in the reference data. For the boldlink module:
- terraform >= 0.14.11
- aws >= 4.65.0
A specific runtime shows:
- aws 5.23.1
No modules are declared in the minimal module.
The terraform-aws-modules/terraform-aws-route53 module defines a different set of constraints:
- terraform >= 1.5.7
- aws >= 6.28
The same module also declares a name version requirement for aws >= 6.28.
The module contains no modules of its own in the first example.
Resources created by the module include:
- awsroute53record.main as a resource
The module metadata includes an environment example and project terraform-aws-route53.
Core Attributes and Parameters
The awsroute53record resource manages an Route53 Record resource. Required arguments can be minimal.
A minimal configuration example:
hcl
resource "aws_route53_record" "example" {
name = "my-route53-record"
}
The module parameter table includes:
| 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 |
Additional documented attributes from the reference facts include zoneid, name, type, ttl, records. The zoneid characteristic references the ID of the Highway 53 zone where the record will be made. It utilizes the introduction sentence structure to get to the zone ID of the "example_zone" asset. The name indicates the domain name for the record. For this situation, it's example "www.geeksforgeeks.com". The type property characterizes the kind of DNS record.
Provider configuration for AWS is required before any Route53 resources:
hcl
provider "aws" {
region = "us-east-1"
}
This section specifies the AWS provider and sets the region to "us-east-1". The provider block configures the authentication details and default settings for interacting with AWS.
Installation steps for Terraform on Amazon Linux are documented:
bash
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
sudo yum -y install terraform
Step 3: Create A File And Write Terraform Script for AWS Route 53 Using Terraform. Create a file with .tf extension in that file write a script by using following command.
Routing Policy Support
The module supports different routing policies including geolocation, failover, latency, weighted, and CIDR-based routing. Allows only one routing policy block to be supplied.
Weighted routing distributes traffic based on weights and is useful for blue-green deployments.
Weighted routing configuration:
hcl
resource "aws_route53_record" "primary" {
zone_id = aws_route53_zone.primary.zone_id
name = "app.example.com"
type = "A"
set_identifier = "primary"
weighted_routing_policy {
weight = 80
}
alias {
name = aws_lb.primary.dns_name
zone_id = aws_lb.primary.zone_id
evaluate_target_health = true
}
}
The second weighted record sends 20 percent of traffic to the canary ALB:
hcl
resource "aws_route53_record" "canary" {
zone_id = aws_route53_zone.primary.zone_id
name = "app.example.com"
type = "A"
set_identifier = "canary"
weighted_routing_policy {
weight = 20
}
alias {
name = aws_lb.canary.dns_name
zone_id = aws_lb.canary.zone_id
evaluate_target_health = true
}
}
Failover routing provides automatic failover between primary and secondary.
Primary failover record:
hcl
resource "aws_route53_record" "primary_failover" {
zone_id = aws_route53_zone.primary.zone_id
name = "app.example.com"
type = "A"
set_identifier = "primary"
failover_routing_policy {
type = "PRIMARY"
}
alias {
name = aws_lb.primary.dns_name
zone_id = aws_lb.primary.zone_id
evaluate_target_health = true
}
health_check_id = aws_route53_health_check.primary.id
}
Secondary failover record:
hcl
resource "aws_route53_record" "secondary_failover" {
zone_id = aws_route53_zone.primary.zone_id
name = "app.example.com"
type = "A"
set_identifier = "secondary"
failover_routing_policy {
type = "SECONDARY"
}
alias {
name = aws_lb.secondary.dns_name
zone_id =
}
The routing policy block selection is mutually exclusive per record.
Alias Records and Health Checks
Alias records allow pointing to AWS resources using their AWS resource name. The alias block conflicts with ttl and records.
Alias block fields include name, zoneid, and evaluatetarget_health. Evaluate target health controls whether Route 53 checks the health of the target resource.
Health checks can be associated with failover records via healthcheckid.
The module provides the option for alias records that can point to AWS resources using their AWS resource name.
Certificate Validation Automation
Automated ACM certificate validation can be implemented with for_each over domain validation options.
hcl
resource "aws_route53_record" "cert_validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = aws_route53_zone.primary.zone_id
}
Validation completion is waited on with:
hcl
resource "aws_acm_certificate_validation" "main" {
certificate_arn = aws_acm_certificate.main.arn
validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn]
}
For_Each Iteration Patterns
Managing records with for_each keeps configuration DRY.
Variable definition:
hcl
variable "subdomains" {
default = {
"api" = "10.0.1.10"
"admin" = "10.0.1.11"
"staging" = "10.0.2.10"
}
}
Resource iteration:
hcl
resource "aws_route53_record" "subdomains" {
for_each = var.subdomains
zone_id = aws_route53_zone.primary.zone_id
name = "${each.key}.example.com"
type = "A"
ttl = 300
records = [each.value]
}
The for_each pattern applies the same resource shape across multiple logical names while deriving name and records from the map.
Import Existing Records
If you have existing Route 53 records and want to bring them under Terraform management, import is used.
Import an existing record:
bash
terraform import 'aws_route53_record.web' Z1234567890_example.com_A
Import a weighted record:
bash
terraform import 'aws_route53_record.primary' Z1234567890_app.example.com_A_primary
The import ID format is {zoneid}{name}{type}, with {setidentifier} appended for routing-policy records.
Best Practices and Security Scanning
Best Practices:
- Use variables for zone IDs - Don't hardcode zone IDs
The module adheres to security best practices by leveraging automated scanning with Checkov.
The following independent sub-modules are available in the terraform-aws-modules suite:
- 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
See the respective module directories for examples and documentation.
Additional resources in the module set include:
| 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 |
Example Module Invocation
A minimum example invocation:
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
}
Examples available here. NOTE: These examples use the latest version of this module.
Conclusion
Terraform AWS Route53 record management spans a spectrum from a single resource declaration with a name to a fully parameterized module supporting weighted, failover, latency, geolocation, and CIDR-based routing policies. The core resource remains awsroute53record with zoneid, name, type, ttl, records, and optional alias blocks. Routing policies require a setidentifier and a single policy block per record. Alias records integrate directly with AWS load balancers and other resources and can evaluate target health. Foreach constructs enable DRY multi-record patterns for subdomains and ACM certificate validation. Import workflows allow existing DNS state to be absorbed into Terraform with a zoneidnametype identifier and optional setidentifier suffix. Provider configuration, module version constraints, and security scanning via Checkov form the operational envelope. Variable-driven zone IDs and avoidance of hardcoded identifiers reduce drift and improve reusability. The module interface exposes allowoverwrite for record replacement scenarios and conflicts alias with ttl and records to enforce mutually exclusive configuration paths. Installation steps on Amazon Linux and provider region settings complete the deployment prerequisites for Route 53 automation at scale.