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
-
Zone Management:
- Plan hierarchy
- Use DNSSEC
- Monitor changes
- Regular review
-
Security:
- Enable DNSSEC
- Monitor access
- Regular audits
- Secure updates
-
Performance:
- Optimize TTLs
- Monitor latency
- Use CDN
- Regular testing
-
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
-
Zone Organization:
- Clear naming
- Document records
- Regular review
- Monitor changes
-
Security:
- Use DNSSEC
- Monitor logs
- Regular audits
- Update records
-
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