Posted on :: 2454 Words :: Tags: , , , ,

Multi-Cloud: Khi Một Cloud Không Đủ (Và Tại Sao Điều Đó Thường Ổn)

Bạn đã thành thạo Terraform trên một cloud rồi. Giờ mọi conference talk và LinkedIn post đều la hét: "Hãy multi-cloud! Tránh vendor lock-in! Future-proof architecture của bạn!"

Đây là sự thật không ai muốn thừa nhận: Multi-cloud thường là quá mức cần thiết.

Nhưng đôi khi? Nó hoàn toàn cần thiết đó. Company của bạn vừa mua một công ty khác đang chạy trên cloud khác. Bạn cần regional compliance cụ thể mà chỉ Azure mới có. Hoặc có thể bạn đang thực sự build Netflix tiếp theo và cần geographic coverage trên mọi cloud provider trên Trái Đất.

Tutorial này dạy bạn cách implement multi-cloud Terraform, khi nào nó thực sự có ý nghĩa, và khi nào nên từ chối sự bùng nổ phức tạp đó một cách lịch sự nhé.

📦 Code Examples

Repository: terraform-hcl-tutorial-series This Part: Part 8 - Multi-Cloud Patterns

Lấy working example:

git clone https://github.com/khuongdo/terraform-hcl-tutorial-series.git
cd terraform-hcl-tutorial-series
git checkout part-08
cd examples/part-08-multi-cloud/

# So sánh AWS, GCP, và Azure patterns
terraform init
terraform plan

Kiểm Tra Thực Tế Multi-Cloud Mà Không Ai Nói

Bắt đầu với sự thật tàn bạo nào.

Tại Sao Các Công Ty Thực Sự Đi Multi-Cloud

Lý do hợp lệ xứng đáng với cái giá phải trả:

1. Mergers and Acquisitions Company A chạy mọi thứ trên AWS. Company B chạy mọi thứ trên GCP. Chúc mừng với việc mua lại! Bây giờ bạn có multi-cloud architecture cho dù bạn có muốn hay không đó.

2. Geographic Compliance Bạn cần data residency ở Đức, nhưng AWS không có certifications compliance cụ thể mà bạn cần. Azure có. Boom - bạn là multi-cloud rồi.

3. Negotiation Leverage Khi hóa đơn AWS của bạn đạt 7 con số hàng năm, khả năng nói một cách đáng tin cậy "chúng tôi có thể migrate sang GCP" trong đàm phán hợp đồng có giá trị tài chính thực sự đấy.

4. Best-of-Breed Services BigQuery của GCP thực sự đánh bại AWS Redshift cho một số analytics workloads nhất định. AWS Lambda có serverless ecosystem trưởng thành nhất. Azure Active Directory tích hợp tốt hơn với môi trường Windows enterprise của bạn. Đôi khi bạn cần cả ba.

5. True Disaster Recovery AWS US-EAST-1 down là hiếm, nhưng nó xảy ra đó. Nếu 6 giờ downtime khiến bạn mất $10 triệu, cross-cloud failover có ý nghĩa tài chính.

Những Lý Do Tồi (Hầu Hết Chúng)

"Chúng ta cần tránh vendor lock-in" Bạn đã locked vào Terraform, Kubernetes, Docker, PostgreSQL, và hàng tá technologies khác rồi. Cloud provider của bạn là mối lo lock-in ít nhất. Hơn nữa, migrate clouds cực kỳ đắt - bạn sẽ không làm điều đó trừ khi bị buộc.

"Điều gì nếu AWS shut down account của chúng ta?" Nếu AWS terminate account của bạn, bạn có vấn đề lớn hơn multi-cloud architecture. Hãy tập trung vào compliance và tuân thủ ToS thay vì vậy.

"Nó trông impressive trên resume của tôi" Tuyệt. Company của bạn giờ đang trả 3-5x operational overhead để bạn có thể thêm vào LinkedIn. Không phải một deal tốt.

"Chúng tôi muốn flexibility" Flexibility để làm gì, chính xác? Migrate toàn bộ production infrastructure giữa quarter? Đó không phải flexibility, đó là chaos.

Real Talk

Multi-cloud nhân operational complexity của bạn lên 3-5x. Bạn cần expertise trong multiple cloud consoles, billing systems, IAM models, và networking paradigms. Mọi engineer cần context-switch giữa ba cách khác nhau để làm cùng một thứ. Chỉ tiến hành nếu giá trị business rõ ràng xứng đáng với cost này nhé.

