Skip to content
advanced Phase 13 · Multi-Cloud and Provider Composition Patterns

Multi-Cloud Design Tradeoffs

Evaluating when multi-cloud IaC adds resilience and when it only adds complexity.

50m
0 problems
Topic Progress 0%

Counting What Doubles: The Real Bill for Two Active Networks

An architecture review proposes "active-active across AWS and GCP" for 99.99% availability. Your job in the room is to name what actually doubles — not the slide, the bill and the 3 a.m. page. This topic follows Abstraction Modules Across Clouds, which showed you how to hide a second provider; here we ask whether the second provider deserves to exist.

Nothing about the diagram is free. Two active networks means two of almost everything you operate:

Concern One cloud Two active clouds
CI matrix 3 envs × 1 provider = 3 plan jobs 6 plan jobs + 2 interconnect checks + doubled integration runs
Identity one IAM model, one OIDC trust two IAM models, two sets of trust policies, two break-glass procedures
Networking VPC + free regional peering Direct Connect and ExpressRoute, BGP sessions, failover routing
Observability one telemetry pipeline two pipelines, or a broker — plus correlation across two trace ID spaces
DNS / failover TTL-based regional routing health checks per provider, split-horizon records, tested cutover
Modules & tests one implementation two implementations per module, doubled assertion matrix
Debugging one world to inspect our code, cloud A, the interconnect, or cloud B

The last row is the answer interviewers want, and the one that costs the most. In a single-cloud incident your hypothesis space has one layer. In a two-cloud incident every symptom gains three candidate causes, runbooks fork into two versions, and your responders need fluency in both consoles. Mean time to recovery grows even when nothing else does — and availability math says a more probable failure mode than "AWS had a regional outage" is "our failover logic had a bug we tested quarterly."

The money column deserves real numbers:

Cost line Single cloud, 3 AZ Two clouds, active-active
Compute (equivalent workload) ~$3,200/mo ~$3,400/mo — the second provider's markup is small
Cross-network transport $0 (internal traffic) 1 Gbps Direct Connect ≈ $220/mo + 1 Gbps ExpressRoute ≈ $400/mo + cross-connect fees
Egress between clouds $0 $0.05–0.09/GB; a 5 TB/month hot path ≈ $250–$450/mo
Pipeline + test runs 1 matrix 2 matrices, ~2× runner minutes, ~2× sandbox spend
Operations one on-call rotation, one runbook set two rotations to staff, doubled drills

Typical total: 40–80% higher infrastructure spend plus a second on-call runbook, before counting the engineering months. And the latency math constrains the design at the same time: same-region cross-AZ round trips run well under a millisecond, interconnect between clouds adds single-digit milliseconds, and the public internet path runs 20–60 ms — which is why these designs serve failover, not hot paths, a point established when wiring resources across providers.

Now compare against the honest alternative. One cloud with three availability zones, a warm multi-region standby, load balancers with health checks across zones, and managed services with availability SLAs lands at 99.95–99.99% for a fraction of that bill, with one IAM model and one debugging world. Single-cloud with strong redundancy usually wins on availability per dollar — the second cloud buys resilience you already bought regionally, then taxes you for operating it.

None of this says "never." It says: in the review, refuse to approve a two-cloud design whose justification slide says "resilience." Push for the failure mode, the number, and the owner of the second runbook — and if those exist, the next chapter covers which reasons survive that interrogation.

