Terraform AWS Route53 Record Resource Configuration and Routing Policy Implementation

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.

Sources

  1. TerraformFoundation
  2. awsfundamentals.com
  3. oneuptime.com
  4. geeksforgeeks.org
  5. github.com

Related Posts