Terraform Route53 Module Deep Dive for Production DNS Automation

The terraform-aws-route53 module provides a consolidated interface for provisioning and managing Amazon Route 53 DNS resources with Terraform. It is positioned as a practical starting point for implementing DNS configurations that cover hosted zones, records, DNSSEC, resolver endpoints, and associated authorizations. The module bundles examples that demonstrate practical applications of its features and serves as a reference for building common DNS patterns without manually composing each AWS resource.

The module is intended for teams that need repeatable, versioned DNS infrastructure. Examples included in the repository help you understand how to implement common DNS configurations using Terraform. The complete example demonstrates a comprehensive Route53 configuration with multiple components working together. The complete example demonstrates comprehensive usage of the terraform-aws-route53 module, showcasing all major features and components through practical configurations.

Module Purpose and Example Scope

The terraform-aws-route53 module includes comprehensive examples that showcase its capabilities. The main example demonstrates practical configurations that can be run using standard Terraform commands. To use the complete example you apply Terraform and after testing you can clean up resources with terraform destroy.

Running these examples creates AWS resources that may incur costs. The examples can be run using standard Terraform commands. The complete example demonstrates a comprehensive Route53 configuration with multiple components working together.

This example serves as a reference implementation that covers most features of the module and demonstrates best practices for configuring complex DNS infrastructure with Terraform.

Core Module Structure and Dependencies

The module is built around a primary zone module source and exposes independent sub-modules for specialized Route53 capabilities.

The following 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

See the respective module directories for examples and documentation.

A typical zone declaration uses the module source terraform-aws-modules/route53/aws with tags applied at the module level.

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" } } } tags = { Environment = "example" Project = "terraform-aws-route53" } }

Tags are commonly set to Environment = "example" and Project = "terraform-aws-route53" in the example configurations.

Version Constraints and Provider Requirements

The module declares explicit version constraints for Terraform and the AWS provider. These constraints ensure compatibility with the resource schemas used inside the module.

Terraform and AWS Provider Requirements

Name Version
terraform >= 1.5.7
aws >= 6.28

The complete example documentation also references an earlier compatibility matrix used for the example:

Name Version
Terraform >= 1.3.2
AWS Provider >= 5.91

Module Inputs Summary

Name Description Type Default Required
comment A comment for the hosted zone

Resource Coverage

The module creates and manages a set of Route53 resources. The resource inventory includes:

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

The module also declares a dependency on an external KMS module for DNSSEC:

Name Source Version
route53dnsseckms terraform-aws-modules/kms/aws 4.0.0

Example Record Patterns

The complete example demonstrates a comprehensive Route53 configuration with multiple components working together through the records map. Practical patterns shown include alias records, mail exchange, geolocation routing, geoproximity routing, and CloudFront integration.

A public zone example includes:

  • An S3 website alias record with an A type pointing to an S3 website endpoint zone id
  • An MX record for mail with multiple priority entries
  • A geolocation CNAME with continent based routing policy
  • Geoproximity routing by AWS region with bias
  • Geoproximity routing by coordinates with latitude and longitude
  • CloudFront IPv4 and IPv6 alias records