Four Reasons That Justify a Second Cloud (and Four That Don't)

"We should go multi-cloud" is a preference until it names the failure mode it protects against and the monthly price of that protection. Most proposals fail that sentence. Run every justification through this table before any architecture work starts.

Proposed reason Verdict The reasoning you should give
"Avoid vendor lock-in" usually no You pay daily for an exit you may never take. Buy exit insurance where exits happen: open data formats, scheduled exports, a restore rehearsed into a second account. A second production network is a very expensive insurance policy with a low claim rate.
Regulatory data residency yes, sometimes If law requires data to remain in a jurisdiction where your primary provider has no in-region offering, the second provider is a requirement, not a preference. Encode residency as a policy rule so it stays true.
Acquisition yes, deliberately The acquired company runs on Azure with audits already certified. Ripping it out and re-certifying costs more than integrating it. Standardize over quarters — shared pipelines first, shared clouds last.
Best-of-breed capability yes, consciously One provider's analytics engine or GPU instances are core to the product. Accept the integration cost with eyes open, and isolate that dependency behind the contract from Abstraction Modules Across Clouds.
Customer contract yes, priced An enterprise customer mandates provider diversity or in-country operation. That is a cost of sale — put it in the contract's price, not silently in the platform backlog.
Negotiating leverage rarely Leverage requires real spend and credible migration readiness. Twenty services and a demo environment do not move a vendor's pricing desk; fifty million dollars of committed volume might.
Bargain credits no Credits expire in 12–24 months; the architecture does not. Never design for a coupon.
"Our engineers prefer it" no Preference is not a requirement. Route it through tooling choices, not duplicated production networks.

The interview version of this skill is a question you ask back: "What is the failure you are protecting against, and what does the protection cost per month?" Candidates who can only quote SLA percentages have not done the analysis; candidates who answer "AWS outage takes us down — we measured a 4-hour regional event as $900k, and the second cloud costs $7k/month plus two engineering quarters" have. Note that this frame also handles the true positive: residency and acquisition requirements survive the interrogation precisely because they name concrete, non-hypothetical constraints.

Sequencing matters as much as the verdict. Adding a second cloud after 200 services exist means re-implementing modules, splitting state, forking pipelines, and retraining responders — an order of magnitude more expensive than deciding at service number ten. But deferring is still a decision, and undocumented decisions get relitigated every reorg. Write an Architecture Decision Record: the reasons considered, the verdict, the price of the rejected option, and a review date. When the acquisition closes or the residency rule lands, the ADR shows the trigger you were waiting for instead of looking like nobody thought about it.

One more cost that never appears in the initial proposal: optionality decay. A second cloud kept idle — a passive standby with real resources — generates bills without generating evidence that failover works, because nobody exercises it. If you keep the second network, budget the quarterly failover drill alongside it. An untested second cloud is not resilience; it is a duplicate that has never been asked to do anything.

Verdict in hand, the remaining decision is mechanical but unforgiving: where the state lives. Get that wrong and even a well-justified design becomes surgery later.

Deciding State Boundaries Before the First Resource Spans Two Clouds

Two teams once stood up one Terraform state for a workload spanning AWS and Azure. Six months later the split had to happen for blast-radius reasons — and it took a maintenance window, three engineers, terraform state pull with hand-edited JSON, and an import pass for the resources whose addresses moved. The design question this illustrates is not technical preference: state partitioning must be decided before the first resource spans providers, because retrofitting it is surgery on your single source of truth.

Four strategies, with what each actually buys:

Strategy Cross-cloud atomic plan Blast radius Pipeline shape Cost of adopting it later
One state, both clouds yes — one graph orders everything the entire estate one lock, one huge plan, constant lock contention very high: state must be split
State per cloud no — wiring goes through lookups one cloud two backends, two pipelines medium: add backend, move half the addresses
State per service × environment no one service in one env many small states, parallel-safe low — this is where you should start
State per team-owned domain partial a domain one state per owning team medium: needs ownership map first

The atomic-plan column is the seductive one. A single state lets a plan order an Azure private endpoint after the AWS-side DNS record it depends on, and no data source is involved. You pay for that with the blast radius: a corrupted or mis-targeted plan touches everything, one lock serializes every engineer, and the plan output for a 400-resource cross-cloud graph is a document nobody reviews carefully — which defeats the purpose of gating on plans.

Wiring across state boundaries has three forms, ordered from tightest to loosest coupling. terraform_remote_state reads another state directly: convenient, but it couples the reader to the writer's backend permissions and schema. Data source lookups — reading a DNS zone, a parameter store, a resource attribute by name — decouple the two states; ordering becomes eventual rather than graph-enforced, which is the correct semantics for a failover relationship. Using the network itself (queues, databases, global DNS) as the integration point is loosest and most realistic: these clouds are supposed to survive each other's absence, so a hard reference to the other cloud's state backend contradicts the goal.

Backend and lock choices follow the partition. Each state gets its own backend and its own lock resource — an S3 bucket with a DynamoDB LockID table, an Azure storage account with blob lease — so two pipelines can never contend across partitions:

terraform {
  backend "s3" {
    bucket         = "corp-tfstate-platform"
    key            = "services/payments/prod/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "corp-tfstate-locks"
    encrypt        = true
  }
}

Locks do not span states, which is the point: a stuck run in staging-network must not block prod-app. Keep each state's backend inside a platform-controlled account, and mirror periodic state pull snapshots to the other cloud's object store: if the partition exists for outage resilience, your ability to rebuild it cannot live entirely in the cloud you are recovering from.

Then the retrofit cost, concretely, because this is where the interview answer separates from the résumé answer. Splitting one state means terraform init -migrate-state to relocate a whole state, or state pull → partition the JSON by address → state push into new backends, then re-point every output and data source that crossed the old boundary, then verify with a no-op plan in each partition. Every step has a failure mode where a resource ends up in two states — which produces a later apply that destroys a resource another state believes it owns. Weeks of work, done under a freeze, versus an hour of decision at day zero.

Decide the partition table the same week you choose the backend. With that settled, the roadmap moves into verification: The Native terraform test Framework.

Quiz

1. Which cost line exists in a two-cloud active-active design but is zero in a single-cloud multi-AZ design?

Question 1 options

2. Leadership proposes multi-cloud solely to avoid vendor lock-in, and nobody can name an exit scenario. What is the cheapest credible insurance?

Question 2 options

3. Under what condition does regulation justify choosing a second provider?

Question 3 options

4. When must the state partitioning strategy for a design spanning two providers be decided?

Question 4 options

Flashcards

Question

What doubles when you operate two active clouds, and which item hurts most?

Answer

CI matrices, identity models, network interconnects, observability pipelines, module implementations, runbooks — and the debugging hypothesis space. The last hurts most: every symptom now has four candidate causes (our code, cloud A, the interconnect, cloud B), so mean time to recovery grows even when nothing else fails.

Question

Which single-cloud design usually beats multi-cloud on availability per dollar?

Answer

Three availability zones with cross-zone load balancing, a warm multi-region standby, health-checked failover, and managed services with availability SLAs — delivering roughly 99.95 to 99.99 percent for a fraction of a second network's cost, with one IAM model and one debugging world.

Question

Name the reasons that justify a second cloud and the two that most often don't.

Answer

Justified: regulatory residency where the primary has no region, an acquisition already certified elsewhere, a customer contract mandating diversity, or a product-critical best-of-breed capability priced consciously. Usually not: vague lock-in fear and negotiating leverage you lack the volume to exercise.

Question

Trade-off between one shared state spanning both clouds and a state per cloud.

Answer

One state gives atomic cross-cloud plans but concentrates blast radius, serializes every engineer on one lock, and produces reviews nobody reads. Per-cloud states shrink blast radius and let pipelines run independently, at the cost of graph ordering across the boundary — replaced by lookups or eventual wiring.

Question

How do you wire across state boundaries, ordered from tightest to loosest coupling?

Answer

terraform_remote_state (couples reader to the writer's backend permissions), data source lookups (decoupled, eventual ordering), and the network itself — queues, databases, global DNS (loosest, and correct for designs meant to survive the other cloud's absence).

Revision Notes

Key Takeaways

  • 1. Two active networks double pipelines, identity, observability, and above all the debugging hypothesis space — MTTR grows even when nothing else does
  • 2. Single-cloud with three AZs plus a warm multi-region standby usually wins availability per dollar; the second cloud taxes you monthly for resilience you partly bought already
  • 3. Justifications split into requirements (residency, acquisition, contract) and preferences (lock-in fear, leverage, credits) — only requirements survive the cost question
  • 4. State partitioning must be decided before the first apply spans providers; splitting later is pull/partition/push surgery under a freeze with double-ownership failure modes
  • 5. Cross-cloud latency and egress make the second network a failover asset, not a hot-path participant — design the wiring to tolerate the other cloud being gone

Interview Tips

  • • "When would you recommend multi-cloud?" — answer with the requirement categories (residency, acquisition, contract, priced best-of-breed) and then ask the counter-question: what failure are you protecting against, and what does it cost monthly?
  • • "Our CTO wants active-active across two clouds for availability — what do you say?" — walk the doubled table, name MTTR as the hidden cost, and propose single-cloud multi-AZ plus a warm standby with the numbers
  • • "How would you split Terraform state across two providers?" — decide before the first cross-provider apply, prefer per-service-per-environment states, and wire with lookups or the network, not hard remote-state references
  • • "You inherited one state spanning AWS and Azure — what now?" — describe the surgery honestly: state pull, partition by address, push to new backends, re-point outputs, verify with no-op plans, and watch for resources claimed by two states

Cheat Sheet

Multi-Cloud Design Tradeoffs

What doubles (active-active, two providers):

Area Single cloud Two clouds
CI 3 plan jobs 6 plans + 2 interconnect checks + doubled integration
Identity one IAM model + OIDC trust two models, two trust configs, two break-glass paths
Network VPC + free regional peering Direct Connect ~$220/mo + ExpressRoute ~$400/mo + BGP
Egress between clouds $0 internal $0.05-0.09/GB; 5 TB hot path ≈ $250-450/mo
Debugging one world our code, cloud A, interconnect, or cloud B → MTTR grows

Decision question: What failure am I protecting against, and what does the protection cost per month? Write both numbers or it is a preference.

Verdict table: residency / acquisition / contract / priced best-of-breed → yes; lock-in fear / leverage / credits / engineer preference → no. Record deferred verdicts in an ADR with a review date.

State partitioning — decide before the first cross-provider apply:

Strategy Atomic cross-cloud plan Blast radius Retrofit cost
One state yes entire estate very high (state surgery)
Per cloud no one cloud medium
Per service × env no one service low — start here

Wiring across states: terraform_remote_state (tight) → data source lookups (decoupled) → the network itself (correct for failover).

Latency rule: same-AZ sub-ms, interconnect single-digit ms, public internet 20-60 ms — second cloud serves failover, not hot paths.

Continue Learning