DNS Setup in Google Cloud: Public and Private Zones with DNSSEC
When your project's domain starts resolving through Google Cloud infrastructure, the first question is how to manage DNS. You can manually edit records at the registrar, but as you scale, this becomes chaotic. We use Google Cloud DNS — a managed service with 100% uptime SLA that is easily automated via Terraform and external-dns. Cloud DNS integrates tightly with VPC, GKE, and other services. Public zones serve external users; private zones only handle internal requests. For infrastructure on Google Cloud, this is the natural choice: no need to stand up your own NS servers — full control through a unified API. For example, during a SaaS project migration, we moved 50 domains in one day with Terraform, and external-dns automatically syncs records with Kubernetes.
In this article, we'll cover how to set up public and private zones, enable DNSSEC, and automate record updates via external-dns. We'll provide ready-to-use Terraform modules and a real-world case with numbers.
Benefits of Google Cloud DNS
Cloud DNS integrates tightly with VPC, GKE, and other Google Cloud services. Public zones serve external users; private zones only handle internal requests. For infrastructure on GCP, this is the natural choice: no need to stand up your own NS servers — full control through a unified API.
Public Zone
For an external domain, create a public zone and enable DNSSEC:
resource "google_dns_managed_zone" "public" {
project = var.project_id
name = "example-com"
dns_name = "example.com."
description = "Public DNS zone"
dnssec_config {
state = "on"
}
}
resource "google_dns_record_set" "api" {
project = var.project_id
managed_zone = google_dns_managed_zone.public.name
name = "api.example.com."
type = "A"
ttl = 300
rrdatas = [google_compute_global_address.lb.address]
}
# MX records for email
resource "google_dns_record_set" "mx" {
project = var.project_id
managed_zone = google_dns_managed_zone.public.name
name = "example.com."
type = "MX"
ttl = 3600
rrdatas = [
"1 aspmx.l.google.com.",
"5 alt1.aspmx.l.google.com.",
]
}Google Cloud DNS documentation
After creating the zone, you must update the NS records at your domain registrar to the nameservers provided by Cloud DNS (typically ns-cloud-{a-d}1.googledomains.com). This ensures your domain resolves through Google.
How to set up a private zone for internal services?
Internal services — databases, message brokers, APIs — are better addressed by DNS rather than by IP. A private zone is only visible inside your VPC:
resource "google_dns_managed_zone" "private" {
project = var.project_id
name = "internal-example-com"
dns_name = "internal.example.com."
description = "Private DNS for VPC"
visibility = "private"
private_visibility_config {
networks {
network_url = var.vpc_self_link
}
}
}
resource "google_dns_record_set" "postgres" {
project = var.project_id
managed_zone = google_dns_managed_zone.private.name
name = "postgres.internal.example.com."
type = "A"
ttl = 60
rrdatas = [google_sql_database_instance.main.private_ip_address]
}Private zones are only visible from within the VPC. Applications use postgres.internal.example.com instead of an IP — during failover or migration, you only change the DNS record, not the configuration of all services.
What is DNSSEC and why do you need it?
DNSSEC protects public zones from DNS spoofing. After enabling, Cloud DNS automatically signs the zone. You need to add a DS record to the parent zone (at your registrar). To obtain the DS record, run:
# Get DS record for registrar
gcloud dns dns-keys list \
--zone=example-com \
--filter="type=keySigning" \
--format="value(dsRecord)"This procedure takes about 10 minutes and provides protection against DNS response spoofing. We recommend enabling it for all public zones.
How to verify DNSSEC works?
Use the `dnssec-verify` tool or online services like the DNSSEC debugger from Verisign. If the DS record is correctly added, the check will show a green status.Comparison of public and private zones
| Characteristic | Public Zone | Private Zone |
|---|---|---|
| Accessibility | Entire internet | Only inside VPC |
| DNSSEC | Supported | Not required (disabled by default) |
| Integration with external-dns | For Ingress/Service LoadBalancer | For internal services (ClusterIP, Headless) |
| Typical TTL | 300–3600 sec | 60–300 sec |
| Scenario | example.com, api.example.com | db.internal.example.com, kafka.internal.example.com |
Typical DNS records and their purpose
| Record Type | Purpose | Example TTL |
|---|---|---|
| A | IPv4 address | 300 |
| AAAA | IPv6 address | 300 |
| CNAME | Alias (canonical name) | 600 |
| MX | Mail server | 3600 |
| TXT | Text data (SPF, DKIM) | 3600 |
| SRV | Service records | 300 |
Case: DNS migration to GCP for a SaaS project
From our practice: a client (SaaS company) had the domain mysaas.com, which was previously managed at an external registrar. Manual record updates during deployments took 30 minutes and often led to errors. We set up a public zone in Cloud DNS, migrated all existing records (A, CNAME, MX, TXT) via Terraform, enabled DNSSEC. For internal communication — a private zone internal.mysaas.com, adding records for PostgreSQL and Redis. external-dns in GKE automatically created records for new microservices. Result: DNS update time during deployments dropped from 30 minutes to 3 seconds (external-dns sync).
Process of work
- Analysis: which domains you use, which records are needed, whether DNSSEC is available at the registrar.
- Design: zone architecture (public/private), subnet scheme for private zones.
- Implementation: Terraform code, import existing records, configure external-dns.
- Testing: verify resolution, DNSSEC operation (dnssec-verify), failover.
- Deployment: update NS records at registrar, monitor via Cloud Monitoring + Grafana.
Estimated timelines
- Public zone with DNSSEC and basic records: from 4 hours.
- Private zone with external-dns integration for GKE: from 1 day.
- Complex setup (migration of all zones + automation): from 3 days.
What is included in the work
- Creation of public and private zones with required records (A, AAAA, CNAME, MX, TXT, SRV).
- Enabling DNSSEC and public audit of signatures.
- Setting up external-dns for Kubernetes (GKE).
- Terraform modules for managing zones as code.
- Documentation: DNS schema, instructions for adding records, incident runbook.
- Training your team to work with Cloud DNS.
- Support for 2 weeks after deployment.
Why trust us
We have 5 years of experience in DevOps and SRE, with over 20 successful projects migrating DNS to GCP. Our engineers hold Google Cloud Professional DevOps Engineer certifications. We guarantee stability: all changes go through code review and test zones.
We are ready to discuss your project. Contact us for a consultation. Order Google Cloud DNS setup and get transparent DNS management without headaches.







