Managing Cloud DNS with Terraform

Learn how to set up and manage Google Cloud DNS using Terraform

In this guide, we’ll explore how to manage Google Cloud DNS using Terraform.

Video Tutorial

Learn more about managing Google Cloud DNS with Terraform in this comprehensive video tutorial:

Prerequisites

  • Google Cloud SDK installed and configured
  • Terraform installed (version 1.0.0 or later)
  • A GCP project with billing enabled

Project Structure

.
├── main.tf                   # Main Terraform configuration file
├── variables.tf              # Variable definitions
├── outputs.tf               # Output definitions
├── terraform.tfvars         # Variable values
└── modules/
    └── dns/
        ├── main.tf          # Cloud DNS specific configurations
        ├── variables.tf      # Module variables
        ├── zones.tf         # DNS zone configurations
        └── outputs.tf       # Module outputs

Provider Configuration

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 4.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

Variables

variable "project_id" {
  description = "The ID of the GCP project"
  type        = string
}

variable "region" {
  description = "The region to deploy resources to"
  type        = string
  default     = "us-central1"
}

variable "dns_name" {
  description = "The DNS name for the zone"
  type        = string
}

DNS Zone Configuration

resource "google_dns_managed_zone" "public_zone" {
  name        = "public-zone"
  dns_name    = var.dns_name
  description = "Public DNS zone"

  labels = {
    environment = "production"
  }

  dnssec_config {
    state = "on"
  }
}

resource "google_dns_managed_zone" "private_zone" {
  name        = "private-zone"
  dns_name    = "internal.${var.dns_name}"
  description = "Private DNS zone"

  visibility = "private"

  private_visibility_config {
    networks {
      network_url = google_compute_network.vpc_network.id
    }
  }
}

DNS Record Sets

# A Record
resource "google_dns_record_set" "a_record" {
  name         = "www.${google_dns_managed_zone.public_zone.dns_name}"
  managed_zone = google_dns_managed_zone.public_zone.name
  type         = "A"
  ttl          = 300

  rrdatas = ["203.0.113.10"]
}

# CNAME Record
resource "google_dns_record_set" "cname_record" {
  name         = "blog.${google_dns_managed_zone.public_zone.dns_name}"
  managed_zone = google_dns_managed_zone.public_zone.name
  type         = "CNAME"
  ttl          = 300

  rrdatas = ["www.${google_dns_managed_zone.public_zone.dns_name}"]
}

# MX Record
resource "google_dns_record_set" "mx_record" {
  name         = google_dns_managed_zone.public_zone.dns_name
  managed_zone = google_dns_managed_zone.public_zone.name
  type         = "MX"
  ttl          = 3600

  rrdatas = [
    "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."
  ]
}

# TXT Record
resource "google_dns_record_set" "txt_record" {
  name         = google_dns_managed_zone.public_zone.dns_name
  managed_zone = google_dns_managed_zone.public_zone.name
  type         = "TXT"
  ttl          = 300

  rrdatas = ["\"v=spf1 include:_spf.google.com ~all\""]
}

DNSSEC Configuration

resource "google_dns_managed_zone" "dnssec_zone" {
  name        = "dnssec-zone"
  dns_name    = "secure.${var.dns_name}"
  description = "DNSSEC-enabled zone"

  dnssec_config {
    state = "on"
    default_key_specs {
      algorithm  = "rsasha256"
      key_length = 2048
      key_type   = "keySigning"
      kind       = "dns#dnsKeySpec"
    }
    default_key_specs {
      algorithm  = "rsasha256"
      key_length = 1024
      key_type   = "zoneSigning"
      kind       = "dns#dnsKeySpec"
    }
  }
}

Policy Configuration

resource "google_dns_policy" "default_policy" {
  name                      = "dns-policy"
  enable_inbound_forwarding = true
  enable_logging            = true

  networks {
    network_url = google_compute_network.vpc_network.id
  }

  alternative_name_server_config {
    target_name_servers {
      ipv4_address    = "8.8.8.8"
      forwarding_path = "default"
    }
    target_name_servers {
      ipv4_address    = "8.8.4.4"
      forwarding_path = "default"
    }
  }
}

Response Policy Zone

resource "google_dns_response_policy" "response_policy" {
  response_policy_name = "response-policy"

  networks {
    network_url = google_compute_network.vpc_network.id
  }
}

resource "google_dns_response_policy_rule" "response_policy_rule" {
  response_policy = google_dns_response_policy.response_policy.response_policy_name
  rule_name      = "block-malicious"
  dns_name       = "malicious.example.com."

  local_data {
    local_datas {
      name    = "malicious.example.com."
      type    = "A"
      ttl     = 300
      rrdatas = ["127.0.0.1"]
    }
  }
}

Outputs

output "public_zone_name_servers" {
  value       = google_dns_managed_zone.public_zone.name_servers
  description = "The name servers for the public zone"
}

output "private_zone_id" {
  value       = google_dns_managed_zone.private_zone.id
  description = "The ID of the private zone"
}

output "dnssec_zone_key_signing_key" {
  value       = google_dns_managed_zone.dnssec_zone.dnssec_config[0].default_key_specs[0]
  description = "The key signing key for the DNSSEC zone"
}

Best Practices

  1. Zone Management:

    • Plan hierarchy
    • Use DNSSEC
    • Monitor changes
    • Regular review
  2. Security:

    • Enable DNSSEC
    • Monitor access
    • Regular audits
    • Secure updates
  3. Performance:

    • Optimize TTLs
    • Monitor latency
    • Use CDN
    • Regular testing
  4. Cost Optimization:

    • Monitor queries
    • Optimize zones
    • Clean up unused
    • Regular review

Common Operations

Creating Resources

terraform init
terraform plan
terraform apply

DNS Operations

# Verify DNS records
dig @8.8.8.8 www.example.com

# Check DNSSEC
dig @8.8.8.8 example.com DNSKEY

Best Practices and Tips

  1. Zone Organization:

    • Clear naming
    • Document records
    • Regular review
    • Monitor changes
  2. Security:

    • Use DNSSEC
    • Monitor logs
    • Regular audits
    • Update records
  3. Operations:

    • Monitor performance
    • Track changes
    • Set up alerts
    • Regular maintenance

Conclusion

You’ve learned how to set up and manage Google Cloud DNS using Terraform. This setup provides:

  • Reliable DNS service
  • Security with DNSSEC
  • Performance optimization
  • Best practices implementation