Foundation: Configuring Multiple Providers

Nếu bạn đã quyết định multi-cloud là worth it (hoặc nó được quyết định cho bạn), đây là cách config Terraform để work với multiple clouds.

Tin tốt? Terraform làm cho phần configuration khá straightforward.

Basic Multi-Provider Setup

# main.tf
terraform {
  required_version = ">= 1.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
  }
}

# Provider configurations
provider "aws" {
  region = "us-east-1"
}

provider "google" {
  project = "my-gcp-project"
  region  = "us-central1"
}

provider "azurerm" {
  features {}  # Required empty block (yes, really)
}

Để ý cách mỗi provider có configuration quirks riêng của nó:

  • AWS muốn region
  • GCP muốn projectregion
  • Azure đòi features {} block ngay cả khi nó empty

Chào mừng đến multi-cloud! Mọi thứ gần giống nhau nhưng khác biệt tinh tế theo những cách sẽ frustrate bạn lúc 11 giờ tối đó.

Authentication: Ba Cách Khác Nhau Để Nói "Log In"

AWS dùng standard credential chain:

export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"

Hoặc dùng ~/.aws/credentials, hoặc IAM roles nếu bạn chạy trên EC2, hoặc OIDC nếu bạn ở CI/CD. Standard AWS stuff.

GCP dùng Application Default Credentials:

export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"

Hoặc dùng gcloud auth application-default login cho local development. GCP có cách riêng của nó.

Azure dùng Azure CLI hoặc service principals:

az login  # Interactive authentication

Hoặc cho automation:

export ARM_CLIENT_ID="your-client-id"
export ARM_CLIENT_SECRET="your-client-secret"
export ARM_TENANT_ID="your-tenant-id"
export ARM_SUBSCRIPTION_ID="your-subscription-id"

Security Warning

KHÔNG BAO GIỜ hardcode credentials trong Terraform files. Dùng environment variables, cloud-native secret managers (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault), hoặc CI/CD pipeline secrets. Đối xử với credentials như nuclear launch codes - bởi vì đối với infrastructure của bạn, chúng về cơ bản là vậy đó.

Cloud Rosetta Stone: Cùng Thứ, Tên Khác Nhau

Mọi cloud làm những thứ giống nhau - virtual machines, object storage, databases - nhưng với tên resources và configuration styles hoàn toàn khác nhau.

Đây là decoder ring của bạn.

Virtual Machines: Ba Cách Thuê Một Máy Tính

AWS EC2 Instance:

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"  # Ubuntu 22.04
  instance_type = "t3.micro"

  tags = {
    Name        = "web-server"
    Environment = "production"
  }
}

Ngắn gọn và sweet. AWS pioneered cloud computing, nên API của họ tương đối straightforward.

GCP Compute Engine:

resource "google_compute_instance" "web" {
  name         = "web-server"
  machine_type = "e2-micro"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "ubuntu-os-cloud/ubuntu-2204-lts"
    }
  }

  network_interface {
    network = "default"
    access_config {}  # Ephemeral public IP
  }

  labels = {
    environment = "production"
  }
}

Verbose hơn. GCP yêu cầu explicit boot disk và network configuration. Hơn nữa, họ gọi tags là "labels" bởi vì consistency bị overrated.

Azure Virtual Machine:

resource "azurerm_resource_group" "main" {
  name     = "web-resources"
  location = "East US"
}

resource "azurerm_linux_virtual_machine" "web" {
  name                = "web-server"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  size                = "Standard_B1s"

  admin_username = "adminuser"
  admin_ssh_key {
    username   = "adminuser"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  network_interface_ids = [
    azurerm_network_interface.main.id,
  ]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }

  tags = {
    environment = "production"
  }
}

Azure đưa verbosity lên tầm cao mới. Bạn cần resource group (container cho resources khác), network interface (resource riêng), và image reference với publisher/offer/SKU. Buckle up đi.

Quick comparison:

ConceptAWSGCPAzure
Resourceaws_instancegoogle_compute_instanceazurerm_linux_virtual_machine
ImageAMI IDImage family/projectPublisher/Offer/SKU
Sizet3.microe2-microStandard_B1s
LocationRegion (implicit)Zone (explicit)Location (via resource group)
MetadataTagsLabelsTags

Cùng concept. Execution hoàn toàn khác nhau.

Object Storage: Buckets All the Way Down

