Skip to content
All articles

Spanner & Terraform: Globally-Consistent SQL + Declarative IaC

Dean Jain

Dean Jain

Senior Staff Software Engineer · Enterprise AI, Data & Cloud Architect

· 5 min read

SpannerTerraformIaC
---
config:
  theme: dark
  fontSize: 17
  themeVariables:
    fontFamily: "Comic Sans MS, Comic Neue, Chalkboard SE, cursive"
---
flowchart LR
    subgraph SP["🌍 Cloud Spanner"]
        direction LR
        TT["⏱️ TrueTime<br/>atomic clocks + GPS"]:::gate --> SC["✅ Strong consistency<br/>at global scale"]:::good
    end
    subgraph TF["🏗️ Terraform"]
        direction LR
        DS["📜 Declared desired state"]:::gate --> REC["✅ System reconciles<br/>the infrastructure"]:::good
    end
    classDef gate fill:#D7C3F2,stroke:#8E5BD0,stroke-width:2px,color:#0F172A
    classDef good fill:#BFEFC8,stroke:#3FA34D,stroke-width:2px,color:#0F172A

Figure 1: Two declarative wins Spanner reconciles global consistency via synchronized clocks; Terraform reconciles infrastructure to a declared state.

Two technologies, one underlying idea. Cloud Spanner breaks a rule everyone learned that you can’t have horizontally-scalable SQL and strong consistency across the globe using synchronized atomic clocks. Terraform breaks the habit of clicking through consoles by letting you describe the infrastructure you want and having the system make it real. Different domains, same move: replace imperative, manual work with a declarative source of truth the system reconciles. Here’s how each pulls it off, and why the pattern is worth internalizing.

Summary

  • Spanner is horizontally-scalable, strongly-consistent SQL petabytes, global multi-region, full ACID transactions, 99.999% availability. The “impossible” combination.
  • The trick is TrueTime. Atomic clocks + GPS give every node a tightly-bounded view of “now,” so Spanner can order transactions globally without sacrificing strong consistency.
  • It replicates three ways read-write, read-only, and witness replicas so it survives regional loss while staying consistent.
  • Terraform is declarative IaC. You write the desired state in HCL; Terraform figures out how to reach it. You stop scripting steps.
  • Declarative buys you idempotence + a single source of truth. Apply the same code any number of times and converge on the same state auditable before it ever runs.

1. Spanner: the RDBMS that shouldn’t exist

For decades the trade was iron-clad: relational databases give you strong consistency but scale up (one big box); NoSQL scales out but you give up consistency. Cloud Spanner refuses the trade it’s Google’s globally-distributed RDBMS that scales horizontally to petabytes while staying strongly consistent, with full ACID atomic transactions, 10,000+ reads/writes, and 99.999% availability across regions.

How? The hard part of horizontal SQL with strong consistency is that nodes must agree on the order of transactions, which requires agreeing on time and ordinary server clocks drift. Spanner’s answer is TrueTime: a service backed by atomic clocks and GPS in every datacenter that gives each node not a single timestamp but a tightly-bounded interval of the current time. Because the uncertainty is small and known, Spanner can wait out that interval and guarantee a global ordering of commits. Synchronized physical time is the unlock it turns “which write happened first?” from a distributed-consensus nightmare into a clock reading.

That’s the whole insight: Spanner didn’t beat the CAP-theorem trade-offs with cleverer software alone it changed the physics available to the software by engineering time itself into the datacenter.

2. How Spanner stays available and consistent

Strong consistency is only useful if the database is also up. Spanner replicates data automatically across regions in three replica roles:

---
config:
  theme: dark
  fontSize: 17
  themeVariables:
    fontFamily: "Comic Sans MS, Comic Neue, Chalkboard SE, cursive"
---
flowchart TB
    L["✍️ Read-write replica<br/>(handles writes)"]:::server
    L --> RO["📖 Read-only replica<br/>(serves reads)"]:::obs
    L --> W["🗳️ Witness replica<br/>(votes, no full data)"]:::neutral
    TT["⏱️ TrueTime orders every commit"]:::gate -.-> L
    classDef server fill:#A8E6D0,stroke:#2FA37C,stroke-width:2px,color:#0F172A
    classDef obs fill:#AED6F1,stroke:#2E86C1,stroke-width:2px,color:#0F172A
    classDef neutral fill:#ECECEC,stroke:#8A8A8A,stroke-width:2px,color:#0F172A
    classDef gate fill:#D7C3F2,stroke:#8E5BD0,stroke-width:2px,color:#0F172A

