Skip to content

sourcefuse/terraform-aws-arc-route53

Repository files navigation

Module Structure

AWS Route53 Terraform Module

Latest Release Last Updated Terraform GitHub Actions

Quality gate


terraform-aws-module-template

Overview

A production-ready Terraform module for provisioning and managing AWS Route 53 hosted zones and DNS records with support for advanced routing policies, health checks, and alias records.

Prerequisites

Before using this module, ensure you have the following:

  • AWS credentials configured.
  • Terraform installed.
  • A working knowledge of Terraform.

Features

  • Public and Private Hosted Zones - Support for both public and private DNS zones
  • Multiple Record Types - A, AAAA, CNAME, MX, TXT, SRV, NS, PTR
  • Alias Records - Native support for ALB, NLB, CloudFront, S3, and other AWS services
  • Advanced Routing Policies - Weighted, latency-based, failover, and geolocation routing
  • Health Checks - HTTP/HTTPS/TCP endpoint monitoring with CloudWatch integration
  • Multi-VPC Support - Associate private zones with multiple VPCs
  • Idempotent & Safe - Conditional creation and force destroy protection
  • Well-Architected - Follows AWS and Terraform best practices

Usage

Basic Public Hosted Zone

module "tags" {
  source  = "sourcefuse/arc-tags/aws"
  version = "1.2.6"

  environment = "production"
  project     = "terraform-aws-arc-route53"
}

module "route53" {
  source = "path/to/module"

  name    = "example.com"
  comment = "Production DNS zone"

  records = {
    "example.com" = {
      type    = "A"
      ttl     = 300
      records = ["192.0.2.1"]
    }
    "www.example.com" = {
      type    = "CNAME"
      ttl     = 300
      records = ["example.com"]
    }
  }

  tags = module.tags.tags
}

Private Hosted Zone

module "route53_private" {
  source = "path/to/module"

  name      = "internal.example.com"
  zone_type = "private"
  vpc_id    = "vpc-12345678"

  records = {
    "db.internal.example.com" = {
      type    = "A"
      ttl     = 300
      records = ["10.0.1.100"]
    }
  }
}

Alias Record (ALB)

module "route53_alias" {
  source = "path/to/module"

  name = "example.com"

  records = {
    "app.example.com" = {
      type = "A"
      alias = {
        name                   = aws_lb.main.dns_name
        zone_id                = aws_lb.main.zone_id
        evaluate_target_health = true
      }
    }
  }
}

Failover Routing with Health Checks

module "route53_failover" {
  source = "path/to/module"

  name = "example.com"

  health_checks = {
    "primary" = {
      type              = "HTTPS"
      fqdn              = "primary.example.com"
      port              = 443
      resource_path     = "/health"
      failure_threshold = 3
      request_interval  = 30
    }
  }

  records = {
    "api.example.com" = {
      type            = "A"
      ttl             = 60
      records         = ["192.0.2.1"]
      set_identifier  = "primary"
      health_check_id = module.route53_failover.health_check_ids["primary"]
      failover_routing_policy = {
        type = "PRIMARY"
      }
    }
  }
}

Examples

Usage

To see a full example, check out the main.tf file in the example folder.

module "this" {
  source = "git::https://github.com/sourcefuse/terraform-aws-arc-route53"
}

Requirements

Name Version
terraform >= 1.5.0
aws >= 5.0, < 7.0

Providers

Name Version
aws 6.35.1

Modules

No modules.

Resources

Name Type
aws_route53_health_check.calculated resource
aws_route53_health_check.cloudwatch resource
aws_route53_health_check.endpoint resource
aws_route53_hosted_zone_dnssec.this resource
aws_route53_key_signing_key.this resource
aws_route53_record.alias resource
aws_route53_record.this resource
aws_route53_vpc_association_authorization.this resource
aws_route53_zone.this resource
aws_route53_zone_association.secondary resource
aws_region.current data source
aws_route53_zone.existing data source

Inputs