AWS S3:

resource "aws_s3_bucket" "data" {
  bucket = "my-company-data-bucket"

  tags = {
    Purpose = "analytics"
  }
}

resource "aws_s3_bucket_versioning" "data" {
  bucket = aws_s3_bucket.data.id

  versioning_configuration {
    status = "Enabled"
  }
}

Versioning là separate resource kể từ AWS provider v4. Because reasons.

GCP Cloud Storage:

resource "google_storage_bucket" "data" {
  name     = "my-company-data-bucket"
  location = "US"

  versioning {
    enabled = true
  }

  labels = {
    purpose = "analytics"
  }
}

Cleaner hơn. Versioning là inline. Labels thay vì tags.

Azure Blob Storage:

resource "azurerm_storage_account" "data" {
  name                     = "mycompanydatastorage"  # Lowercase, globally unique
  resource_group_name      = azurerm_resource_group.main.name
  location                 = azurerm_resource_group.main.location
  account_tier             = "Standard"
  account_replication_type = "LRS"

  tags = {
    purpose = "analytics"
  }
}

resource "azurerm_storage_container" "data" {
  name                  = "data-bucket"
  storage_account_name  = azurerm_storage_account.data.name
  container_access_type = "private"
}

Azure dùng two-level hierarchy: Storage Account (parent) → Container (child). Storage account name phải globally unique, lowercase, và không thể có hyphens. Enjoy debugging validation error đó nhé.

Key differences:

  • AWS: Bucket name globally unique, versioning là separate resource
  • GCP: Bucket name globally unique, versioning inline
  • Azure: Storage Account + Container model, strict naming rules

Khi Multi-Cloud Thực Sự Có Ý Nghĩa

Dùng decision framework này trước khi commit vào multi-cloud complexity:

Bạn có multiple cloud providers HÔM NAY?
├─ Không → Stick với single cloud. Chỉ thêm cloud thứ hai với clear business case.
└─ Có → Tiếp tục

Multi-cloud là mandatory (merger, compliance, existing contracts)?
├─ Có → Multi-cloud là required. Optimize cho operational simplicity.
└─ Không → Tiếp tục

Bạn có thể consolidate sang single cloud trong 12 tháng?
├─ Có → Tạo migration plan. Đừng đầu tư vào multi-cloud abstraction.
└─ Không → Embrace multi-cloud. Build cho lâu dài.

Scenario 1: Geographic Coverage

Bạn đang build global CDN và cần presence ở 50+ regions worldwide.

# AWS dominates North America và Europe
provider "aws" {
  alias  = "us_east"
  region = "us-east-1"
}

provider "aws" {
  alias  = "eu_west"
  region = "eu-west-1"
}

# GCP strong ở Asia-Pacific
provider "google" {
  alias  = "asia"
  region = "asia-southeast1"
}

# Azure cho government và compliance regions
provider "azurerm" {
  alias       = "gov"
  environment = "usgovernment"
}

Valid use case. Mỗi cloud có regional coverage khác nhau.

Scenario 2: Best-of-Breed Services

# GCP cho machine learning và analytics
resource "google_bigquery_dataset" "analytics" {
  dataset_id = "web_analytics"
  location   = "US"
}

# AWS cho mature compute ecosystem
resource "aws_ecs_cluster" "app" {
  name = "production-app"
}

# Azure cho enterprise Windows integration
resource "azurerm_active_directory_domain_service" "corp" {
  name                = "corp-domain"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  # ... configuration
}

Chọn best tool cho mỗi job. Defensible nếu bạn có team để support nó.

Provider Aliases: Multiple Instances của Same Cloud

Đôi khi bạn cần multiple configurations của cùng provider - deploying sang multiple AWS regions chẳng hạn.

Multi-Region AWS Deployment

# providers.tf
provider "aws" {
  region = "us-east-1"
  alias  = "us_east"
}

provider "aws" {
  region = "eu-west-1"
  alias  = "eu_west"
}

provider "aws" {
  region = "ap-southeast-1"
  alias  = "asia"
}

# main.tf
resource "aws_s3_bucket" "us_data" {
  provider = aws.us_east
  bucket   = "my-app-us-data"
}

resource "aws_s3_bucket" "eu_data" {
  provider = aws.eu_west
  bucket   = "my-app-eu-data"
}

resource "aws_s3_bucket" "asia_data" {
  provider = aws.asia
  bucket   = "my-app-asia-data"
}

