NTC Route53 Migration (v1 → v2)
This guide covers the migration of terraform-aws-ntc-route53 from v1.x to v2.x.
Overview of Changes
v2.0.0 introduces significant architectural improvements to simplify multi-region configurations:
Key Changes
| Feature | v1.x | v2.x |
|---|---|---|
| Provider Architecture | AWS Provider v5 | AWS Provider v6 with region attribute |
| DNSSEC Configuration | Separate module | Integrated into root module |
| Query Logs Configuration | Separate module | Integrated into root module |
| Multi-Region Support | Multiple provider aliases + module calls | Single module with regions configuration |
| Module Complexity | 3+ module calls needed | Single module call |
Before & After Comparison
- v1.x Structure
- v2.x Structure
Previous approach required 3 separate module configurations:
# Main hosted zone module
module "ntc_route53" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-route53?ref=1.3.0"
# ... configuration
}
# Separate DNSSEC module
module "ntc_route53_dnssec" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-route53//modules/dnssec?ref=1.3.0"
zone_id = module.ntc_route53.zone_id
# ... configuration
providers = {
aws.us_east_1 = aws.use1
}
}
# Separate Query Logs module
module "ntc_route53_query_logging" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-route53//modules/query-logs?ref=1.3.0"
zone_id = module.ntc_route53.zone_id
# ... configuration
providers = {
aws.us_east_1 = aws.use1
}
}
New consolidated approach with a single module:
# All-in-one configuration
module "ntc_route53" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-route53?ref=2.0.0"
# ... configuration
# DNSSEC integrated
dnssec_config = {
enabled = true
key_signing_keys = [
{
ksk_name = "ksk-1"
ksk_status = "active"
}
]
}
# Query Logs integrated
query_logs_config = {
enabled = true
}
}
Migration Steps
Step 1: Upgrade AWS Provider to v6 (Keep NTC at v1.x)
Upgrade the AWS provider to v6 before upgrading NTC modules. This writes the new region attribute into the Terraform state for all existing resources. Without this intermediate step, resources managed through non-default (aliased) providers may be flagged for recreation during the NTC v2 upgrade.
Update only the provider version constraint. Keep all existing provider aliases and NTC module versions unchanged.
terraform {
required_version = ">= 1.3.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0" # ← Updated from ~> 5.0
}
}
}
# Keep all existing provider aliases unchanged
provider "aws" {
region = "eu-central-1"
}
provider "aws" {
alias = "euc1"
region = "eu-central-1"
}
provider "aws" {
alias = "euc2"
region = "eu-central-2"
}
provider "aws" {
alias = "use1"
region = "us-east-1"
}
Initialize and apply:
terraform init -upgrade
terraform plan
# Expected: in-place updates adding the region attribute — NO recreations
terraform apply
Step 2: Simplify Provider Configuration
After the provider upgrade is applied, simplify the provider configuration for NTC v2:
terraform {
required_version = ">= 1.5.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
provider "aws" {
region = "eu-central-1"
}
# Regional providers still needed for some exceptions (where region attribute isn't supported)
provider "aws" {
alias = "use1"
region = "us-east-1"
}
Step 3: Consolidate Module Configuration
Extract DNSSEC and Query Log Configuration
If you have separate DNSSEC and Query Log modules, consolidate them:
- Old Configuration
- New Configuration
# ---------------------------------------------------------------------------------------------------------------------
# ¦ NTC ROUTE53 - PUBLIC HOSTED ZONE
# ---------------------------------------------------------------------------------------------------------------------
module "ntc_route53" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-route53?ref=1.3.0"
zone_name = "mydomain.com"
zone_description = "Managed by Terraform"
zone_type = "public"
}
# ---------------------------------------------------------------------------------------------------------------------
# ¦ NTC ROUTE53 - DNSSEC (Separate Module)
# ---------------------------------------------------------------------------------------------------------------------
module "ntc_route53_dnssec" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-route53//modules/dnssec?ref=1.3.0"
zone_id = module.ntc_route53.zone_id
key_signing_keys = [
{
ksk_name = "ksk-1"
ksk_status = "active"
}
]
providers = {
aws.us_east_1 = aws.use1
}
}
# ---------------------------------------------------------------------------------------------------------------------
# ¦ NTC ROUTE53 - QUERY LOGGING (Separate Module)
# ---------------------------------------------------------------------------------------------------------------------
module "ntc_route53_query_logging" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-route53//modules/query-logs?ref=1.3.0"
zone_id = module.ntc_route53.zone_id
providers = {
aws.us_east_1 = aws.use1
}
}
# ---------------------------------------------------------------------------------------------------------------------
# ¦ NTC ROUTE53 - PUBLIC HOSTED ZONE (All-in-One)
# ---------------------------------------------------------------------------------------------------------------------
module "ntc_route53" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-route53?ref=2.0.0"
zone_name = "mydomain.com"
zone_description = "Managed by Terraform"
zone_type = "public"
# DNSSEC Configuration (integrated)
dnssec_config = {
enabled = true
key_signing_keys = [
{
ksk_name = "ksk-1"
ksk_status = "active"
}
]
}
# Query Logs Configuration (integrated)
query_logs_config = {
enabled = true
}
}
Step 4: Add State Migration Blocks
Create a state_migrations.tf file to migrate resources without recreating them:
# ---------------------------------------------------------------------------------------------------------------------
# ¦ STATE MIGRATIONS - v1.x to v2.x
# ---------------------------------------------------------------------------------------------------------------------
# These moved blocks ensure Terraform state is updated without recreating resources
# Run: terraform plan - should show only "moved" operations (no creates/destroys)
# After successful migration, this file can be deleted
# -------------------------------------------------------------------------------------------------------------------
# DNSSEC
# -------------------------------------------------------------------------------------------------------------------
moved {
from = module.ntc_route53_dnssec.aws_kms_alias.ntc_dnssec["ksk-1"]
to = module.ntc_route53.module.dnssec[0].aws_kms_alias.ntc_dnssec["ksk-1"]
}
moved {
from = module.ntc_route53_dnssec.aws_kms_key.ntc_dnssec["ksk-1"]
to = module.ntc_route53.module.dnssec[0].aws_kms_key.ntc_dnssec["ksk-1"]
}
moved {
from = module.ntc_route53_dnssec.aws_route53_hosted_zone_dnssec.ntc_dnssec["ksk-1"]
to = module.ntc_route53.module.dnssec[0].aws_route53_hosted_zone_dnssec.ntc_dnssec["ksk-1"]
}
moved {
from = module.ntc_route53_dnssec.aws_route53_key_signing_key.ntc_dnssec["ksk-1"]
to = module.ntc_route53.module.dnssec[0].aws_route53_key_signing_key.ntc_dnssec["ksk-1"]
}
# -------------------------------------------------------------------------------------------------------------------
# QUERY LOGS
# -------------------------------------------------------------------------------------------------------------------
moved {
from = module.ntc_route53_query_logging.aws_route53_query_log.ntc_query_log
to = module.ntc_route53.module.query_logs[0].aws_route53_query_log.ntc_query_log
}
moved {
from = module.ntc_route53_query_logging.aws_kms_key.ntc_query_log_encryption[0]
to = module.ntc_route53.module.query_logs[0].aws_kms_key.ntc_query_log_encryption[0]
}
moved {
from = module.ntc_route53_query_logging.aws_kms_alias.ntc_query_log_encryption[0]
to = module.ntc_route53.module.query_logs[0].aws_kms_alias.ntc_query_log_encryption[0]
}
moved {
from = module.ntc_route53_query_logging.aws_cloudwatch_log_resource_policy.ntc_query_log
to = module.ntc_route53.module.query_logs[0].aws_cloudwatch_log_resource_policy.ntc_query_log
}
moved {
from = module.ntc_route53_query_logging.aws_cloudwatch_log_group.ntc_query_log
to = module.ntc_route53.module.query_logs[0].aws_cloudwatch_log_group.ntc_query_log
}
- These
movedblocks tell Terraform to update its state without recreating resources - After successful migration (successful apply), you can delete
state_migrations.tf - If you have different regions, adjust the region names accordingly
Step 5: Remove Old Definitions
After consolidating the configuration, remove the DNSSEC and Query Logs module calls.
Step 6: Initialize and Plan
# Upgrade to AWS Provider v6
terraform init -upgrade
# Review the plan
terraform plan
Expected plan output:
- ✅ Many
movedoperations (state migrations) - ✅ Some in-place updates (configuration changes)
- ❌ NO resource deletions or recreations
If you see deletions or recreations, do NOT apply! Review your configuration and state migration blocks carefully.
Step 7: Apply Migration
terraform apply
Monitor the output. The migration should complete without errors.
Step 8: Clean Up
After successful migration:
# Remove the state migration file (optional, but recommended)
rm state_migrations.tf
# Commit your changes
git add .
git commit -m "Migrate ntc-route53 from v1.x to v2.x"
Complete Example
See a complete before/after example in the GitHub repository:
Troubleshooting
Issue: Resources Being Recreated
Symptom: terraform plan shows deletions and recreations
Solution:
- Check your
movedblocks match your existing state exactly - Verify resource names haven't changed
- Use
terraform state listto see current resource addresses
Issue: Provider Configuration Errors
Symptom: "provider configuration not present" errors
Solution:
- Ensure AWS Provider v6 is installed (
terraform init -upgrade) - Verify your
required_providersblock hasversion = "~> 6.0"
Issue: Region Not Supported
Symptom: "region not available" errors in ESC
Solution:
- For ESC, ensure you're using supported regions
- Check region codes match your partition (e.g.,
eu-central-1vseusc-de-east-1)
Need Help?
- 📚 Review the main migration guide
- 🐛 Check common issues
- 💬 Contact NTC Support