Name Description Type Default Required
comment Comment for the hosted zone string "Managed by Terraform" no
create_zone Whether to create the Route 53 hosted zone bool true no
delegation_set_id ID of the reusable delegation set to associate with the zone string null no
dnssec_kms_key_arn ARN of KMS key for DNSSEC signing (must be in us-east-1) string null no
dnssec_signing_key_name Name for the DNSSEC key signing key string null no
enable_accelerated_recovery Enable Route 53 Accelerated Recovery (60-minute RTO for public zones) bool null no
enable_dnssec Enable DNSSEC signing for the hosted zone bool false no
force_destroy Whether to force destroy all records in the zone when deleting bool false no
health_checks Map of health checks to create
map(object({
type = string # HTTP, HTTPS, TCP, CALCULATED, HTTP_STR_MATCH, HTTPS_STR_MATCH, CLOUDWATCH_METRIC
resource_path = optional(string)
fqdn = optional(string)
ip_address = optional(string)
port = optional(number)
protocol = optional(string)
failure_threshold = optional(number, 3)
request_interval = optional(number, 30)
measure_latency = optional(bool, false)
enable_sni = optional(bool, true)
search_string = optional(string)
cloudwatch_alarm_name = optional(string)
cloudwatch_alarm_region = optional(string)
insufficient_data_health_status = optional(string, "Healthy")
child_health_checks = optional(list(string))
child_healthcheck_threshold = optional(number)
disabled = optional(bool, false)
invert_healthcheck = optional(bool, false)
routing_control_arn = optional(string)
}))
{} no
name Name of the Route 53 hosted zone string n/a yes
records Map of DNS records to create
map(object({
type = string
ttl = optional(number)
records = optional(list(string))

# Alias configuration
alias = optional(object({
name = string
zone_id = string
evaluate_target_health = optional(bool, false)
}))

# Routing policies
set_identifier = optional(string)

# Weighted routing
weighted_routing_policy = optional(object({
weight = number
}))

# Latency routing
latency_routing_policy = optional(object({
region = string
}))

# Failover routing
failover_routing_policy = optional(object({
type = string # PRIMARY or SECONDARY
}))

# Geolocation routing
geolocation_routing_policy = optional(object({
continent = optional(string)
country = optional(string)
subdivision = optional(string)
}))

# Geoproximity routing
geoproximity_routing_policy = optional(object({
aws_region = optional(string)
bias = optional(number)
coordinates = optional(list(object({
latitude = number
longitude = number
})))
local_zone_group = optional(string)
}))

# CIDR routing
cidr_routing_policy = optional(object({
collection_id = string
location_name = string
}))

# Multivalue answer routing
multivalue_answer_routing_policy = optional(bool)

# Health check
health_check_id = optional(string)

# Allow overwrite
allow_overwrite = optional(bool, false)

# Timeouts
record_timeouts = optional(object({
create = optional(string)
update = optional(string)
delete = optional(string)
}))
}))
{} no
secondary_vpcs List of secondary VPCs to associate with the hosted zone
list(object({
vpc_id = string
vpc_region = optional(string)
}))
[] no
tags A map of tags to assign to resources map(string) {} no
vpc_association_authorizations VPC association authorizations for cross-account VPC associations
map(object({
vpc_id = string
vpc_region = optional(string)
}))
{} no
vpc_id VPC ID to associate with private hosted zone string null no
vpc_region VPC region (defaults to current region if not specified) string null no
zone_tags Additional tags specific to the hosted zone map(string) {} no
zone_timeouts Timeouts for zone operations
object({
create = optional(string)
update = optional(string)
delete = optional(string)
})
null no
zone_type Type of hosted zone (public or private) string "public" no

Outputs

Name Description
dnssec_key_signing_key_id The ID of the DNSSEC key signing key
dnssec_key_signing_key_status The status of the DNSSEC key signing key
dnssec_status The status of DNSSEC for the hosted zone
health_check_arns Map of health check names to their ARNs
health_check_ids Map of health check names to their IDs
name_servers List of name servers for the hosted zone
record_ids Map of record names to their IDs
record_names Map of record names to their FQDNs
zone_arn The ARN of the hosted zone
zone_id The hosted zone ID
zone_name The name of the hosted zone

Versioning

This project uses a .version file at the root of the repo which the pipeline reads from and does a git tag.

When you intend to commit to main, you will need to increment this version. Once the project is merged, the pipeline will kick off and tag the latest git commit.

Development

Prerequisites

Configurations

  • Configure pre-commit hooks
    pre-commit install

Versioning

while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch

For Example

git commit -m "your commit message #major"

By specifying this , it will bump the version and if you don't specify this in your commit message then by default it will consider patch and will bump that accordingly

Tests

  • Tests are available in test directory
  • Configure the dependencies
    cd test/
    go mod init github.com/sourcefuse/terraform-aws-refarch-<module_name>
    go get github.com/gruntwork-io/terratest/modules/terraform
  • Now execute the test
    go test -timeout  30m

Authors

This project is authored by:

  • SourceFuse ARC Team

About

Terraform module for route53

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors