- Published on
Multi-Cloud戦略&マイグレーション完全ガイド2025:AWS/GCP/Azure比較、ハイブリッドクラウド
- Authors

- Name
- Youngju Kim
- @fjvbn20031
目次
1. なぜMulti-Cloudなのか?
クラウド市場が成熟(せいじゅく)するにつれ、単一のクラウドプロバイダーにすべてのワークロードを集中させる戦略はますますリスクが高くなっています。2025年時点でFortune 500企業の約89%がマルチクラウド戦略を採用しており、平均して2.6個のパブリッククラウドを使用しています。
1.1 ベンダーロックイン(Vendor Lock-in)リスク
単一クラウドに依存する際の主なリスク:
- 価格交渉力(かかくこうしょうりょく)の喪失:代替手段がなければプロバイダーの値上げに従属
- サービス中断リスク:2024年に主要クラウドプロバイダーは平均4.2件の大規模障害(しょうがい)を発生
- 技術的依存:独自サービス(AWS Lambda、Azure Functionsなど)使用時、移行コストが指数関数的に増加
- 規制変更:データ主権法(しゅけんほう)、規制変更時の柔軟な対応が不可能
1.2 Multi-Cloudを選択する4つの理由
Best-of-Breed戦略:各クラウドの強みを活用します。
- AWS:最も広いサービスポートフォリオ、エンタープライズエコシステム
- GCP:データ分析(BigQuery)、AI/ML(Vertex AI)、Kubernetes(GKE)
- Azure:エンタープライズ統合(Active Directory、Office 365)、ハイブリッド(Azure Arc)
規制準拠(Compliance):業界・地域別のデータ要件を満たす
- 金融:特定データの国内リージョン保存義務
- 医療:HIPAA準拠可能なサービス選択
- 公共:政府専用クラウドリージョン活用
災害復旧(DR):プロバイダーレベルの障害に備える
- 単一クラウドDR:リージョン間レプリケーション(同一プロバイダー内)
- マルチクラウドDR:プロバイダー間レプリケーション(AWS障害時にGCPへフェイルオーバー)
コスト最適化:ワークロードごとに最適な価格を選択
- スポット/プリエンプティブルインスタンスの価格差を活用
- コミット使用割引(Reserved/Committed Use)を戦略的に分配
- データエグレスコストを比較して最適配置
1.3 Multi-Cloudの現実的な課題
マルチクラウドは万能ではありません。必ず考慮すべき課題:
| 課題 | 説明 | 緩和戦略 |
|---|---|---|
| 複雑性の増加 | 2〜3倍の運用オーバーヘッド | IaC、統合管理プラットフォーム |
| 人材不足 | 各クラウドの専門家が必要 | 抽象化レイヤー、研修投資 |
| ネットワークコスト | クラウド間データ転送コスト | データローカリティ設計 |
| セキュリティ統合 | 異なるIAM/セキュリティモデル | Zero Trust、統合IdP |
| 一貫性の維持 | サービスごとの動作差異 | 標準化された抽象化レイヤー |
2. AWS vs GCP vs Azure:サービスマッピング
2.1 コンピューティングサービス比較
| カテゴリ | AWS | GCP | Azure |
|---|---|---|---|
| 仮想マシン | EC2 | Compute Engine | Virtual Machines |
| コンテナオーケストレーション | EKS | GKE | AKS |
| サーバーレスコンテナ | Fargate | Cloud Run | Container Apps |
| サーバーレス関数 | Lambda | Cloud Functions | Azure Functions |
| バッチ処理 | AWS Batch | Cloud Batch | Azure Batch |
| アプリプラットフォーム | Elastic Beanstalk | App Engine | App Service |
| VMware統合 | VMware Cloud on AWS | Google Cloud VMware Engine | Azure VMware Solution |
2.2 ストレージサービス比較
| カテゴリ | AWS | GCP | Azure |
|---|---|---|---|
| オブジェクトストレージ | S3 | Cloud Storage | Blob Storage |
| ブロックストレージ | EBS | Persistent Disk | Managed Disks |
| ファイルストレージ | EFS | Filestore | Azure Files |
| アーカイブ | S3 Glacier | Archive Storage | Archive Storage |
| ハイブリッドストレージ | Storage Gateway | Transfer Appliance | StorSimple |
2.3 データベースサービス比較
| カテゴリ | AWS | GCP | Azure |
|---|---|---|---|
| リレーショナルDB | RDS, Aurora | Cloud SQL, AlloyDB | Azure SQL, MySQL/PostgreSQL |
| NoSQLドキュメント | DynamoDB | Firestore | Cosmos DB |
| インメモリ | ElastiCache | Memorystore | Azure Cache for Redis |
| グラフDB | Neptune | - | Cosmos DB (Gremlin) |
| 時系列DB | Timestream | - | Azure Data Explorer |
| グローバル分散DB | Aurora Global, DynamoDB Global Tables | Spanner | Cosmos DB |
2.4 ネットワーキングサービス比較
| カテゴリ | AWS | GCP | Azure |
|---|---|---|---|
| 仮想ネットワーク | VPC | VPC | VNet |
| ロードバランサー | ALB/NLB/GLB | Cloud Load Balancing | Azure Load Balancer/App Gateway |
| CDN | CloudFront | Cloud CDN | Azure CDN/Front Door |
| DNS | Route 53 | Cloud DNS | Azure DNS |
| 専用接続 | Direct Connect | Cloud Interconnect | ExpressRoute |
| VPN | Site-to-Site VPN | Cloud VPN | VPN Gateway |
| サービスメッシュ | App Mesh | Traffic Director | - |
2.5 AI/MLサービス比較
| カテゴリ | AWS | GCP | Azure |
|---|---|---|---|
| MLプラットフォーム | SageMaker | Vertex AI | Azure ML |
| LLMサービス | Bedrock | Gemini API, Model Garden | Azure OpenAI Service |
| 自然言語処理 | Comprehend | Natural Language AI | Cognitive Services |
| 画像分析 | Rekognition | Vision AI | Computer Vision |
| 音声処理 | Transcribe/Polly | Speech-to-Text/Text-to-Speech | Speech Services |
| レコメンデーション | Personalize | Recommendations AI | Personalizer |
2.6 データ分析比較
| カテゴリ | AWS | GCP | Azure |
|---|---|---|---|
| データウェアハウス | Redshift | BigQuery | Synapse Analytics |
| ストリーム処理 | Kinesis | Dataflow | Stream Analytics |
| ETL/ELT | Glue | Dataflow, Dataproc | Data Factory |
| データカタログ | Glue Data Catalog | Data Catalog | Purview |
| BIツール | QuickSight | Looker | Power BI |
3. マルチクラウドアーキテクチャパターン
3.1 Active-Activeパターン
2つ以上のクラウドで同時にトラフィックを処理します。
┌─────────────────────┐
│ Global DNS / LB │
│ (Route 53 / CF) │
└──────────┬──────────┘
┌─────┴─────┐
│ │
┌────▼────┐ ┌────▼────┐
│ AWS │ │ GCP │
│ Region │ │ Region │
│ │ │ │
│ ┌─────┐ │ │ ┌─────┐ │
│ │ K8s │ │ │ │ GKE │ │
│ │ EKS │ │ │ │ │ │
│ └──┬──┘ │ │ └──┬──┘ │
│ │ │ │ │ │
│ ┌──▼──┐ │ │ ┌──▼──┐ │
│ │ DB │◄┼─┼─► DB │ │
│ │ RDS │ │ │ │ SQL │ │
│ └─────┘ │ │ └─────┘ │
└─────────┘ └─────────┘
メリット:最大の可用性、ゼロダウンタイムフェイルオーバー デメリット:データ同期の複雑さ、高コスト 適切なケース:ミッションクリティカルサービス、グローバルサービス
3.2 Active-Passiveパターン
プライマリクラウドがトラフィックを処理し、セカンダリクラウドはDR用にスタンバイします。
┌────────────────────┐
│ Global DNS │
└────────┬───────────┘
│
┌────────▼────────┐ ┌────────────────┐
│ AWS (Active) │ 複製 ──►│ Azure (Passive)│
│ │ │ │
│ ┌───────────┐ │ │ ┌───────────┐ │
│ │ Workloads │ │ │ │ Standby │ │
│ └───────────┘ │ │ └───────────┘ │
│ ┌───────────┐ │ │ ┌───────────┐ │
│ │ Database │──┼──────────┼─►│ Replica │ │
│ └───────────┘ │ │ └───────────┘ │
└─────────────────┘ └────────────────┘
メリット:合理的なコスト、クラウドレベルのDR デメリット:フェイルオーバー時のダウンタイム、パッシブリソースのコスト 適切なケース:高可用性は必要だがコストに敏感な場合
3.3 Cloud Burstingパターン
通常はオンプレミス/プライマリクラウドで処理し、ピーク時にセカンダリクラウドへ拡張します。
# Kubernetes Federation - Cloud Bursting例
apiVersion: types.kubefed.io/v1beta1
kind: FederatedDeployment
metadata:
name: web-app
namespace: production
spec:
template:
spec:
replicas: 10
containers:
- name: web
image: registry.example.com/web-app:v2.1
placement:
clusters:
- name: on-prem-cluster
weight: 70
- name: aws-eks-cluster
weight: 20
- name: gcp-gke-cluster
weight: 10
overrides:
- clusterName: aws-eks-cluster
clusterOverrides:
- path: "/spec/replicas"
value: 5
3.4 Arbitrage(アービトラージ)パターン
ワークロード特性に応じて、最もコスト効率の良いクラウドに配置します。
# クラウドコスト比較と自動配置の例
class CloudArbitrage:
def __init__(self):
self.providers = {
"aws": AWSProvider(),
"gcp": GCPProvider(),
"azure": AzureProvider()
}
def find_optimal_placement(self, workload):
costs = {}
for name, provider in self.providers.items():
cost = provider.estimate_cost(
cpu=workload.cpu_cores,
memory_gb=workload.memory_gb,
storage_gb=workload.storage_gb,
gpu=workload.gpu_type,
duration_hours=workload.expected_duration,
region=workload.preferred_region
)
costs[name] = cost
# コスト対性能スコアを計算
scores = {}
for name, cost in costs.items():
perf = self.providers[name].benchmark_score(workload.type)
scores[name] = perf / cost
best = max(scores, key=scores.get)
return best, costs[best], scores[best]
def auto_schedule(self, workloads):
placements = []
for wl in workloads:
provider, cost, score = self.find_optimal_placement(wl)
placements.append({
"workload": wl.name,
"provider": provider,
"estimated_cost": cost,
"efficiency_score": score
})
return placements
4. ハイブリッドクラウドソリューション
4.1 Google Anthos
AnthosはGKEをベースに、オンプレミス、AWS、Azureでも同一のKubernetes環境を提供します。
# Anthos Config Management - マルチクラスター設定
apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
name: config-management
spec:
clusterName: production-cluster
git:
syncRepo: https://github.com/org/anthos-config
syncBranch: main
secretType: ssh
policyDir: "policies"
policyController:
enabled: true
templateLibraryInstalled: true
referentialRulesEnabled: true
hierarchyController:
enabled: true
enablePodTreeLabels: true
enableHierarchicalResourceQuotas: true
Anthosのコアコンポーネント:
- Anthos on GKE:GCP内のマネージドKubernetes
- Anthos on VMware:オンプレミスvSphere上でGKEを実行
- Anthos on AWS:AWS上のAnthosマネージドクラスター
- Anthos on Azure:Azure上のAnthosマネージドクラスター
- Anthos Config Management:GitOpsベースのマルチクラスターポリシー管理
- Anthos Service Mesh:Istioベースのサービスメッシュ統合管理
4.2 Azure Arc
Azure Arcは、Azure管理プレーンをオンプレミス、AWS、GCPなどどこにでも拡張します。
# Azure ArcにKubernetesクラスターを登録
az connectedk8s connect \
--name production-eks \
--resource-group multi-cloud-rg \
--location eastus \
--tags "environment=production" "cloud=aws"
# Arc対応データサービスのデプロイ
az arcdata dc create \
--name arc-dc \
--k8s-namespace arc \
--connectivity-mode indirect \
--resource-group multi-cloud-rg \
--location eastus \
--storage-class managed-premium \
--profile-name azure-arc-kubeadm
# Arc対応SQL Managed Instance
az sql mi-arc create \
--name sql-prod \
--resource-group multi-cloud-rg \
--location eastus \
--storage-class-data managed-premium \
--storage-class-logs managed-premium \
--cores-limit 8 \
--memory-limit 32Gi \
--k8s-namespace arc
4.3 AWS EKS Anywhere
EKS Anywhereは、オンプレミスでAWS EKSと同一のKubernetesを実行します。
# EKS Anywhereクラスター設定
apiVersion: anywhere.eks.amazonaws.com/v1alpha1
kind: Cluster
metadata:
name: prod-cluster
spec:
clusterNetwork:
cniConfig:
cilium: {}
pods:
cidrBlocks:
- "192.168.0.0/16"
services:
cidrBlocks:
- "10.96.0.0/12"
controlPlaneConfiguration:
count: 3
endpoint:
host: "10.0.0.100"
machineGroupRef:
kind: VSphereMachineConfig
name: cp-machines
workerNodeGroupConfigurations:
- count: 5
machineGroupRef:
kind: VSphereMachineConfig
name: worker-machines
name: md-0
kubernetesVersion: "1.29"
managementCluster:
name: prod-cluster
4.4 Red Hat OpenShift(ハイブリッド)
OpenShiftは、すべての主要クラウドとオンプレミスで一貫したKubernetesプラットフォームを提供します。
# OpenShiftマルチクラスターハブ設定
apiVersion: operator.open-cluster-management.io/v1
kind: MultiClusterHub
metadata:
name: multiclusterhub
namespace: open-cluster-management
spec:
availabilityConfig: High
enableClusterBackup: true
overrides:
components:
- name: cluster-lifecycle
enabled: true
- name: cluster-backup
enabled: true
- name: multicluster-engine
enabled: true
- name: grc
enabled: true
- name: app-lifecycle
enabled: true
5. クラウドマイグレーション6R戦略
5.1 6Rの概要と意思決定ツリー
マイグレーション対象のワークロードを分析する際、6つの戦略(6R)から1つを選択します。
ワークロード分析開始
│
▼
ビジネス価値がある? ─── No ──► Retire(廃止)
│ Yes
▼
変更が必要? ─── No ──► Retain(維持)
│ Yes
▼
SaaSで代替可能? ─── Yes ──► Repurchase(再購入)
│ No
▼
アーキテクチャ変更が必要? ─── No ──► Rehost(リホスト)
│ Yes またはReplatform
▼
完全な再設計が必要? ─── No ──► Replatform(リプラットフォーム)
│ Yes
▼
Refactor(リファクター)
5.2 各戦略の詳細
Rehost(Lift and Shift):
- 既存アプリケーションをそのままクラウドVMに移行
- 最も速くリスクが低い
- クラウドネイティブのメリットは限定的
- AWS Application Migration Service、Azure Migrate、Google Migrate for Compute Engine を活用
Replatform(Lift and Reshape):
- コアアーキテクチャを維持しながらクラウドサービスを活用
- 例:自前のMySQLをRDS/Cloud SQLに移行
- 中程度の労力で運用メリットを即座に確保
Refactor(Re-architect):
- クラウドネイティブに完全再設計
- マイクロサービス、サーバーレス、コンテナ化
- 最も高い労力、最も高いクラウドメリット
- 長期的なコスト削減とスケーラビリティ
Repurchase(Replace):
- SaaS製品に置き換え
- 例:自前のメールサーバーをOffice 365/Google Workspaceに
- 運用負担の完全な排除
Retire(廃止):
- 不要になったワークロードの削除
- 平均して全体の10〜20%が廃止対象
Retain(維持):
- まだマイグレーションの準備ができていないワークロード
- レガシー依存関係、規制要件など
5.3 マイグレーション評価スコアカード
# マイグレーション戦略決定の自動化例
class MigrationAssessor:
def assess_workload(self, workload):
score = {
"business_value": self._rate_business_value(workload),
"technical_complexity": self._rate_complexity(workload),
"cloud_readiness": self._rate_cloud_readiness(workload),
"data_sensitivity": self._rate_data_sensitivity(workload),
"dependency_count": len(workload.dependencies),
"team_skill_level": self._rate_team_skills(workload.team)
}
# 戦略推奨ロジック
if score["business_value"] < 3:
return "Retire"
if score["cloud_readiness"] < 2:
return "Retain"
if workload.has_saas_alternative and score["technical_complexity"] > 7:
return "Repurchase"
if score["technical_complexity"] < 4 and score["cloud_readiness"] > 6:
return "Rehost"
if score["technical_complexity"] < 7:
return "Replatform"
return "Refactor"
def generate_report(self, workloads):
results = {}
for wl in workloads:
strategy = self.assess_workload(wl)
if strategy not in results:
results[strategy] = []
results[strategy].append({
"name": wl.name,
"estimated_effort_weeks": self._estimate_effort(wl, strategy),
"estimated_cost": self._estimate_cost(wl, strategy),
"risk_level": self._assess_risk(wl, strategy)
})
return results
6. マイグレーション計画の策定
6.1 ディスカバリーと依存関係マッピング
マイグレーション前に現在の環境を正確に把握することが重要です。
# AWS Application Discovery Serviceの使用
aws discovery start-continuous-export
# エージェントベースの収集
aws discovery start-data-collection-by-agent-ids \
--agent-ids agent-001 agent-002 agent-003
# サーバー依存関係マップの照会
aws discovery describe-agents \
--filters name=hostName,values=web-server-*,condition=CONTAINS
6.2 TCO(総所有コスト)分析
# TCO比較分析フレームワーク
class TCOAnalysis:
def calculate_on_prem_tco(self, infra):
annual_costs = {
"hardware": infra.server_count * 8000 / 3, # 3年減価償却
"software_licenses": infra.license_costs,
"datacenter": infra.rack_units * 1200, # 電力、冷却、スペース
"network": infra.bandwidth_gbps * 500,
"personnel": infra.fte_count * 120000,
"maintenance": infra.server_count * 2400,
"disaster_recovery": infra.dr_cost_annual,
"security": infra.security_cost_annual,
"compliance": infra.compliance_cost_annual
}
return sum(annual_costs.values()), annual_costs
def calculate_cloud_tco(self, workloads, provider="aws"):
annual_costs = {
"compute": self._estimate_compute(workloads, provider),
"storage": self._estimate_storage(workloads, provider),
"network": self._estimate_network(workloads, provider),
"managed_services": self._estimate_managed(workloads, provider),
"personnel": workloads.cloud_fte * 130000,
"migration_amortized": workloads.migration_cost / 3,
"training": workloads.team_size * 5000,
"tools": workloads.tool_licenses
}
return sum(annual_costs.values()), annual_costs
def compare(self, infra, workloads):
on_prem_total, on_prem_detail = self.calculate_on_prem_tco(infra)
cloud_totals = {}
for provider in ["aws", "gcp", "azure"]:
total, detail = self.calculate_cloud_tco(workloads, provider)
cloud_totals[provider] = {
"total": total,
"detail": detail,
"savings_pct": (on_prem_total - total) / on_prem_total * 100
}
return {
"on_prem": {"total": on_prem_total, "detail": on_prem_detail},
"cloud": cloud_totals
}
6.3 マイグレーションウェーブ計画
大規模なマイグレーションはウェーブ(段階)に分けて実行します。
| ウェーブ | 対象 | 戦略 | 期間 | リスク |
|---|---|---|---|---|
| Wave 0 | パイロット(非重要アプリ2〜3個) | Rehost | 4週間 | 低 |
| Wave 1 | Webフロントエンド、静的サイト | Rehost/Replatform | 6週間 | 低 |
| Wave 2 | APIサーバー、マイクロサービス | Replatform/Refactor | 8週間 | 中 |
| Wave 3 | データベース、ストレージ | Replatform | 6週間 | 高 |
| Wave 4 | レガシーモノリス | Refactor | 12週間 | 高 |
| Wave 5 | 最終移行、クリーンアップ | - | 4週間 | 中 |
7. データマイグレーション戦略
7.1 オンライン vs オフラインマイグレーション
オンラインマイグレーション(ネットワーク転送):
- 100TB以下のデータに適切
- 専用接続(Direct Connect/ExpressRoute)推奨
- 増分同期が可能
オフラインマイグレーション(物理転送):
- AWS Snowball / Snowball Edge:最大80TB/デバイス
- AWS Snowmobile:ペタバイト規模
- Azure Data Box:最大100TB
- Google Transfer Appliance:最大300TB
7.2 データベースマイグレーション
# AWS DMS(Database Migration Service)タスク設定例
# ソース:オンプレミスOracle、ターゲット:Amazon Aurora PostgreSQL
Resources:
DMSReplicationTask:
Type: AWS::DMS::ReplicationTask
Properties:
MigrationType: full-load-and-cdc
SourceEndpointArn: !Ref OracleSourceEndpoint
TargetEndpointArn: !Ref AuroraTargetEndpoint
ReplicationInstanceArn: !Ref DMSReplicationInstance
TableMappings: |
{
"rules": [
{
"rule-type": "selection",
"rule-id": "1",
"rule-name": "select-all-tables",
"object-locator": {
"schema-name": "PROD_SCHEMA",
"table-name": "%"
},
"rule-action": "include"
},
{
"rule-type": "transformation",
"rule-id": "2",
"rule-name": "lowercase-schema",
"rule-action": "convert-lowercase",
"rule-target": "schema",
"object-locator": {
"schema-name": "PROD_SCHEMA"
}
}
]
}
7.3 ストレージ転送
# AWSからGCPへストレージ転送
gcloud transfer jobs create \
--source-agent-pool=transfer-pool \
--source-s3-bucket=my-aws-bucket \
--source-s3-region=us-east-1 \
--destination-gcs-bucket=my-gcp-bucket \
--schedule-starts=2025-01-15T00:00:00Z \
--schedule-repeats-every=24h \
--include-prefixes="data/,backups/" \
--exclude-prefixes="temp/,logs/"
8. アプリケーションマイグレーションパターン
8.1 Strangler Figパターン
既存のモノリスを段階的にマイクロサービスに置き換えます。
Phase 1: プロキシレイヤー追加
┌────────────────┐
│ API Gateway / │
│ Load Balancer │
└───────┬────────┘
│
▼
┌────────────────┐
│ Monolith │ ← 全トラフィック
│ (オンプレミス) │
└────────────────┘
Phase 2: 一部機能を移行
┌────────────────┐
│ API Gateway │
└───┬────────┬───┘
│ │
▼ ▼
┌──────┐ ┌──────────┐
│ New │ │ Monolith │ ← 残りのトラフィック
│ Auth │ │ │
│(Cloud)│ │(オンプレ) │
└──────┘ └──────────┘
Phase 3: 大部分の移行完了
┌────────────────┐
│ API Gateway │
└┬──┬──┬──┬──┬───┘
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌─┐┌─┐┌─┐┌─┐┌────────┐
│A││B││C││D││Monolith│ ← 最小トラフィック
└─┘└─┘└─┘└─┘└────────┘
(Cloud services)
8.2 Blue-Green切り替え
# KubernetesベースのBlue-Green切り替え設定
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: web-app-migration
spec:
replicas: 10
strategy:
blueGreen:
activeService: web-app-active
previewService: web-app-preview
autoPromotionEnabled: false
prePromotionAnalysis:
templates:
- templateName: migration-validation
args:
- name: service-name
value: web-app-preview
postPromotionAnalysis:
templates:
- templateName: post-migration-check
scaleDownDelaySeconds: 3600
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
version: cloud-native
spec:
containers:
- name: web-app
image: registry.example.com/web-app:v3.0-cloud
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
9. マルチクラウドネットワーキング
9.1 クラウド間接続オプション
┌─────────────────────────────────────────────────────┐
│ 接続オプション比較 │
├────────────────┬──────────┬──────────┬──────────────┤
│ │ 帯域幅 │ レイテンシ │ コスト │
├────────────────┼──────────┼──────────┼──────────────┤
│ パブリックインターネット│ 変動 │ 高 │ エグレス費用 │
│ VPN (IPsec) │ 1-3 Gbps│ 中 │ 低 │
│ 専用回線 │ 10-100Gb│ 低 │ 高(月額) │
│ Megaport/Equinix│ 柔軟 │ 低 │ 中 │
└────────────────┴──────────┴──────────┴──────────────┘
9.2 トランジットアーキテクチャ
# Terraform - AWS Transit GatewayとVPN設定
resource "aws_ec2_transit_gateway" "main" {
description = "Multi-cloud transit gateway"
default_route_table_association = "disable"
default_route_table_propagation = "disable"
auto_accept_shared_attachments = "enable"
tags = {
Name = "multi-cloud-tgw"
}
}
resource "aws_vpn_connection" "to_gcp" {
customer_gateway_id = aws_customer_gateway.gcp.id
transit_gateway_id = aws_ec2_transit_gateway.main.id
type = "ipsec.1"
static_routes_only = false
tunnel1_inside_cidr = "169.254.10.0/30"
tunnel2_inside_cidr = "169.254.10.4/30"
tags = {
Name = "aws-to-gcp-vpn"
}
}
resource "aws_customer_gateway" "gcp" {
bgp_asn = 65000
ip_address = var.gcp_vpn_gateway_ip
type = "ipsec.1"
tags = {
Name = "gcp-customer-gateway"
}
}
9.3 サービスメッシュ(マルチクラウド)
# Istioマルチクラスター設定(Primary-Remote)
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio-primary
spec:
values:
global:
meshID: multi-cloud-mesh
multiCluster:
clusterName: aws-cluster
network: aws-network
pilot:
env:
EXTERNAL_ISTIOD: "true"
meshConfig:
defaultConfig:
proxyMetadata:
ISTIO_META_DNS_CAPTURE: "true"
ISTIO_META_DNS_AUTO_ALLOCATE: "true"
components:
ingressGateways:
- name: istio-eastwestgateway
label:
istio: eastwestgateway
topology.istio.io/network: aws-network
enabled: true
k8s:
env:
- name: ISTIO_META_REQUESTED_NETWORK_VIEW
value: aws-network
10. アイデンティティフェデレーション
10.1 マルチクラウドIAM戦略
┌─────────────────────────────────────┐
│ 中央アイデンティティプロバイダー │
│ (Okta / Azure AD / Google) │
└──────────┬──────────────────────────┘
│ SAML / OIDC
┌─────┼──────┬───────┐
▼ ▼ ▼ ▼
┌─────┐┌─────┐┌──────┐┌─────────┐
│ AWS ││ GCP ││Azure ││On-Prem │
│ IAM ││ IAM ││ AD ││ LDAP │
└─────┘└─────┘└──────┘└─────────┘
10.2 OIDCベースのクラウド間認証
# AWSからGCPリソースへのアクセス(Workload Identity Federation)
import google.auth
from google.auth import impersonated_credentials
import boto3
class CrossCloudAuth:
def get_gcp_credentials_from_aws(self):
# AWS STSから現在の認証情報を確認
sts = boto3.client("sts")
aws_identity = sts.get_caller_identity()
# GCP Workload Identity Federationを使用
credentials, project = google.auth.default(
scopes=["https://www.googleapis.com/auth/cloud-platform"]
)
# サービスアカウントのインパーソネーション
target_credentials = impersonated_credentials.Credentials(
source_credentials=credentials,
target_principal="cross-cloud@project.iam.gserviceaccount.com",
target_scopes=["https://www.googleapis.com/auth/cloud-platform"],
lifetime=3600
)
return target_credentials
11. クラウドネイティブポータビリティ
11.1 Kubernetesベースの抽象化
# マルチクラウドKubernetesデプロイ(Helm values)
# values-aws.yaml
cloud:
provider: aws
region: us-east-1
storageClass: gp3
ingressClass: alb
serviceAnnotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
# values-gcp.yaml
cloud:
provider: gcp
region: us-central1
storageClass: pd-ssd
ingressClass: gce
serviceAnnotations:
cloud.google.com/neg: '{"ingress": true}'
# values-azure.yaml
cloud:
provider: azure
region: eastus
storageClass: managed-premium
ingressClass: azure-application-gateway
serviceAnnotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "false"
11.2 Terraformマルチクラウドモジュール
# modules/compute/main.tf - クラウド抽象化レイヤー
variable "cloud_provider" {
type = string
validation {
condition = contains(["aws", "gcp", "azure"], var.cloud_provider)
error_message = "Supported providers: aws, gcp, azure"
}
}
variable "instance_config" {
type = object({
name = string
cpu = number
memory_gb = number
disk_gb = number
os = string
})
}
# AWS実装
module "aws_compute" {
source = "./aws"
count = var.cloud_provider == "aws" ? 1 : 0
instance_type = local.aws_instance_map[
"${var.instance_config.cpu}-${var.instance_config.memory_gb}"
]
ami_id = local.aws_ami_map[var.instance_config.os]
volume_size = var.instance_config.disk_gb
name = var.instance_config.name
}
# GCP実装
module "gcp_compute" {
source = "./gcp"
count = var.cloud_provider == "gcp" ? 1 : 0
machine_type = local.gcp_machine_map[
"${var.instance_config.cpu}-${var.instance_config.memory_gb}"
]
image = local.gcp_image_map[var.instance_config.os]
disk_size = var.instance_config.disk_gb
name = var.instance_config.name
}
# Azure実装
module "azure_compute" {
source = "./azure"
count = var.cloud_provider == "azure" ? 1 : 0
vm_size = local.azure_vm_map[
"${var.instance_config.cpu}-${var.instance_config.memory_gb}"
]
image_ref = local.azure_image_map[var.instance_config.os]
disk_size = var.instance_config.disk_gb
name = var.instance_config.name
}
output "instance_id" {
value = coalesce(
try(module.aws_compute[0].instance_id, ""),
try(module.gcp_compute[0].instance_id, ""),
try(module.azure_compute[0].instance_id, "")
)
}
11.3 OCIコンテナイメージ戦略
# マルチステージビルド - クラウド非依存イメージ
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server ./cmd/server
# 最終イメージ - distroless(クラウド非依存)
FROM gcr.io/distroless/static-debian12:nonroot
COPY /app/server /server
COPY /app/config /config
EXPOSE 8080
USER nonroot:nonroot
ENTRYPOINT ["/server"]
12. マルチクラウド災害復旧(DR)
12.1 DR戦略比較
| DR戦略 | RTO | RPO | コスト | 複雑性 |
|---|---|---|---|---|
| Backup and Restore | 時間単位 | 時間単位 | 低 | 低 |
| Pilot Light | 10〜30分 | 分単位 | 中 | 中 |
| Warm Standby | 分単位 | 秒単位 | 高 | 高 |
| Active-Active | 秒単位 | ほぼ0 | 非常に高い | 非常に高い |
12.2 マルチクラウドDR実装
# マルチクラウドDRオーケストレーター
class MultiCloudDR:
def __init__(self):
self.primary = AWSProvider(region="us-east-1")
self.secondary = AzureProvider(region="eastus")
self.health_checker = HealthChecker()
def execute_failover(self):
"""Primary(AWS)障害時にSecondary(Azure)へ切り替え"""
steps = [
self._verify_secondary_health,
self._promote_database_replica,
self._update_dns_records,
self._scale_up_secondary,
self._verify_application_health,
self._notify_stakeholders
]
for step in steps:
result = step()
if not result.success:
self._rollback_failover(result.step_index)
raise FailoverError(f"Failed at step: {step.__name__}")
def _promote_database_replica(self):
"""Azure SQL読み取りレプリカをプライマリに昇格"""
self.secondary.promote_replica(
server="dr-sql-server",
database="production-db",
failover_group="prod-failover-group"
)
def continuous_replication(self):
"""継続的なデータ同期"""
replication_config = {
"database": {
"type": "async",
"lag_threshold_seconds": 30,
"source": "aws-rds-primary",
"target": "azure-sql-replica"
},
"storage": {
"type": "incremental",
"interval_minutes": 15,
"source": "s3://prod-bucket",
"target": "azure://prod-container"
}
}
return replication_config
13. マルチクラウドコスト管理
13.1 統合コストモニタリング
# マルチクラウドコストダッシュボードコレクター
class MultiCloudCostCollector:
def collect_all_costs(self, period="monthly"):
aws_costs = self._get_aws_costs(period)
gcp_costs = self._get_gcp_costs(period)
azure_costs = self._get_azure_costs(period)
return {
"total": aws_costs["total"] + gcp_costs["total"] + azure_costs["total"],
"by_provider": {
"aws": aws_costs,
"gcp": gcp_costs,
"azure": azure_costs
},
"by_service": self._aggregate_by_service(
aws_costs, gcp_costs, azure_costs
),
"anomalies": self._detect_anomalies(
aws_costs, gcp_costs, azure_costs
),
"recommendations": self._generate_optimization_recommendations(
aws_costs, gcp_costs, azure_costs
)
}
def _detect_anomalies(self, *provider_costs):
"""コスト異常検知"""
anomalies = []
for costs in provider_costs:
for service, cost in costs["by_service"].items():
avg = cost.get("rolling_avg_30d", 0)
current = cost.get("current", 0)
if avg > 0 and current > avg * 1.5:
anomalies.append({
"service": service,
"provider": costs["provider"],
"current": current,
"average": avg,
"increase_pct": (current - avg) / avg * 100
})
return anomalies
13.2 コスト最適化戦略
| 戦略 | 削減率 | 適用対象 |
|---|---|---|
| Reserved/Committed Use | 30〜60% | 安定したワークロード |
| スポット/プリエンプティブルインスタンス | 60〜90% | バッチ、テスト |
| オートスケーリング | 20〜40% | 変動トラフィック |
| 適正サイズ(Right-sizing) | 15〜35% | 全ワークロード |
| ストレージティアリング | 40〜70% | アーカイブデータ |
| ネットワーク最適化 | 10〜30% | クロスクラウド通信 |
14. ガバナンスとコンプライアンス
14.1 マルチクラウドガバナンスフレームワーク
# Open Policy Agent (OPA) - マルチクラウドポリシー
package multicloud.governance
# 全リソースに必須タグを要求
required_tags := ["environment", "team", "cost-center", "data-classification"]
deny[msg] {
resource := input.resource
tag := required_tags[_]
not resource.tags[tag]
msg := sprintf(
"Resource %v is missing required tag: %v",
[resource.name, tag]
)
}
# データ主権 - 特定データは特定リージョンのみに保存
deny[msg] {
resource := input.resource
resource.tags["data-classification"] == "pii-jp"
not startswith(resource.region, "ap-northeast-1")
not startswith(resource.region, "japan")
msg := sprintf(
"Japanese PII data must be stored in Japan region. Resource %v in %v",
[resource.name, resource.region]
)
}
# 暗号化必須
deny[msg] {
resource := input.resource
resource.type == "storage_bucket"
not resource.encryption.enabled
msg := sprintf(
"Storage %v must have encryption enabled",
[resource.name]
)
}
15. 実践クイズ
Q1. マルチクラウドアーキテクチャにおけるActive-ActiveパターンとActive-Passiveパターンの主な違いと、それぞれの適切な状況を説明してください。
Active-Active:両方のクラウドが同時にトラフィックを処理します。最大の可用性を提供しますが、データ同期の複雑さとコストが高くなります。ミッションクリティカルなサービスやグローバルサービスに適しています。
Active-Passive:プライマリクラウドのみがトラフィックを処理し、セカンダリクラウドはDR用にスタンバイします。コストは合理的ですが、フェイルオーバー時に若干のダウンタイムが発生します。高可用性は必要だがコストに敏感な場合に適しています。
主な違いは同時処理の有無と**フェイルオーバー時間(RTO)**です。Active-ActiveのRTOはほぼ0で、Active-Passiveは数分のRTOがあります。
Q2. 6Rマイグレーション戦略のReplatformとRefactorの違いを説明し、それぞれの適切なユースケースを示してください。
Replatform:コアアーキテクチャを維持しながら一部をクラウドマネージドサービスに置き換えます。例えば自前のMySQLをAmazon RDSに移行したり、自前のRedisをElastiCacheに置き換えたりします。中程度の労力で運用メリットを素早く得られます。
Refactor:クラウドネイティブに完全再設計します。モノリスをマイクロサービスに分解したり、サーバーレスアーキテクチャに移行したりします。最も高い労力が必要ですが、長期的に最大のクラウドメリットを得られます。
Replatformは素早い成果が必要な場合に、Refactorは長期的なイノベーションが目標の場合に適しています。
Q3. Workload Identity Federationとは何か、なぜサービスアカウントキーより安全なのかを説明してください。
Workload Identity Federationは、外部IdP(AWS IAM、Azure ADなど)の認証情報をGCPの一時トークンに交換するメカニズムです。
サービスアカウントキーより安全な理由:
- 鍵管理が不要:JSONキーファイルの生成・配布・ローテーションが不要
- 一時トークン:交換されたトークンは1時間後に自動失効(しっこう)
- 最小権限:特定の属性(ロール、タグなど)に基づくきめ細かいアクセス制御
- 監査が容易:すべてのトークン交換がCloud Audit Logsに記録
- 漏洩(ろうえい)リスクの低減:長期的な認証情報が存在しないため漏洩するものがない
Q4. Strangler Figパターンでモノリスをマイクロサービスに移行する際の主要なステップと注意点を説明してください。
主要なステップ:
- プロキシ/API Gateway追加:すべてのトラフィックがゲートウェイを経由するように設定
- 機能の特定:分離可能な境界づけられたコンテキストを特定
- 段階的な抽出:一つずつマイクロサービスとして抽出し、ゲートウェイでルーティング変更
- データ分離:共有DBからサービスごとのDBに分離
- モノリスの縮小:すべての機能抽出後にモノリスを廃止
注意点:
- データベース分離が最も困難な部分 - トランザクション整合性に注意
- 一度に多くのサービスを抽出しないこと
- サービス間通信パターン(同期/非同期)を慎重に決定
- モニタリング/オブザーバビリティを先に構築してからマイグレーション開始
- ロールバック計画は必須
Q5. マルチクラウド環境でデータエグレス(egress)コストを最適化する戦略を3つ以上提示してください。
- データローカリティ設計:処理エンジンをデータが存在するクラウドに配置。データを移動させずコンピューティングを移動
- CDN活用:クラウド内部から外部へ出るトラフィックをCDNでキャッシュしてオリジンエグレスを削減
- 圧縮とプロトコル最適化:gRPC、Protobufなど効率的なシリアライゼーションで転送データサイズを削減
- 専用接続(Dedicated Interconnect):Direct Connect、ExpressRouteなどを使用するとインターネット経由より低いエグレスコスト
- 非同期バッチ転送:リアルタイム転送の代わりにデータを集めてオフピーク時にバッチ転送
- プライベートピアリング:Megaport、Equinix Fabricなど中立的な交換ポイントを通じてクラウド間の直接ピアリング
参考資料
- AWS Well-Architected Framework - Multi-Cloud
- Google Cloud - Hybrid and Multi-Cloud Patterns
- Azure Architecture Center - Multi-Cloud
- HashiCorp - Multi-Cloud with Terraform
- CNCF Multi-Cloud Reference Architecture
- Gartner - Cloud Migration Strategies
- AWS Migration Hub Documentation
- Google Anthos Documentation
- Azure Arc Documentation
- Istio Multi-Cluster Documentation
- Open Policy Agent Documentation
- Kubernetes Federation v2
- FinOps Foundation - Multi-Cloud Cost Management