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 (awsroute53vpcassociationauthorization) must be performed by the account that owns the zone.
Hence why the awsroute53zoneassociation 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"
bucketprefix = "s3-bucket-"
forcedestroy = true
website = {
indexdocument = "index.html"
}
}
module "cloudfront" {
source = "terraform-aws-modules/cloudfront/aws"
version = "~> 3.0"
enabled = false
waitfordeployment = false
origin = {
s3bucket = {
domainname = module.s3bucket.s3bucketbucketregionaldomainname
}
}
defaultcachebehavior = {
targetoriginid = "s3bucket"
viewerprotocolpolicy = "allow-all"
}
viewercertificate = {
cloudfrontdefaultcertificate = true
}
}
resource "awsroute53healthcheck" "failover" {
fqdn = module.cloudfront.cloudfrontdistributiondomainname
port = 443
type = "HTTPS"
resourcepath = "/index.html"
failurethreshold = 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.