hcl records = { 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" } } }

Private Zones and VPC Association

Private hosted zones are configured with VPC association. A private zone example shows:

hcl module "zone" { source = "terraform-aws-modules/route53/aws" name = "terraform-aws-modules-example.com" comment = "Private zone for terraform-aws-modules example" records = { "apigateway1" = { type = "A" alias = { name = "d-10qxlbvagl.execute-api.eu-west-1.amazonaws.com" zone_id = "ZLY8HYME6SFAD" } } ip_alias = { name = "terraform-aws-modules-example.com" type = "A" ttl = 3600 records = [ "10.10.10.10", ] } } vpc = { one = { vpc_id = "vpc-1234556abcdef" vpc_region = "eu-west-1" } } tags = { Environment = "example" Project = "terraform-aws-route53" } }

Association behavior is split by account ownership:

Association (awsroute53zoneassociation) must be performed by the account that owns the VPC.
Association authorization (aws
route53vpcassociationauthorization) must be performed by the account that owns the zone.
Hence why the aws
route53zoneassociation resource is outside the scope of the module, but the authorization (awsroute53vpcassociationauthorization) is inside the scope of the module.

Caution

Since Terraform does not support variables in the lifecycleblock, the ignorevpc variable is used to switch between two resources: awsroute53zone.this and awsroute53zone.ignore_vpc.
Therefore, if you changes this value after resources have been created, Terraform will attempt to destroy and recreate the Route53 zone which is usually not desired

Integration with Other AWS Services

The example demonstrates integration of Route53 with other AWS services:

```hcl
module "s3bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
bucket
prefix = "s3-bucket-"
forcedestroy = true
website = {
index
document = "index.html"
}
}

module "cloudfront" {
source = "terraform-aws-modules/cloudfront/aws"
version = "~> 3.0"
enabled = false
waitfordeployment = false
origin = {
s3bucket = {
domain
name = module.s3bucket.s3bucketbucketregionaldomainname
}
}
defaultcachebehavior = {
targetoriginid = "s3bucket"
viewer
protocolpolicy = "allow-all"
}
viewer
certificate = {
cloudfrontdefaultcertificate = true
}
}

resource "awsroute53healthcheck" "failover" {
fqdn = module.cloudfront.cloudfront
distributiondomainname
port = 443
type = "HTTPS"
resourcepath = "/index.html"
failure
threshold = 3
request_interval = 30
}
```

DNS records are created to reference these services, demonstrating how to integrate Route53 with a broader AWS infrastructure.

Disabling Components and Configuration Guardrails

The module supports conditional creation of optional components. The example shows how to disable specific modules when needed:

```hcl
module "disabledresolverendpoints" {
source = "../../modules/resolver-endpoints"
create = false
}

module "disabled_records" {
source = ...
}
```

This pattern allows you to keep a single configuration and toggle features without removing code.

Complete Example Workflow

The complete example demonstrates comprehensive usage of the terraform-aws-route53 module, showcasing:

The complete example demonstrates a comprehensive Route53 configuration with multiple components working together.

To evaluate the example:

  • Run terraform apply to provision the example resources
  • After testing, you can clean up resources with terraform destroy
  • When you no longer need these resources, run terraform destroy

Note: Running these examples creates AWS resources that may incur costs.

The example shows integration with VPC configuration:

hcl security_group_name_prefix = "example2-sg-" security_group_ingress_cidr_blocks = [ module.vpc1.vpc_cidr_block ] security_group_egress_cidr_blocks = [ module.vpc2.vpc_cidr_block ]

The example shows:

Conclusion

The terraform-aws-route53 module provides a structured, example-driven approach to managing Route53 DNS infrastructure with Terraform. It combines a primary zone module with independent sub-modules for delegation sets, resolver endpoints, and resolver firewall rule groups. Version constraints are explicit for Terraform >= 1.5.7 and AWS provider >= 6.28, with example compatibility documented at Terraform >= 1.3.2 and AWS Provider >= 5.91.

The complete example serves as a reference implementation that covers most features of the module and demonstrates best practices for configuring complex DNS infrastructure with Terraform. It showcases alias records for S3 and CloudFront, MX records, geolocation and geoproximity routing policies, private zone VPC associations, and integration with S3 buckets, CloudFront distributions, and Route53 health checks.

Operational considerations are embedded in the design. VPC association authorization is handled inside the module while the actual zone association must be performed by the VPC owning account. The ignorevpc variable switches between awsroute53zone.this and awsroute53zone.ignorevpc because Terraform does not support variables in lifecycle_block, and changing this value after creation will trigger destroy and recreate of the zone.

For production use, the module supports disabling components via create flags, tagging with Environment and Project metadata, and comprehensive record definitions. Running the examples creates AWS resources that may incur costs, and cleanup is performed with terraform destroy.

Sources

  1. deepwiki.com terraform-aws-route53 usage examples
  2. github.com terraform-aws-modules terraform-aws-route53
  3. deepwiki.com terraform-aws-route53 complete example

Related Posts