Figure 2: Spanner's three replica roles read-write, read-only, and witness keep it available through regional loss while TrueTime keeps it consistent.

  • Read-write replicas take writes; read-only replicas scale out reads; witness replicas hold no full data but participate in voting to maintain quorum cheaply. Lose a region and the database stays both writable and consistent.

Pricing is straightforward and worth knowing up front: you pay for data nodes (hourly) plus storage plus egress the cost of always-on, globally-replicated capacity.

Spanner has also grown well beyond classic SQL, which matters when you’re deciding whether it can be your one database:

  • Analytics bridges change streams (CDC) into BigQuery, federated joins against BigQuery tables, and reverse ETL from BigQuery back into Spanner.
  • Operational control configurable read-only replicas, fine-grained access control, and scheduled backups.
  • A widening surface Google keeps folding new workloads into Spanner (graph, vector, and search capabilities are on its public trajectory), aiming to make it a single consistent home for more than classic SQL.

The takeaway: Spanner is steadily becoming a single, globally-consistent home for more than transactions not just a scalable SQL box.

3. Terraform: describe the infra, don’t build it

Now the other half. Infrastructure as Code (IaC) treats infrastructure VMs, networks, storage, IAM as machine-readable definition files instead of console clicks. Terraform (HashiCorp) is the popular declarative IaC tool: you author your desired resources in HCL (HashiCorp Configuration Language), and Terraform provisions them across almost any provider (GCP, AWS, GitHub, Docker, …).

The keyword is declarative you describe the desired state, not the steps to get there. That single property cascades into the benefits that make IaC worth it:

  • Simplicity focus on what you want, not how it’s achieved.
  • Idempotence apply the same code any number of times and the infrastructure converges to the same state; re-running is safe.
  • Change management diffs to the desired state are easy to read and review.
  • Auditability & compliance static analysis can flag policy violations before anything is applied.
  • Single Source of Truth the code is authoritative; if reality drifts, you re-apply to bring it back.

The workflow is a tight loop:

---
config:
  theme: dark
  fontSize: 17
  themeVariables:
    fontFamily: "Comic Sans MS, Comic Neue, Chalkboard SE, cursive"
---
flowchart LR
    SC["🔍 Scope<br/>what's needed"]:::gov --> AU["✍️ Author<br/>HCL files"]:::obs
    AU --> IN["⚙️ Init<br/>get providers"]:::gate
    IN --> PL["📋 Plan<br/>preview changes"]:::warn
    PL --> AP["🚀 Apply<br/>create + write state"]:::good
    AP -.->|"state file = source of truth<br/>compares future changes"| PL
    classDef gov fill:#E0D6F5,stroke:#9B7EDE,stroke-width:2px,color:#0F172A
    classDef obs fill:#AED6F1,stroke:#2E86C1,stroke-width:2px,color:#0F172A
    classDef gate fill:#D7C3F2,stroke:#8E5BD0,stroke-width:2px,color:#0F172A
    classDef warn fill:#FFE6A8,stroke:#E0A106,stroke-width:2px,color:#0F172A
    classDef good fill:#BFEFC8,stroke:#3FA34D,stroke-width:2px,color:#0F172A

Figure 3: The Terraform loop scope, author, init, plan, apply; the state file becomes the source of truth for future diffs.

terraform plan previews exactly what will change before you commit; terraform apply makes it real and records a state file that future runs diff against. That plan-before-apply step is the heart of safe infra changes you see the blast radius before anything happens.

The common thread

Spanner and Terraform live in different worlds, but they win the same way. In both, you declare the desired end state a globally-consistent set of committed transactions, or a desired set of cloud resources and the system does the reconciling. You stop managing the how (clock coordination, API call sequences) and own only the what. That’s the same declarative shift that makes Kubernetes and SQL itself powerful, and it’s a pattern worth reaching for: describe the destination, let the system find the path.

Why it matters: Spanner is the tool to reach for when you genuinely need strong consistency at global scale and don’t want to hand-roll sharding and consensus its TrueTime trick is doing work that would otherwise be your problem. Terraform is the tool to make infrastructure reproducible, reviewable, and idempotent instead of a pile of undocumented console clicks. Both pay off most when you commit fully to the declarative model one source of truth, reconciled rather than mixing in manual changes that drift.

References