Module 20: Multi-Cloud Strategies
Belt Level: ⚫ Black Belt Duration: 60 minutes Prerequisites: Modules 1-19, especially Module 17 (Platform as a Product), Module 18 (Multi-Tenancy) Certification Track: Fawkes Platform Architect
🎯 Learning Objectives
By the end of this module, you will be able to:
- Evaluate when multi-cloud architecture makes sense vs. single-cloud with vendor lock-in mitigation
- Design abstraction layers that enable portability across cloud providers
- Implement disaster recovery and failover strategies across multiple clouds
- Optimize costs by leveraging pricing differences and committed use discounts
- Navigate the tradeoffs between cloud-agnostic tools and cloud-native services
📚 Theory: Multi-Cloud Architecture
What is Multi-Cloud?
Multi-cloud: Using services from multiple cloud providers (AWS, GCP, Azure) within the same organization or architecture.
Types of multi-cloud:
- Distributed workloads: Different applications run on different clouds
- Redundant deployment: Same application deployed to multiple clouds for resilience
- Hybrid bursting: Primary cloud with overflow to secondary cloud
- Data residency: Workloads placed in specific clouds for compliance
Why Multi-Cloud?
✅ Valid Reasons
- Avoid vendor lock-in: Reduce dependency on single provider
- Disaster recovery: Survive cloud provider outage
- Regulatory compliance: Data residency requirements (EU data must stay in EU)
- Cost optimization: Use cheapest provider for specific workload
- Acquisitions: Inherited cloud environments from acquired companies
- Best-of-breed services: Leverage unique capabilities (e.g., BigQuery on GCP, SageMaker on AWS)
❌ Poor Reasons
- "Just in case" vendor lock-in fear: Adds massive complexity without clear benefit
- Negotiation leverage: Threat of moving is often sufficient
- Resume-driven development: Learning new cloud for sake of it
- Avoiding architectural decisions: Multi-cloud doesn't solve bad architecture
The Multi-Cloud Spectrum
┌────────────────────────────────────────────────────────────────┐
│ CLOUD STRATEGY SPECTRUM │
├────────────────────────────────────────────────────────────────┤
│ │
│ SINGLE CLOUD (CLOUD-NATIVE) │
│ ├─ Deeply integrate with cloud-specific services │
│ ├─ Fastest time-to-market, most features │
│ ├─ Highest vendor lock-in │
│ ├─ Example: Lambda, DynamoDB, SQS, S3, CloudWatch │
│ └─ Best for: Startups, rapid innovation │
│ │
│ SINGLE CLOUD (WITH ABSTRACTION) │
│ ├─ Use cloud-agnostic tools on single cloud │
│ ├─ Kubernetes, PostgreSQL, Kafka, Redis │
│ ├─ Could migrate but requires effort │
│ ├─ Example: EKS + RDS PostgreSQL + MSK Kafka │
│ └─ Best for: Most enterprises │
│ │
│ MULTI-CLOUD (DISTRIBUTED) │
│ ├─ Different apps on different clouds │
│ ├─ Moderate complexity, limited blast radius │
│ ├─ Each app optimized for its cloud │
│ ├─ Example: Web app on AWS, ML on GCP, legacy on Azure │
│ └─ Best for: Large orgs with diverse needs │
│ │
│ MULTI-CLOUD (PORTABLE) │
│ ├─ Same app deployable to any cloud │
│ ├─ High complexity, maximum portability │
│ ├─ Abstraction layer hides cloud differences │
│ ├─ Example: Kubernetes + Crossplane + Terraform │
│ └─ Best for: High-compliance industries, DR requirements │
│ │
│ MULTI-CLOUD (ACTIVE-ACTIVE) │
│ ├─ Same app running on multiple clouds simultaneously │
│ ├─ Highest complexity, highest resilience │
│ ├─ Data replication, global routing, conflict resolution │
│ ├─ Example: CockroachDB across 3 clouds with global LB │
│ └─ Best for: Mission-critical systems (financial, healthcare)│
│ │
└────────────────────────────────────────────────────────────────┘
Complexity & Cost ──────────────────────────────────────────────▶
Portability ▶
The Cost of Multi-Cloud
Operational overhead:
- Multiple IAM systems to manage
- Different networking models (VPC, VNet, VPC)
- Divergent monitoring and logging tools
- Team training for multiple clouds
- More complex incident response
Financial costs:
- Data egress fees (expensive to move data between clouds)
- Lost volume discounts (spend split across providers)
- Duplication of resources (CI/CD, monitoring, networks)
Engineering complexity:
- Lowest common denominator (can't use best-of-breed services)
- Abstraction layers introduce bugs and performance overhead
- Testing must cover all cloud environments
Rule of thumb: Multi-cloud adds 30-50% operational overhead compared to single cloud.
🏗️ Multi-Cloud Architecture Patterns
Pattern 1: Multi-Cloud by Application
When to use: Different teams/products have different cloud requirements.
┌─────────────────────────────────────────────────┐
│ Organization │
├─────────────────────────────────────────────────┤
│ │
│ Product A (AWS) Product B (GCP) │
│ ├─ EKS ├─ GKE │
│ ├─ RDS PostgreSQL ├─ Cloud SQL │
│ ├─ S3 ├─ BigQuery │
│ └─ CloudWatch └─ Cloud Monitoring │
│ │
│ Shared Platform Team │
│ ├─ Terraform modules for both clouds │
│ ├─ Separate CI/CD per cloud │
│ └─ Unified observability (Datadog) │
│ │
└─────────────────────────────────────────────────┘
Pros:
- Each team optimizes for their cloud
- Limited complexity (no cross-cloud communication)
- Easy to start (pilot one app on new cloud)
Cons:
- Teams must learn different clouds
- Harder to share infrastructure
- Duplicated platform tooling
Pattern 2: Multi-Cloud for Disaster Recovery
When to use: Must survive cloud provider outage (99.99%+ availability requirement).
┌──────────────────────────────────────────────────────────┐
│ PRIMARY CLOUD (AWS) │
│ ┌────────────────────────────────────────────────┐ │
│ │ Production Workloads │ │
│ │ ├─ Active traffic (100%) │ │
│ │ ├─ Continuous deployment │ │
│ │ └─ Real-time data replication ──┐ │ │
│ └────────────────────────────────────────────────┘ │
└────────────────────────────────────────┼─────────────────┘
│
│ Replicate data
▼
┌──────────────────────────────────────────────────────────┐
│ SECONDARY CLOUD (GCP) │
│ ┌────────────────────────────────────────────────┐ │
│ │ Standby Workloads │ │
│ │ ├─ Infrastructure pre-provisioned │ │
│ │ ├─ Data replicated continuously │ │
│ │ └─ Auto-failover if AWS unhealthy │ │
│ └────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
Global Load Balancer (Cloudflare, AWS Route53)
├─ Health checks both clouds
├─ Automatic failover (DNS/Anycast)
└─ Failback once primary recovers
Implementation:
- Active-Passive: Primary handles all traffic, secondary is warm standby
- Active-Active: Both clouds handle traffic (more complex, requires data sync)
Key decisions:
- RTO (Recovery Time Objective): How long can you be down?
- RTO < 5 min → Active-Active (expensive)
- RTO 5-30 min → Warm standby (moderate cost)
- RTO > 30 min → Cold standby (cheapest)
- RPO (Recovery Point Objective): How much data can you lose?
- RPO = 0 → Synchronous replication (very expensive)
- RPO < 5 min → Continuous async replication
- RPO > 15 min → Periodic snapshots
Pattern 3: Multi-Cloud with Kubernetes
When to use: Need portable workloads with minimal cloud-specific code.
┌──────────────────────────────────────────────────────────┐
│ APPLICATION LAYER (Cloud-Agnostic) │
│ ├─ Kubernetes YAML manifests │
│ ├─ Helm charts │
│ ├─ ArgoCD for GitOps deployment │
│ └─ Prometheus + Grafana for monitoring │
└────────────────────┬─────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ EKS │ │ GKE │ │ AKS │
│ (AWS) │ │ (GCP) │ │ (Azure) │
└─────────┘ └─────────┘ └─────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Cloud │ │ Cloud │ │ Cloud │
│ Services│ │ Services│ │ Services│
│ │ │ │ │ │
│ RDS │ │Cloud SQL│ │CosmosDB │
│ S3 │ │ GCS │ │ Blob │
│ SQS │ │ Pub/Sub │ │ServiceBs│
└─────────┘ └─────────┘ └─────────┘
Abstraction strategies:
- Storage: Use Kubernetes CSI drivers
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
storageClassName: fast-ssd # Maps to EBS (AWS), PD-SSD (GCP), Premium (Azure)
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
- Secrets: Use External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: cloud-secrets
spec:
provider:
# Automatically detects AWS Secrets Manager, GCP Secret Manager, or Azure Key Vault
# based on cluster environment
- Databases: Use Crossplane for cloud resource provisioning
apiVersion: database.crossplane.io/v1alpha1
kind: PostgreSQLInstance
metadata:
name: my-database
spec:
forProvider:
# Crossplane translates to RDS, Cloud SQL, or Azure Database
engineVersion: "14"
instanceClass: db.t3.medium
storageGB: 100
providerConfigRef:
name: default # Points to current cloud
Pattern 4: Data Residency & Compliance
When to use: Regulatory requirements dictate where data must reside (GDPR, data sovereignty).
┌─────────────────────────────────────────────────────────────┐
│ GLOBAL APPLICATION │
│ (Single codebase, multi-region) │
└──────────────────────────┬──────────────────────────────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ AWS EU │ │ GCP US │ │ Azure APAC │
│ eu-central-1 │ │ us-central1 │ │ australiaeast│
│ │ │ │ │ │
│ GDPR │ │ HIPAA │ │ AU Privacy │
│ compliant │ │ compliant │ │ Act │
└──────────────┘ └──────────────┘ └──────────────┘
EU customer US customer APAC customer
data stays in data stays in data stays in
EU region US region APAC region
Implementation:
- Geo-routing: Route users to nearest compliant region (DNS, Anycast)
- Data partitioning: Customer data sharded by geography
- Cross-region replication: Limited to regions with adequate legal frameworks
🛠️ Tools for Multi-Cloud
1. Infrastructure-as-Code
Terraform: De facto standard for multi-cloud IaC.
# Single Terraform module can provision across clouds
resource "aws_s3_bucket" "data_lake" {
count = var.cloud_provider == "aws" ? 1 : 0
bucket = "my-data-lake"
}
resource "google_storage_bucket" "data_lake" {
count = var.cloud_provider == "gcp" ? 1 : 0
name = "my-data-lake"
location = "US"
}
resource "azurerm_storage_account" "data_lake" {
count = var.cloud_provider == "azure" ? 1 : 0
name = "mydatalake"
resource_group_name = azurerm_resource_group.main[0].name
location = "eastus"
}
# Output abstraction
output "data_lake_url" {
value = var.cloud_provider == "aws" ? aws_s3_bucket.data_lake[0].bucket_regional_domain_name :
var.cloud_provider == "gcp" ? google_storage_bucket.data_lake[0].url :
azurerm_storage_account.data_lake[0].primary_blob_endpoint
}
Pulumi: Multi-cloud IaC using real programming languages.
import * as aws from "@pulumi/aws";
import * as gcp from "@pulumi/gcp";
import * as azure from "@pulumi/azure-native";
// Abstract storage bucket across clouds
function createStorageBucket(provider: string, name: string) {
switch (provider) {
case "aws":
return new aws.s3.Bucket(name);
case "gcp":
return new gcp.storage.Bucket(name, { location: "US" });
case "azure":
const resourceGroup = new azure.resources.ResourceGroup("rg");
return new azure.storage.StorageAccount(name, {
resourceGroupName: resourceGroup.name,
location: "eastus",
});
}
}
const bucket = createStorageBucket(process.env.CLOUD_PROVIDER, "my-bucket");
2. Kubernetes Abstraction
Crossplane: Provision cloud resources using Kubernetes APIs.
# Define a composition that works across clouds
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xdatabases.example.com
spec:
group: example.com
names:
kind: XDatabase
plural: xdatabases
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
size:
type: string
enum: [small, medium, large]
engine:
type: string
enum: [postgres, mysql]
---
# Composition for AWS
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xdatabase.aws
spec:
compositeTypeRef:
apiVersion: example.com/v1alpha1
kind: XDatabase
resources:
- name: rds-instance
base:
apiVersion: database.aws.crossplane.io/v1beta1
kind: RDSInstance
spec:
forProvider:
engine: # Set from spec.engine
instanceClass: # Map spec.size to AWS instance class
---
# Composition for GCP
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: xdatabase.gcp
spec:
compositeTypeRef:
apiVersion: example.com/v1alpha1
kind: XDatabase
resources:
- name: cloudsql-instance
base:
apiVersion: database.gcp.crossplane.io/v1beta1
kind: CloudSQLInstance
spec:
forProvider:
databaseVersion: # Set from spec.engine
tier: # Map spec.size to GCP tier
Usage (same manifest works on any cloud):
apiVersion: example.com/v1alpha1
kind: XDatabase
metadata:
name: my-app-db
spec:
size: medium
engine: postgres
# Crossplane automatically provisions RDS on AWS, Cloud SQL on GCP, etc.
3. Service Mesh for Multi-Cloud Networking
Istio Multi-Cluster: Connect services across multiple Kubernetes clusters in different clouds.
# Configure Istio to treat GKE and EKS clusters as one mesh
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio-control-plane
spec:
values:
global:
meshID: shared-mesh
multiCluster:
clusterName: aws-east-cluster # or gcp-us-cluster
network: aws-network # or gcp-network
Service in AWS can call service in GCP transparently:
# Payment service running in AWS EKS
apiVersion: v1
kind: Service
metadata:
name: payment-api
namespace: payments
---
# Fraud detection service running in GCP GKE
apiVersion: v1
kind: Service
metadata:
name: fraud-detection
namespace: fraud
# Payment service can call: http://fraud-detection.fraud.svc.cluster.local
# Istio routes across clouds with mTLS
4. Observability
Unified observability across clouds:
# Prometheus scrapes metrics from all clouds
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
data:
prometheus.yml: |
global:
external_labels:
cluster: 'multi-cloud'
scrape_configs:
- job_name: 'aws-services'
ec2_sd_configs:
- region: us-east-1
access_key: ${AWS_ACCESS_KEY}
secret_key: ${AWS_SECRET_KEY}
- job_name: 'gcp-services'
gce_sd_configs:
- project: my-project
zone: us-central1-a
- job_name: 'azure-services'
azure_sd_configs:
- subscription_id: ${AZURE_SUBSCRIPTION_ID}
tenant_id: ${AZURE_TENANT_ID}
remote_write:
- url: https://prometheus.example.com/api/v1/write
# Centralized long-term storage
Grafana dashboards showing unified view:
┌─────────────────────────────────────────────────┐
│ Application Performance (All Clouds) │
├─────────────────────────────────────────────────┤
│ │
│ Request Rate: 1,250 req/s │
│ ├─ AWS: 800 req/s (64%) │
│ ├─ GCP: 350 req/s (28%) │
│ └─ Azure: 100 req/s (8%) │
│ │
│ Error Rate: 0.12% │
│ ├─ AWS: 0.08% │
│ ├─ GCP: 0.15% │
│ └─ Azure: 0.25% │
│ │
│ P99 Latency: 245ms │
│ ├─ AWS: 220ms │
│ ├─ GCP: 250ms │
│ └─ Azure: 310ms │
│ │
└─────────────────────────────────────────────────┘
5. Cost Management
Cloud Cost Optimization Tools:
- Kubecost: Multi-cluster Kubernetes cost visibility
- CloudHealth: Cross-cloud cost management
- Infracost: Estimate Terraform costs before deployment
Example: Compare costs across clouds
# Infracost for Terraform
infracost breakdown --path . --usage-file usage.yml
# Output:
# AWS: $12,450/month
# GCP: $10,200/month (18% cheaper)
# Azure: $13,100/month (5% more expensive)
Strategy: Hybrid committed use discounts
Single Cloud (AWS only):
├─ 3-year Reserved Instances: 60% of capacity
├─ 1-year Reserved Instances: 20% of capacity
└─ On-demand: 20% of capacity
└─ Average discount: 45%
Multi-Cloud (AWS + GCP):
├─ Can't commit as much (workloads split)
├─ AWS: 40% reserved, 60% on-demand
└─ GCP: 40% committed use, 60% on-demand
└─ Average discount: 30%
Result: Multi-cloud loses ~15% in discounts
🏗️ Hands-On Lab: Multi-Cloud Deployment
Lab Overview
You will deploy the same application to AWS (EKS) and GCP (GKE) using:
- Terraform to provision infrastructure
- Kubernetes manifests for the application
- Crossplane to provision cloud-specific resources (RDS, Cloud SQL)
- Istio multi-cluster for cross-cloud service communication
- Unified observability with Prometheus + Grafana
Duration: 25 minutes
Tools: terraform, kubectl, helm, fawkes CLI
Lab Setup
# Start the multi-cloud lab environment
fawkes lab start --module 20
# This provisions:
# - AWS account with EKS cluster (simulated in lab)
# - GCP account with GKE cluster (simulated in lab)
# - Pre-configured kubectl contexts: aws-cluster, gcp-cluster
# Verify access to both clusters
kubectl config get-contexts
# You should see:
# CURRENT NAME CLUSTER
# * aws-cluster aws-cluster
# gcp-cluster gcp-cluster
Exercise 1: Provision Infrastructure with Terraform (7 minutes)
Objective: Use Terraform to create VPCs, subnets, and Kubernetes clusters on both AWS and GCP.
cd ~/fawkes-lab-20/terraform
# Review the multi-cloud Terraform configuration
cat main.tf
main.tf:
# Multi-cloud infrastructure
variable "cloud_provider" {
type = string
# Set via: terraform apply -var="cloud_provider=aws"
}
# AWS Resources
module "aws_infrastructure" {
count = var.cloud_provider == "aws" ? 1 : 0
source = "./modules/aws"
cluster_name = "fawkes-eks"
region = "us-east-1"
node_count = 3
}
# GCP Resources
module "gcp_infrastructure" {
count = var.cloud_provider == "gcp" ? 1 : 0
source = "./modules/gcp"
cluster_name = "fawkes-gke"
region = "us-central1"
node_count = 3
}
# Outputs
output "cluster_endpoint" {
value = var.cloud_provider == "aws" ? module.aws_infrastructure[0].cluster_endpoint : module.gcp_infrastructure[0].cluster_endpoint
}
output "kubeconfig_command" {
value = var.cloud_provider == "aws" ? "aws eks update-kubeconfig --name fawkes-eks" : "gcloud container clusters get-credentials fawkes-gke"
}
Apply infrastructure:
# Provision AWS cluster
terraform init
terraform apply -var="cloud_provider=aws" -auto-approve
# Switch to GCP
terraform apply -var="cloud_provider=gcp" -auto-approve
# Both clusters are now running
Exercise 2: Deploy Application to Both Clouds (5 minutes)
Objective: Deploy identical application manifests to both AWS and GCP clusters.
cd ~/fawkes-lab-20/k8s
# Deploy to AWS
kubectl config use-context aws-cluster
kubectl apply -f namespace.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
# Deploy to GCP
kubectl config use-context gcp-cluster
kubectl apply -f namespace.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
# Verify deployments
kubectl get pods -n payments --context aws-cluster
kubectl get pods -n payments --context gcp-cluster
deployment.yaml (same for both clouds):
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment-api
namespace: payments
spec:
replicas: 3
selector:
matchLabels:
app: payment-api
template:
metadata:
labels:
app: payment-api
spec:
containers:
- name: api
image: ghcr.io/fawkes-demo/payment-api:v2.0.0
ports:
- containerPort: 8080
env:
- name: CLOUD_PROVIDER
value: "auto-detect" # App detects AWS vs GCP
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
Exercise 3: Provision Cloud Resources with Crossplane (6 minutes)
Objective: Use Crossplane to provision PostgreSQL databases on both clouds using the same API.
# Install Crossplane on both clusters
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
# Install on AWS cluster
kubectl config use-context aws-cluster
helm install crossplane crossplane-stable/crossplane \
--namespace crossplane-system --create-namespace
# Install on GCP cluster
kubectl config use-context gcp-cluster
helm install crossplane crossplane-stable/crossplane \
--namespace crossplane-system --create-namespace
# Install cloud provider packages
kubectl config use-context aws-cluster
kubectl crossplane install provider crossplane/provider-aws:v0.35.0
kubectl config use-context gcp-cluster
kubectl crossplane install provider crossplane/provider-gcp:v0.30.0
Create database using cloud-agnostic API:
# On AWS (will create RDS)
kubectl config use-context aws-cluster
kubectl apply -f - <<EOF
apiVersion: database.example.com/v1alpha1
kind: Database
metadata:
name: payment-db
namespace: payments
spec:
engine: postgres
version: "14"
size: small
storageGB: 100
EOF
# On GCP (will create Cloud SQL)
kubectl config use-context gcp-cluster
kubectl apply -f - <<EOF
apiVersion: database.example.com/v1alpha1
kind: Database
metadata:
name: payment-db
namespace: payments
spec:
engine: postgres
version: "14"
size: small
storageGB: 100
EOF
# Same manifest, different implementations!
Verify databases are provisioning:
kubectl get database -n payments --context aws-cluster
# NAME READY PROVIDER SIZE
# payment-db True AWS RDS small
kubectl get database -n payments --context gcp-cluster
# NAME READY PROVIDER SIZE
# payment-db True GCP CloudSQL small
Exercise 4: Configure Multi-Cluster Service Mesh (7 minutes)
Objective: Connect services across AWS and GCP clusters using Istio.
# Istio is pre-installed in the lab. Configure multi-cluster mesh.
# Install east-west gateway on AWS
kubectl config use-context aws-cluster
kubectl apply -f ~/fawkes-lab-20/istio/aws-east-west-gateway.yaml
# Install east-west gateway on GCP
kubectl config use-context gcp-cluster
kubectl apply -f ~/fawkes-lab-20/istio/gcp-east-west-gateway.yaml
# Exchange discovery secrets (allow clusters to find each other)
istioctl x create-remote-secret \
--context=aws-cluster \
--name=aws | \
kubectl apply -f - --context=gcp-cluster
istioctl x create-remote-secret \
--context=gcp-cluster \
--name=gcp | \
kubectl apply -f - --context=aws-cluster
Test cross-cloud communication:
# Deploy a client pod in AWS that calls service in GCP
kubectl config use-context aws-cluster
kubectl run -it curl-test --image=curlimages/curl --restart=Never -- \
curl http://payment-api.payments.svc.cluster.local
# This request will:
# 1. DNS resolves to local service
# 2. Istio detects service also exists in GCP
# 3. Load balances across both clouds
# 4. Encrypts traffic with mTLS through east-west gateway
View traffic distribution:
# Deploy Kiali dashboard
kubectl apply -f ~/fawkes-lab-20/kiali/kiali.yaml --context aws-cluster
# Port-forward to view
kubectl port-forward svc/kiali 20001:20001 -n istio-system --context aws-cluster
# Open browser: http://localhost:20001
# You'll see traffic flowing between AWS and GCP clusters
Lab Validation
# Run validation
fawkes lab validate --module 20
# You should see:
# ✅ AWS EKS cluster provisioned
# ✅ GCP GKE cluster provisioned
# ✅ Application deployed to both clouds
# ✅ Crossplane databases created (RDS + Cloud SQL)
# ✅ Istio multi-cluster mesh configured
# ✅ Cross-cloud service communication working
Cleanup:
fawkes lab stop --module 20
✅ Knowledge Check
Question 1: Multi-Cloud Rationale
Which is a VALID reason to adopt multi-cloud architecture?
A) To learn new technologies B) Regulatory requirement for data residency in specific regions C) To have leverage in vendor negotiations D) To avoid making architectural decisions
Show Answer
**Answer:** B Data residency requirements (e.g., GDPR mandating EU data stay in EU) are legitimate drivers for multi-cloud. Learning, negotiation leverage, and avoiding decisions are poor reasons that don't justify the added complexity.Question 2: Multi-Cloud Cost
What is the typical operational overhead increase when moving from single-cloud to multi-cloud?
A) 5-10% B) 15-20% C) 30-50% D) 100%+
Show Answer
**Answer:** C Industry studies show multi-cloud typically adds 30-50% operational overhead due to: multiple IAM systems, divergent tooling, team training, lost volume discounts, and increased complexity.Question 3: Disaster Recovery
For a system requiring RTO (Recovery Time Objective) of 30 minutes, which DR strategy is most appropriate?
A) Cold standby (infrastructure provisioned on-demand) B) Warm standby (infrastructure pre-provisioned, app in standby) C) Hot standby (active-active across clouds) D) No DR needed
Show Answer
**Answer:** B Warm standby balances cost and recovery time. Cold standby takes too long (>30 min to provision infrastructure). Hot standby (active-active) is overkill for 30-minute RTO and significantly more expensive.Question 4: Kubernetes Portability
Which component is NOT helpful for multi-cloud Kubernetes portability?
A) CSI (Container Storage Interface) drivers B) Crossplane for cloud resource provisioning C) AWS Lambda functions D) External Secrets Operator
Show Answer
**Answer:** C AWS Lambda is cloud-specific and tightly coupled to AWS. CSI drivers, Crossplane, and External Secrets Operator all provide abstraction layers that work across clouds.Question 5: Data Egress Costs
Why is data transfer between clouds expensive?
A) Bandwidth limitations B) Cloud providers charge high egress fees C) Encryption overhead D) Latency penalties
Show Answer
**Answer:** B Cloud providers charge significant egress fees (often $0.08-0.12/GB) when data leaves their network. This makes active-active multi-cloud with frequent data sync very expensive.Question 6: Service Mesh
What does an Istio multi-cluster east-west gateway provide?
A) Load balancing within a single cluster B) Secure connectivity between clusters in different clouds C) DNS resolution for external services D) Container image registry
Show Answer
**Answer:** B East-west gateways enable secure, mTLS-encrypted communication between services in different Kubernetes clusters, even across cloud providers.Question 7: Terraform vs Crossplane
What is the key difference between Terraform and Crossplane for multi-cloud?
A) Terraform is faster B) Crossplane uses Kubernetes APIs, Terraform uses CLI C) Terraform only supports AWS D) Crossplane is cheaper
Show Answer
**Answer:** B Crossplane provisions cloud resources using Kubernetes Custom Resources (declarative, reconciliation loops). Terraform uses its own CLI and state files (imperative with state management).Question 8: Cloud-Native vs Cloud-Agnostic
When should you prefer cloud-native services over cloud-agnostic tools?
A) Never, always use cloud-agnostic B) When speed-to-market and features outweigh portability concerns C) Only for non-production environments D) When you have unlimited budget
Show Answer
**Answer:** B Cloud-native services (Lambda, DynamoDB, BigQuery) offer better performance, features, and developer experience. Use them when portability is not a primary concern (which is most startups and many enterprises).🌍 Real-World Examples
Example 1: Shopify's Multi-Cloud Strategy
Approach: Multi-cloud by region, not by workload.
Architecture:
- Primary: GCP (main infrastructure)
- Disaster Recovery: AWS (warm standby)
- Data residency: Regional clouds for EU/APAC
Key decisions:
- Standardized on Kubernetes (GKE primary, EKS secondary)
- Used Terraform for infrastructure provisioning
- Avoided active-active (complexity not worth it)
- Invested heavily in observability (Datadog across clouds)
Results:
- Survived GCP outage in 2020 with minimal downtime
- Achieved 99.99% availability SLA
- Cost: ~20% overhead vs single-cloud
Lesson: Multi-cloud for DR makes sense at scale, but keep it simple (active-passive, not active-active).
Example 2: Spotify's Cloud Migration
Journey: Datacenter → GCP (2016-2018)
Why NOT multi-cloud?:
- Decided vendor lock-in risk < operational complexity cost
- Bet on GCP for best-of-breed data/ML services (BigQuery, Dataflow)
- Negotiated favorable pricing with Google
How they mitigated lock-in:
- Used Kubernetes for all workloads (portable if needed)
- Abstracted storage with GCS-compatible libraries
- Open-sourced internal tools (Backstage) for community portability
Results:
- Successful migration in 2 years
- Reduced infrastructure costs by 30%
- Faster feature development (cloud-native services)
Lesson: For most companies, single-cloud with portability planning is better than multi-cloud execution.
Example 3: Capital One's Multi-Cloud Hybrid
Approach: AWS-primary with strategic GCP usage.
Architecture:
- 95% of workloads: AWS (core banking systems)
- ML/AI workloads: GCP (BigQuery, Vertex AI)
- Data analytics: GCP (better data warehouse pricing)
Implementation:
- Cross-cloud VPN for secure connectivity
- Replicate data to GCP for analytics (batch, nightly)
- Unified IAM via Okta SSO
Results:
- Best-of-breed services without full multi-cloud complexity
- Contained GCP usage to specific use cases
- Avoided active-active complexity
Lesson: Tactical multi-cloud (best tool for the job) is more practical than strategic multi-cloud (everything everywhere).
Example 4: Dropbox's Cloud Repatriation
Journey: AWS → Own Datacenters (2016)
Why leave the cloud?:
- At scale (exabytes of data), cloud economics inverted
- 90% of workload predictable (not bursty)
- Egress fees killed economics ($75M+/year in bandwidth)
Result:
- Saved ~$75M over 2 years
- Better performance (purpose-built infrastructure)
- Retained AWS for edge locations and burst capacity
Lesson: Multi-cloud isn't always the answer. Sometimes "no cloud" or "hybrid cloud" makes more sense at extreme scale.
📊 DORA Capabilities Mapping
This module supports these DORA capabilities:
| Capability | How This Module Helps | Impact on Metrics |
|---|---|---|
| Deployment Automation | Terraform + Crossplane enable automated provisioning across clouds | Improves deployment frequency |
| Loosely Coupled Architecture | Service mesh enables independent deployment across clouds | Enables faster changes, reduces dependencies |
| Monitoring & Observability | Unified observability (Prometheus, Grafana) across clouds | Reduces MTTR with consistent tooling |
| Database Change Management | Crossplane provides declarative database provisioning | Safer, faster database changes |
🔧 Troubleshooting Common Issues
Issue 1: Cross-Cloud Networking Latency
Symptom: Services in AWS calling services in GCP have 200ms+ latency.
Cause: Geographic distance + internet routing.
Solution:
# Use dedicated interconnect
# AWS Direct Connect ↔ GCP Cloud Interconnect
# Or optimize service placement
# - Deploy services that talk frequently in same cloud
# - Use caching (Redis) to reduce cross-cloud calls
# - Async messaging (Kafka) instead of synchronous HTTP
Issue 2: Istio Multi-Cluster Not Working
Symptom: Services in one cluster cannot reach services in another cluster.
Cause: Missing east-west gateway or incorrect network configuration.
Solution:
# Verify east-west gateway is running
kubectl get svc -n istio-system --context aws-cluster
kubectl get svc -n istio-system --context gcp-cluster
# Check if remote secrets are created
kubectl get secrets -n istio-system --context aws-cluster | grep gcp
kubectl get secrets -n istio-system --context gcp-cluster | grep aws
# Verify service endpoints are discovered
istioctl proxy-config endpoints <pod-name> -n payments --context aws-cluster
# Should show endpoints from both clusters
Issue 3: Terraform State Conflicts
Symptom: Error acquiring the state lock when running Terraform.
Cause: Multiple people/pipelines running Terraform simultaneously.
Solution:
# Use remote state with locking
terraform {
backend "s3" {
bucket = "terraform-state-bucket"
key = "multi-cloud/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks" # Enables locking
encrypt = true
}
}
# Alternative: Use Terraform Cloud for automatic locking
Issue 4: Crossplane Resource Stuck in "Provisioning"
Symptom: Database resource shows "Provisioning" for >10 minutes.
Cause: Cloud provider API errors or missing permissions.
Solution:
# Check Crossplane provider logs
kubectl logs -n crossplane-system -l pkg.crossplane.io/provider=provider-aws
# Common issues:
# - IAM role missing permissions
# - API rate limits hit
# - Invalid parameter (e.g., unsupported instance type)
# Describe the resource for detailed error
kubectl describe database payment-db -n payments
Issue 5: Cost Explosion from Data Egress
Symptom: Cloud bill 2x higher than expected.
Cause: Frequent data transfer between clouds.
Solution:
# Audit data transfer
aws ce get-cost-and-usage \
--time-period Start=2025-10-01,End=2025-10-31 \
--granularity MONTHLY \
--metrics BlendedCost \
--group-by Type=DIMENSION,Key=USAGE_TYPE | \
grep DataTransfer
# Optimization strategies:
# 1. Cache frequently accessed data locally (Redis)
# 2. Batch data transfers (nightly sync vs real-time)
# 3. Use compression (gzip) for data transfer
# 4. Colocate services that communicate frequently
# 5. Consider CDN (CloudFlare) for static assets
📚 Additional Resources
Official Documentation
- AWS Well-Architected Framework - Multi-Region
- GCP Multi-Cloud Architecture
- Azure Arc for Multi-Cloud
- CNCF Multi-Cloud White Paper
Tools & Frameworks
Books & Papers
- "Cloud Native Transformation" by Pini Reznik, Jamie Dobson & Michelle Gienow (O'Reilly) - Chapter on multi-cloud strategies
- "Architecting the Cloud" by Michael J. Kavis - Multi-cloud decision framework
- ThoughtWorks Technology Radar - Regular assessment of multi-cloud tools
Case Studies
- Shopify Engineering Blog - Multi-Cloud
- Spotify Labs - Why We Chose GCP
- Dropbox Tech Blog - Infrastructure
🎯 Key Takeaways
By completing this module, you've learned:
- ✅ When multi-cloud makes sense - DR, compliance, best-of-breed; not "just in case"
- ✅ The multi-cloud spectrum - From single-cloud to active-active, understand tradeoffs
- ✅ Abstraction strategies - Kubernetes, Crossplane, Terraform for portability
- ✅ Cost implications - 30-50% overhead, lost volume discounts, egress fees
- ✅ Implementation patterns - Multi-cloud by app, DR, data residency
- ✅ Practical tools - Terraform, Crossplane, Istio, unified observability
Critical insight: Multi-cloud is a tool, not a goal. Most organizations benefit more from single-cloud excellence with portability planning than premature multi-cloud complexity.
Decision framework:
- Start-up: Single cloud, cloud-native services (speed > portability)
- Growth stage: Single cloud with abstraction layers (prepare for optionality)
- Enterprise: Selective multi-cloud (DR, compliance, best-of-breed)
🚀 Next Steps
Congratulations! You've Completed the Black Belt Curriculum! 🥋
You've mastered all 20 modules of the Fawkes Dojo. Here's what comes next:
1. Black Belt Assessment (4 hours)
To earn your Fawkes Platform Architect certification, complete:
Written Exam (50 questions, 90% pass required):
- Multi-cloud architecture design
- Zero trust security implementation
- Platform-as-a-product principles
- Multi-tenancy patterns
- DORA metrics and continuous improvement
Practical Assessment:
-
Architecture Design (90 minutes)
-
Design a complete platform architecture for a given scenario
- Present to peer review panel
-
Defend design decisions under questioning
-
Implementation Challenge (90 minutes)
-
Implement multi-tenant namespace with resource quotas
- Configure zero trust policies (mTLS, image signing)
- Deploy application across two cloud providers
-
Set up unified observability
-
Code Contribution (60 minutes)
-
Contribute a feature or bug fix to Fawkes codebase
- Submit PR with documentation and tests
-
Code review by platform team
-
Mentorship (Outside assessment time)
- Mentor 2 White Belt learners through Module 1-4
- Document learner progress
- Provide constructive feedback
2. Continue Your Platform Engineering Journey
Advanced Topics (self-study):
- FinOps: Cloud cost optimization at scale
- Platform Security: Advanced threat modeling, security-as-code
- Developer Experience: Measuring and improving DORA metrics
- SRE Practices: Error budgets, on-call rotation, incident response
- Platform Product Management: Roadmapping, user research, adoption metrics
Recommended Certifications:
- Kubernetes: CKA (Certified Kubernetes Administrator)
- Cloud: AWS Solutions Architect, GCP Professional Cloud Architect
- Security: CISSP, Certified Ethical Hacker
- SRE: Google SRE Certification (if available)
3. Contribute to the Platform Engineering Community
Ways to give back:
- Write blog posts about your platform journey
- Speak at meetups or conferences (KubeCon, PlatformCon)
- Contribute to open-source platform tools (Backstage, Crossplane, ArgoCD)
- Mentor junior engineers at your organization
- Share learnings in #platformengineering on Twitter/LinkedIn
4. Apply Your Skills
Platform Engineering Career Paths:
- Platform Engineer: Build and maintain internal developer platforms
- Staff Platform Engineer: Lead platform initiatives, mentor team
- Platform Architect: Design enterprise-wide platform strategies
- Developer Experience Engineer: Focus on DX metrics and improvements
- SRE (Site Reliability Engineer): Own production reliability
- DevOps Architect: Bridge development and operations at scale
- Cloud Architect: Design multi-cloud and hybrid cloud solutions
- Platform Product Manager: Own platform roadmap and adoption
Salary Ranges (US, 2025):
- Platform Engineer: $120k - $180k
- Senior Platform Engineer: $150k - $220k
- Staff Platform Engineer: $180k - $280k
- Platform Architect: $200k - $350k+
📊 Your Fawkes Dojo Progress
╔══════════════════════════════════════════════════════════════╗
║ FAWKES DOJO COMPLETION SUMMARY ║
╚══════════════════════════════════════════════════════════════╝
White Belt (Platform Fundamentals) ████████████ 100%
✅ Module 1: Internal Delivery Platforms
✅ Module 2: DORA Metrics
✅ Module 3: GitOps Principles
✅ Module 4: Your First Deployment
Yellow Belt (CI/CD Mastery) ████████████ 100%
✅ Module 5: Continuous Integration Fundamentals
✅ Module 6: Building Golden Path Pipelines
✅ Module 7: Security Scanning & Quality Gates
✅ Module 8: Artifact Management
Green Belt (GitOps & Deployment) ████████████ 100%
✅ Module 9: GitOps with ArgoCD
✅ Module 10: Deployment Strategies
✅ Module 11: Progressive Delivery
✅ Module 12: Rollback & Incident Response
Brown Belt (Observability & SRE) ████████████ 100%
✅ Module 13: Metrics, Logs, and Traces
✅ Module 14: DORA Metrics Deep Dive
✅ Module 15: SLIs, SLOs, and Error Budgets
✅ Module 16: Incident Management & Postmortems
Black Belt (Platform Architecture) ████████████ 100%
✅ Module 17: Platform as a Product
✅ Module 18: Multi-Tenancy & Resource Management
✅ Module 19: Security & Zero Trust
✅ Module 20: Multi-Cloud Strategies
═══════════════════════════════════════════════════════════════
OVERALL PROGRESS: 20/20 MODULES COMPLETE (100%)
═══════════════════════════════════════════════════════════════
🏆 Ready for Black Belt Certification Assessment!
🎓 Certification Roadmap
┌─────────────────────────────────────────────────────────────┐
│ YOU ARE HERE! │
│ ↓ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 🥋 Black Belt Complete (Modules 1-20) │ │
│ └──────────────────┬───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 📝 Black Belt Assessment │ │
│ │ - 50-question exam (90% pass) │ │
│ │ - Architecture design presentation │ │
│ │ - Implementation challenge │ │
│ │ - Code contribution to Fawkes │ │
│ │ - Mentor 2 White Belt learners │ │
│ └──────────────────┬───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ 🎓 FAWKES PLATFORM ARCHITECT CERTIFICATION │ │
│ │ │ │
│ │ Certificate Number: FPA-2025-XXXXX │ │
│ │ Digital Badge: Add to LinkedIn │ │
│ │ Recognition: Fawkes Contributors Page │ │
│ └───────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
🏅 What You've Accomplished
Over the course of 20 modules, you've learned:
Technical Skills
- ✅ Design and implement internal developer platforms
- ✅ Build CI/CD pipelines with security scanning and quality gates
- ✅ Implement GitOps workflows with ArgoCD
- ✅ Deploy using progressive delivery (canary, blue-green)
- ✅ Establish comprehensive observability (metrics, logs, traces)
- ✅ Define and track DORA metrics
- ✅ Create SLIs, SLOs, and error budgets
- ✅ Respond to incidents and conduct blameless postmortems
- ✅ Design platforms as products with user research
- ✅ Implement multi-tenancy and resource management
- ✅ Architect zero trust security for platforms
- ✅ Design multi-cloud strategies and disaster recovery
Leadership & Soft Skills
- ✅ Communicate platform value to stakeholders
- ✅ Gather and incorporate user feedback
- ✅ Balance technical debt with feature development
- ✅ Lead architectural decisions
- ✅ Mentor junior engineers
- ✅ Navigate organizational change
Industry Knowledge
- ✅ DORA research and high-performing organizations
- ✅ Platform engineering best practices
- ✅ DevOps and SRE principles
- ✅ Cloud architecture patterns
- ✅ Security and compliance requirements
💬 Feedback & Community
Share Your Experience
We'd love to hear about your Fawkes Dojo journey!
Join the community:
- 💬 Mattermost:
#dojo-graduateschannel - 🐦 Twitter: Tweet with
#FawkesDojoand@FawkesPlatform - 💼 LinkedIn: Add "Fawkes Platform Architect" to certifications
- 📝 Blog: Write about your learning experience
Help improve the Dojo:
- Submit feedback via Backstage feedback plugin
- Suggest new modules or improvements
- Contribute lab exercises or quizzes
- Help translate content (internationalization)
🌟 Fawkes Platform Architect Badge
Upon passing the Black Belt Assessment, you'll receive:
╔═══════════════════════════════════════════════════════════╗
║ ║
║ 🏆 FAWKES DOJO 🏆 ║
║ ║
║ PLATFORM ARCHITECT CERTIFIED ║
║ ║
║ ⚫ BLACK BELT ⚫ ║
║ ║
║ This certifies that [YOUR NAME] has demonstrated ║
║ mastery in platform engineering, achieving the ║
║ highest level of the Fawkes Dojo curriculum. ║
║ ║
║ Competencies: ║
║ ✓ Platform Architecture & Design ║
║ ✓ CI/CD & GitOps ║
║ ✓ Observability & SRE ║
║ ✓ Security & Zero Trust ║
║ ✓ Multi-Cloud Strategies ║
║ ║
║ Certificate ID: FPA-2025-XXXXX ║
║ Issue Date: [DATE] ║
║ Valid Until: [DATE + 2 years] ║
║ ║
║ Verify: https://fawkes.io/verify/FPA-2025-XXXXX ║
║ ║
╚═══════════════════════════════════════════════════════════╝
Digital badge includes:
- Credly integration (add to LinkedIn, resume)
- QR code for verification
- Skill tags for recruiter searches
- Expiration date (renew every 2 years with continued learning)
📅 Recertification
Platform engineering evolves rapidly. To maintain your certification:
Recertification Options (every 2 years):
-
Continuous Learning Path:
-
Complete 4 new Fawkes Dojo modules (as they're released)
- Attend 2 platform engineering conferences/workshops
-
Contribute to 2 open-source platform projects
-
Advanced Assessment:
-
Take updated Black Belt exam (reflects new tools/practices)
-
Present case study from your production platform
-
Mentorship Track:
- Mentor 5 engineers through Fawkes Dojo
- Conduct 2 internal platform workshops
- Document learnings and best practices
🎉 Congratulations
You've completed the most comprehensive platform engineering curriculum available. You're now equipped to:
- Build world-class internal developer platforms
- Lead platform initiatives at your organization
- Mentor the next generation of platform engineers
- Shape the future of platform engineering
The journey doesn't end here – it's just beginning. Platform engineering is a rapidly evolving field, and continuous learning is essential.
Go forth and build amazing platforms! 🚀
📞 Stay Connected
- Fawkes Website: https://fawkes.io
- Documentation: https://docs.fawkes.io
- GitHub: https://github.com/fawkes-platform
- Community Forum: https://community.fawkes.io
- Mattermost: #platform-engineering
- Twitter: @FawkesPlatform
- YouTube: Fawkes Platform Engineering
Module 20: Multi-Cloud Strategies | Fawkes Dojo | Black Belt "Build once, deploy anywhere" | Version 1.0
🏆 Black Belt Status: COMPLETE! ✅
╔══════════════════════════════════════════════════════════╗
║ ║
║ 🥋 BLACK BELT CURRICULUM COMPLETE! 🥋 ║
║ ║
║ All 20 modules mastered. You are ready to: ║
║ ║
║ ✓ Schedule Black Belt Assessment ║
║ ✓ Design enterprise platform architectures ║
║ ✓ Lead platform engineering teams ║
║ ✓ Mentor junior platform engineers ║
║ ✓ Contribute to platform engineering community ║
║ ║
║ Next step: fawkes dojo assess --level black-belt ║
║ ║
╚══════════════════════════════════════════════════════════╝
You did it! 🎊 Now go earn that certification! 💪