
August 29, 2026
14 min read
Table of Contents
By Kokil Thapa | Last reviewed: August 2026
Most teams do not wake up wanting three cloud bills. They arrive at Multi-Cloud Architecture: A Practical Guide territory after a merger, a compliance requirement, a vendor outage, or a client contract that mandates a specific provider. Running a Laravel app on one EC2 instance is straightforward; running production workloads across AWS, Azure, and Google Cloud is a different engineering problem — one where networking, identity, observability, and cost control matter more than which logo sits on the invoice. If you are evaluating whether multi-cloud is worth the operational tax, or you already committed and need a sane blueprint, this guide walks through the decisions I make on real client projects — not the slide-deck version vendors sell at conferences. For foundational automation patterns, see the Terraform infrastructure-as-code practical guide first; multi-cloud builds on the same discipline.
What is multi-cloud architecture and when should you actually use it?
Multi-cloud architecture means your production system spans more than one public cloud provider. That is different from hybrid cloud (on-premises plus one public cloud) and different from multi-region (same provider, multiple regions). A Nepali SaaS might keep its primary Laravel API on AWS in ap-south-1 (Mumbai) for latency, run analytics on BigQuery in GCP because the team already knows SQL-based warehousing, and host a Microsoft Teams-integrated reporting module on Azure because the enterprise client mandates it. Each choice has a reason; without reasons, you are paying complexity interest for no return.
In practice, I see four legitimate triggers:
- Vendor resilience: A regional or provider-wide outage should not take your entire business offline. Payment callbacks, booking confirmations, and client portals for law firms cannot sit on a single failure domain if uptime is contractual.
- Compliance and data residency: Some contracts require data to stay in specific jurisdictions. Nepal-based businesses serving EU clients may need GDPR-aligned storage; a government-adjacent portal may require audit trails on a provider the procurement team already approved.
- Best-of-breed services: Route 53 health checks, CloudFront CDN, Azure AD B2C, GCP Vertex AI — no single vendor wins every category. Multi-cloud lets you pick the tool, not the ecosystem.
- Acquisition or partner integration: Post-merger systems rarely share one cloud account on day one. Multi-cloud is sometimes the interim architecture until you consolidate — and sometimes the permanent one.
A common mistake is treating multi-cloud as an insurance policy you buy before you need it. If your team is three developers maintaining a WooCommerce store and a shared VPS, multi-cloud is almost certainly wrong. If you operate booking systems, payment integrations, and client portals where downtime costs real money, selective multi-cloud — one primary provider plus a warm standby elsewhere — can be rational. The decision tree is simple: list the business requirement first, then map the minimum cloud footprint that satisfies it.
How do you design a multi-cloud architecture for web applications?
Start with workload placement, not provider logos. I classify every component into one of four tiers before drawing architecture diagrams:
- Tier 0 — Stateless edge: CDN, WAF, DNS, TLS termination. CloudFront, Cloudflare, or Azure Front Door can front any origin regardless of where the app runs.
- Tier 1 — Application compute: Laravel on EC2, App Service, or GKE. Keep this stateless; session data belongs in Redis, not local disk.
- Tier 2 — Data stores: MySQL 8.0, PostgreSQL 16/17, Redis 7.x. This is where multi-cloud gets expensive. Avoid active-active databases across providers unless you have a dedicated data team.
- Tier 3 — Async and integrations: Queues, webhooks, scheduled jobs, third-party APIs (eSewa, Khalti, Stripe). These tolerate brief cross-cloud latency better than synchronous reads.
Reference pattern for a Laravel production stack
On a production Laravel application I might deploy like this:
- Primary (AWS): EC2 or ECS Fargate running PHP 8.3/8.4, RDS MySQL 8.0, ElastiCache Redis 7.x, S3 for uploads, SQS for queue workers via Laravel Horizon.
- Secondary (GCP or Azure): Read-only replica or warm standby with Terraform-managed identical infrastructure. Deploy the same container image or Git artefact both places.
- Shared services: Cloudflare for DNS and DDoS protection (provider-agnostic), GitLab CI for build pipelines, and a single secrets manager strategy — either HashiCorp Vault or provider-native vaults synced through an external-secrets pattern.
The application code stays identical. Environment-specific values live in .env per cloud, injected at deploy time — never hard-coded provider endpoints in PHP source. I have seen Laravel apps break after a failover because AWS_URL was baked into a config cache from the wrong region. Run php artisan config:clear as part of every failover runbook step.
Infrastructure as code across providers
Do not click-create resources in three consoles. Use Terraform (or OpenTofu) with separate provider blocks and a disciplined state strategy. The guide to managing multi-cloud Terraform state covers remote backends; the short version: one state file per logical stack per environment, stored in a cloud-neutral backend (Terraform Cloud, GitLab-managed state, or S3 with strict locking), never local terraform.tfstate on a laptop.
# main.tf — multi-provider root module (Terraform 1.9+)
terraform {
required_version = ">= 1.9"
backend "s3" {
bucket = "company-terraform-state"
key = "prod/multi-cloud/terraform.tfstate"
region = "ap-south-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
provider "aws" {
region = var.aws_region
}
provider "azurerm" {
features {}
subscription_id = var.azure_subscription_id
}
provider "google" {
project = var.gcp_project_id
region = var.gcp_region
}
module "aws_app" {
source = "./modules/laravel-ec2"
env = var.environment
}
module "azure_standby" {
source = "./modules/laravel-app-service"
env = var.environment
} Pin provider versions explicitly. A silent azurerm major upgrade during terraform plan on a Friday has ended more weekends than I care to count. Commit .terraform.lock.hcl and review provider bumps like application dependency updates.
Single cloud vs multi-cloud vs hybrid cloud — which fits your team?
Teams debate this in abstract terms. The trade-off is operational surface area versus flexibility. Here is how I compare them for web applications in 2026:
| Criteria | Single cloud | Multi-cloud | Hybrid (on-prem + cloud) |
|---|---|---|---|
| Operational complexity | Low — one console, one IAM model | High — three IAM models, three billing APIs | Medium-high — datacenter plus cloud |
| Vendor lock-in risk | Higher for proprietary services (DynamoDB, Cosmos DB) | Lower if you stick to portable primitives (K8s, Postgres, S3-compatible storage) | Varies — legacy apps often stuck on-prem |
| Disaster recovery | Multi-region within one provider (simpler) | Cross-provider failover (harder, slower DNS cutover) | Depends on link quality and replication |
| Cost predictability | Easier with reserved instances / savings plans | Harder — egress between clouds adds up fast | CapEx for hardware plus cloud OpEx |
| Best for | Startups, SMBs, most Laravel/WooCommerce sites | Regulated industries, enterprise contracts, DR mandates | Legacy ERP, banks, orgs with existing datacenters |
| Team size floor | 1 developer with DevOps basics | 2+ engineers with dedicated infra ownership | IT ops team plus cloud skills |
Verdict: default to single cloud with multi-region until a written requirement forces you elsewhere. For most Nepali businesses — law firm portals, eCommerce stores, booking systems — AWS or DigitalOcean in one region with off-site S3 backups and Cloudflare in front covers 95% of resilience needs at a fraction of multi-cloud cost. Multi-cloud earns its keep when the requirement is contractual, not aspirational.
How do you connect AWS, Azure, and GCP in a multi-cloud network?
Public internet between your databases is not a design; it is a incident waiting for a compliance audit. Cross-cloud connectivity falls into three patterns, ordered by complexity:
1. Site-to-site VPN (start here)
Connect AWS VPC to Azure VNet or GCP VPC using IPsec VPN tunnels. Latency adds 2–10 ms depending on region pairs; throughput caps around 1.25 Gbps per tunnel on AWS VGW unless you upgrade to Direct Connect / ExpressRoute. For a Laravel app replicating read traffic or syncing nightly backups, VPN is usually enough. The AWS-to-GCP networking and VPN setup guide walks through tunnel configuration; the same principles apply to Azure with Local Network Gateway resources.
# AWS side — aws_vpn_connection (simplified)
resource "aws_customer_gateway" "peer" {
bgp_asn = 65000
ip_address = var.peer_public_ip
type = "ipsec.1"
}
resource "aws_vpn_connection" "to_azure" {
customer_gateway_id = aws_customer_gateway.peer.id
type = "ipsec.1"
static_routes_only = true
vpn_gateway_id = aws_vpn_gateway.main.id
} 2. Private interconnect (when VPN bandwidth is not enough)
AWS Direct Connect, Azure ExpressRoute, and Google Cloud Interconnect provide dedicated links. Useful for large data replication or real-time analytics pipelines. Cost starts around USD 300–500/month per port before cross-connect fees — roughly Rs 40,000–65,000/month — which is steep for a small SaaS but reasonable for a data-heavy platform.
3. Overlay network with a service mesh or CNI (advanced)
Tools like Cilium Cluster Mesh or Tailscale/WireGuard overlays let pods in GKE talk to pods in EKS without exposing services publicly. This is Kubernetes-native multi-cloud. If you are running plain PHP-FPM on EC2, skip this layer entirely.
DNS is the other half of networking. Use a provider-agnostic DNS service — Cloudflare or Route 53 with health checks — to fail over between origins. Set low TTL (60–300 seconds) on production records you might switch during an incident, but not so low that you amplify query load during normal operation.
What are the hardest operational problems in multi-cloud architecture?
Multi-cloud fails in operations long before it fails in architecture diagrams. These are the problems I troubleshoot repeatedly:
Identity and access management sprawl
AWS IAM roles, Azure RBAC, GCP service accounts — three permission models, three audit logs. Centralise human access through SSO (Okta, Azure AD, or Google Workspace with SAML) and use short-lived credentials for CI/CD. GitLab CI OIDC to AWS and Azure eliminates long-lived access keys sitting in pipeline variables. I have recovered client repos where an AWS key in a public GitLab fork caused a Rs 200,000+ (~USD 1,500) cryptomining bill over a weekend.
Observability fragmentation
CloudWatch, Azure Monitor, and Google Cloud Logging do not talk to each other. Ship logs and metrics to a neutral backend: Grafana Cloud, Datadog, or a self-hosted stack with Prometheus and Loki. OpenTelemetry instrumentation in your Laravel app — one SDK, multiple exporters — beats bolting on three agent configurations after an outage. Structure logs as JSON with trace_id, cloud, and region fields so you can filter during a partial failover.
Secret management
Never duplicate secrets manually across clouds. Options that work in 2026:
- HashiCorp Vault with dynamic database credentials
- AWS Secrets Manager as source of truth with replication to Azure Key Vault via CI sync jobs
- External Secrets Operator on Kubernetes pulling from one vault into all clusters
Rotate secrets on a schedule. Payment gateway keys (Khalti, eSewa, Stripe) must update in all environments simultaneously — a half-updated rotation breaks callbacks on whichever cloud still holds the old key.
Egress cost surprises
Moving 100 GB/month between AWS and GCP over the public internet costs more than many teams expect. Model egress in your architecture review. Keep data close to compute; replicate summaries, not raw event streams, across clouds unless regulation demands full copies.
How do you run disaster recovery and control costs across multiple clouds?
Disaster recovery (DR) is the most common legitimate reason for multi-cloud. The pattern I recommend for web apps: active-passive, not active-active.
Active-passive DR runbook
- Primary region running hot: Full traffic, live database, queue workers processing jobs.
- Secondary cloud warm standby: Infrastructure provisioned via Terraform, container images pre-built, database restored from latest cross-cloud backup (or async replica if budget allows).
- RPO/RTO targets written down: Recovery Point Objective (how much data you can lose) and Recovery Time Objective (how fast you must recover). A booking portal might target RPO 15 minutes, RTO 60 minutes. A brochure site can tolerate RPO 24 hours.
- Automated backups to provider-neutral storage: Nightly MySQL dumps to S3 with cross-region replication, or use the patterns in the cloud backup and disaster recovery strategy guide. Test restores quarterly — an untested backup is wishful thinking.
- DNS failover: Health check fails on primary → update DNS to secondary origin → verify payment webhooks still reach the new endpoint (update gateway callback URLs if IP-based).
On sister sites I maintain with Deployer 7 and GitLab CI on shared EC2, the DR story is simpler: same codebase, off-site S3 backups, and a documented restore-to-fresh-VPS procedure. That is single-cloud DR done right, and it outperforms most half-built multi-cloud setups.
FinOps across providers
Multi-cloud without cost governance bleeds budget silently. Practical controls for 2026:
- Tag everything:
Environment,Team,CostCenter,Cloudon every resource. Untagged resources are invisible in chargeback reports. - One dashboard: AWS Cost Explorer, Azure Cost Management, and GCP Billing export feed into a spreadsheet or tool like Kubecost / CloudHealth. Nepali startups should read the AWS and Azure budgeting guide for Nepal startups before committing cross-cloud spend.
- Right-size standby: DR infrastructure does not need production-grade instances 24/7. Scale down App Service tiers or stop non-essential EC2 instances; Terraform
terraform applypromotes instance sizes during failover. - Reserved capacity on primary only: Buy one-year reserved instances on the cloud that carries 90% of traffic. Pay on-demand for the cold standby.
A realistic monthly cost picture for a mid-size Laravel SaaS: primary AWS stack USD 400–800 (Rs 53,000–106,000), warm Azure standby USD 80–150 (Rs 10,600–20,000), cross-cloud egress USD 20–100 depending on replication volume, plus USD 50–100 for observability and DNS. That is 30–50% more than single-cloud multi-region — budget for it upfront or do not start.
What should you implement first when adopting multi-cloud?
If you have a written requirement to proceed, ship in this order:
- Portable application layer: Dockerise the Laravel app, externalise sessions to Redis, store uploads on S3-compatible object storage, run queue workers as separate processes.
- Single IaC pipeline: One Git repo, Terraform modules per cloud, CI plan/apply with approval gates. See deploying the same app to AWS and Azure with Terraform for a concrete starting point.
- Backup and restore tested: Before any VPN or failover work, prove you can rebuild from backups in under your RTO target.
- Private networking: VPN between VPCs; restrict security groups / NSGs to tunnel CIDRs only.
- DNS failover: Health-checked records with documented runbook.
- Game days: Quarterly simulated failover during business hours. Measure actual RTO, not the number in the slide deck.
Skip Kubernetes across three clouds until you have a platform team. Plain compute — EC2, App Service, or managed PHP platforms — with identical deploy artefacts is faster to operate for most PHP/Laravel shops.
Build multi-cloud with intent, not by accident
Multi-Cloud Architecture: A Practical Guide is not a mandate to spread workloads everywhere. It is a framework for when business requirements — resilience, compliance, client mandates, or acquisition integration — genuinely outweigh the operational cost of running AWS, Azure, and GCP together. Default to one primary cloud with tested backups and multi-region redundancy; add a second provider only with documented RPO/RTO targets, Terraform-managed infrastructure, private networking, unified observability, and a failover runbook your team has actually executed. That is the difference between multi-cloud as architecture and multi-cloud as expensive technical debt.
If you are planning a multi-cloud migration, DR redesign, or need an honest assessment of whether your Nepal-based business actually needs more than one provider, get in touch for a architecture review. I work through stack choices, cost models in NPR, and deployment automation on production systems — not theoretical diagrams.