Critical rule: Resources không có explicit provider = dùng default provider (cái không có alias). Hãy explicit để tránh surprises nhé.

Cross-Cloud Networking: Where Dreams Go to Die

Bạn muốn AWS VPC của bạn talk với GCP VPC của bạn? Buckle up, đây là nơi multi-cloud trở nên painful.

Mỗi cloud có VPC models khác nhau, IP addressing schemes, routing paradigms, và peering mechanisms. Và data egress fees? Brutal.

Reality Check

Cross-cloud VPNs đắt (data egress fees eye-watering), operationally complex (asymmetric routing, MTU issues, BGP debugging lúc 3 giờ sáng), và often unnecessary. Dùng cloud-native public APIs với authentication thay vì whenever possible nhé.

Smart Alternative: Public API Integration

Thay vì private networking, expose services qua authenticated public APIs:

# AWS: Expose API Gateway
resource "aws_api_gateway_rest_api" "app" {
  name = "app-api"
}

# GCP: Call AWS API từ Cloud Run
resource "google_cloud_run_service" "worker" {
  name     = "data-processor"
  location = "us-central1"

  template {
    spec {
      containers {
        image = "gcr.io/my-project/worker:latest"
        env {
          name  = "AWS_API_URL"
          value = "https://${aws_api_gateway_rest_api.app.id}.execute-api.us-east-1.amazonaws.com"
        }
      }
    }
  }
}

Tại sao cái này tốt hơn:

  • Không có VPN complexity
  • Standard HTTPS encryption (TLS 1.3)
  • Cloud-native authentication (AWS Signature v4, GCP OAuth2)
  • Pay per API request, không phải 24/7 VPN tunnel uptime
  • Easier debugging (standard HTTP tools work)

Checkpoint Questions

Trước khi move sang Part 9, đảm bảo bạn hiểu:

  1. Ba lý do business hợp lệ để đi multi-cloud là gì? (M&A, geographic compliance, best-of-breed services)

  2. Sự khác biệt giữa multi-cloud và multi-region là gì? (Multi-cloud = different providers; multi-region = same provider, different locations)

  3. Làm thế nào để config Terraform dùng multiple cloud providers? (Multiple entries trong required_providers block, multiple provider configurations)

  4. Provider alias là gì và khi nào dùng nó? (Multiple instances of same provider cho different regions/accounts)

  5. So sánh VM creation: Tạo VM khác nhau thế nào giữa AWS, GCP, và Azure? (Different resource names, configuration styles, required fields)

  6. Tại sao cross-cloud networking phức tạp? (Different VPC models, egress fees, routing complexity, operational overhead)

  7. Alternative đơn giản hơn cho VPN-based cross-cloud networking là gì? (Public APIs với authentication)

  8. Khi nào nên tránh multi-cloud? (Single cloud meets requirements, team thiếu multi-cloud expertise, không có clear business case, early-stage company)

Checkpoint!

Multi-cloud là tool, không phải religion. Dùng nó khi business requirements đòi hỏi - mergers, compliance, geographic reach, hoặc specific cloud services. Tránh nó khi single-cloud simplicity serve bạn tốt hơn. Architecture tốt nhất là cái team của bạn có thể operate reliably lúc 3 giờ sáng Chủ Nhật đó.

What's Next: Part 9 - Terraform Backends & Remote State

Bạn đã chạy terraform apply trên laptop của bạn. Điều đó ổn cho việc học.

Nhưng điều gì xảy ra khi Sarah chạy terraform apply trên laptop của cô ấy cùng lúc bạn làm vậy?

State conflicts. Infrastructure corruption. Production outages. Panic.

Trong Part 9, mình sẽ giải quyết team collaboration với remote backends:

  • Tại sao local state files break teams (và cách fix nó)
  • Configuring remote backends (S3, GCS, Azure Storage)
  • State locking với DynamoDB/Cloud Storage (preventing simultaneous applies)
  • Migrating existing state sang remote backends (without destroying everything)
  • Workspace strategies cho multi-environment management

The problem:

Developer A: terraform apply (starts)
Developer B (10 giây sau): terraform apply (starts)
Kết quả: State file corruption! Ai tạo cái gì? Không ai biết!

The solution: Remote state với locking. Hẹn gặp bạn ở Part 9 nhé.


Series navigation:


Post này là part của series "Terraform from Fundamentals to Production". Follow along để master Infrastructure as Code với Terraform.