技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
cloud-migration【数据与研究】Use this skill when the user says 'cloud migration', 'migrate to cloud', 'lift and shift', 'rehost', 'replatform', 'refactor', 'rearchitect', '7 Rs', 'migration strategy', 'AWS MGN', 'Azure Migrate', 'Google Migrate', 'Database Migration Service', 'storage migration', 'cutover', 'migration testing'. Covers: 7 Rs migration strategies, migration assess…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Plan and execute cloud migrations using the 7 Rs strategy framework, with tools, testing, cutover planning, and post-migration optimization.
| Strategy | Definition | Effort | Duration | Cloud Benefit |
|---|---|---|---|---|
| Retire | Decommission | Low | Short | Cost savings |
| Retain | Keep on-prem | None | N/A | None |
| Rehost (Lift-Shift) | Move as-is to IaaS | Low | Weeks-Months | Minimal (lower DC cost) |
| Replatform | Move to managed service | Medium | Months | Moderate |
| Refactor / Rearchitect | Rewrite for cloud-native | High | Months-Years | Maximum |
| Repurchase | Switch to SaaS | Medium | Weeks-Months | Functional improvement |
| Relocate | Move to hyperscaler DC | Low | Weeks | Lower latency |
Is the application end-of-life?
├── Yes → Retire (decommission, cost savings)
└── No → Is it a SaaS replacement available?
├── Yes → Repurchase (SaaS switch)
└── No → Need cloud-native benefits (scalability, resilience)?
├── Yes → Can we rewrite the application?
│ ├── Yes → Refactor/Rearchitect (max benefit, max effort)
│ └── No → Replatform (managed services, moderate effort)
└── No → Immediate migration needed?
├── Yes → Rehost (fastest path to cloud)
└── No → Replatform or retain (take time to optimize)
| Dimension | Assessment | Metrics |
|---|---|---|
| Technical | Architecture compatibility | OS, DB, dependency graph |
| Operational | Process maturity | Monitoring, backup, DR |
| Security | Compliance requirements | Encryption, IAM, audit logs |
| Financial | TCO analysis | Current vs cloud cost |
| Skills | Team readiness | Training needs assessment |
| Tool | Scope | Platform | Data Collected |
|---|---|---|---|
| AWS MGN (Application Migration) | VMs | AWS | OS, apps, resources |
| Azure Migrate | VMs + databases | Azure | Dependency mapping |
| Google Migrate for Compute | VMs | GCP | Utilization, network |
| RVTools | VMware VMs | Any | VM config, storage |
| ServiceNow ITOM | Enterprise | Any | CMDB, dependencies |
| CloudHealth | Multi-cloud | Any | Cost, utilization |
| Faddom | App dependency | Any | Application dependency mapping |
| CloudEndure (now AWS MGN) | VMs | AWS | Continuous replication |
| Wave | Type | Risk | Duration | Max Workloads |
|---|---|---|---|---|
| Wave 0 | Foundation | Low | 2-4 weeks | N/A (infrastructure) |
| Wave 1 | Pilot (low-risk) | Low | 2 weeks | 3-5 workloads |
| Wave 2 | Early adopters | Low-Medium | 4 weeks | 10-15 workloads |
| Wave 3-N | Bulk migration | Medium | 4-6 weeks ea. | 20-50 workloads |
| Final Wave | Complex/high-risk | High | 4-8 weeks | 5-10 workloads |
# assessment/tco_analysis.py
"""Total Cost of Ownership comparison for on-prem vs cloud."""
import json
from dataclasses import dataclass, asdict
@dataclass
class WorkloadSpec:
name: str
vcpu: int
memory_gb: int
storage_gb: int
storage_type: str # HDD, SSD, NVMe
network_throughput: str # Mbps
licenses: list[str] # Windows, SQL, Oracle, etc.
def estimate_cloud_cost(self, provider="aws", region="us-east-1"):
"""Estimate monthly cloud cost."""
cost = 0
# Compute costs (example pricing)
if provider == "aws":
instance_map = {
(2, 4): "m6i.large",
(4, 16): "m6i.xlarge",
(8, 32): "m6i.2xlarge",
(16, 64): "m6i.4xlarge",
}
key = (self.vcpu, self.memory_gb)
instance = instance_map.get(key, "m6i.xlarge")
compute = {"m6i.large": 69, "m6i.xlarge": 138,
"m6i.2xlarge": 276, "m6i.4xlarge": 553}
cost += compute.get(instance, 138)
# Storage costs
storage_rates = {"HDD": 0.08, "SSD": 0.125, "NVMe": 0.25}
cost += self.storage_gb * storage_rates.get(self.storage_type, 0.125)
# License costs
license_rates = {"Windows": 50, "SQL": 300, "Oracle": 500}
for lic in self.licenses:
cost += license_rates.get(lic, 0)
return cost
def estimate_onprem_cost(self):
"""Estimate monthly on-prem cost (3-year amortized)."""
hardware = (self.vcpu * 200 + self.memory_gb * 15 + self.storage_gb * 2)
power_cooling = hardware * 0.3
admin = 1500 # shared admin overhead
return (hardware / 36) + power_cooling / 12 + admin
# Example
workload = WorkloadSpec("web-app", 4, 16, 200, "SSD", "1Gbps", ["Windows"])
onprem = workload.estimate_onprem_cost()
cloud = workload.estimate_cloud_cost()
print(f"Workload: {workload.name}")
print(f" On-prem: ${onprem:.0f}/mo")
print(f" Cloud: ${cloud:.0f}/mo")
# migration/dms.tf
resource "aws_dms_replication_subnet_group" "main" {
replication_subnet_group_description = "DMS subnet group"
subnet_ids = aws_subnet.private[*].id
}
resource "aws_dms_replication_instance" "main" {
replication_instance_class = "dms.c5.large"
replication_instance_id = "production-migration"
allocated_storage = 100
multi_az = true
publicly_accessible = false
vpc_security_group_ids = [aws_security_group.dms.id]
replication_subnet_group_id = aws_dms_replication_subnet_group.main.id
}
resource "aws_dms_endpoint" "source" {
endpoint_id = "source-onprem"
endpoint_type = "source"
engine_name = "postgres"
server_name = "192.168.1.100"
port = 5432
database_name = "production_db"
username = var.db_migration_user
password = var.db_migration_password
ssl_mode = "require"
extra_connection_attributes = "ParallelLoadThreads=4;ParallelLoadBufferSize=64"
}
resource "aws_dms_endpoint" "target" {
endpoint_id = "target-rds"
endpoint_type = "target"
engine_name = "postgres"
server_name = aws_db_instance.main.address
port = 5432
database_name = "production_db"
username = var.db_username
password = var.db_password
ssl_mode = "require"
}
resource "aws_dms_replication_task" "full_load" {
replication_task_id = "initial-load"
replication_instance_arn = aws_dms_replication_instance.main.replication_instance_arn
source_endpoint_arn = aws_dms_endpoint.source.endpoint_arn
target_endpoint_arn = aws_dms_endpoint.target.endpoint_arn
migration_type = "full-load-and-cdc"
table_mappings = jsonencode({
rules: [{
"rule-type": "selection"
"rule-id": "1"
"rule-name": "1"
"object-locator": {"schema-name": "public", "table-name": "%"}
"rule-action": "include"
}]
})
replication_task_settings = jsonencode({
FullLoadSettings: {
TargetTablePrepMode: "DROP_AND_CREATE",
CreatePkAfterFullLoad: true,
MaxFullLoadSubTasks: 8,
},
Logging: { EnableLogging: true }
})
}
# migration/cutover-plan.yaml
migration_id: "MIG-2025-001"
workload: "Payment Processing System"
target_platform: "AWS (us-east-1)"
scheduled_date: "2025-06-15T02:00:00 UTC"
pre_cutover:
- task: "Final data sync check"
owner: "DBA-Team"
duration: 15m
- task: "Application shutdown"
owner: "App-Team"
duration: 5m
- task: "Final incremental backup"
owner: "DBA-Team"
duration: 10m
- task: "DNS TTL reduction (60s)"
owner: "NetOps"
duration: 5m
- task: "Scale up target environment"
owner: "CloudOps"
duration: 10m
cutover:
- task: "Start DMS CDC replication"
owner: "DBA-Team"
duration: 5m
- task: "Verify data consistency (row counts, checksums)"
owner: "DBA-Team"
duration: 15m
- task: "Stop source database writes"
owner: "DBA-Team"
duration: 2m
- task: "Apply final CDC changes"
owner: "DBA-Team"
duration: 5m
- task: "Promote target database"
owner: "DBA-Team"
duration: 2m
- task: "Update DNS to target load balancer"
owner: "NetOps"
duration: 2m
- task: "Start application on target"
owner: "App-Team"
duration: 5m
post_cutover:
- task: "Run smoke tests"
owner: "QA-Team"
duration: 15m
- task: "Verify monitoring/alerts on target"
owner: "CloudOps"
duration: 10m
- task: "Monitor error rates for 30 min"
owner: "App-Team"
duration: 30m
- task: "Declare cutover complete"
owner: "Migration-Lead"
duration: 2m
rollback_triggers:
- condition: "Application error rate > 5% for 5 minutes"
action: "Revert DNS to source; failback database"
- condition: "Database replication lag > 60s"
action: "Abort cutover; keep source as primary"
- condition: "Data consistency check fails"
action: "Investigate; abort if > 0.01% mismatch"
rollback:
- task: "Revert DNS to source IP"
duration: 2m
- task: "Re-enable source application"
duration: 5m
- task: "Verify source operation"
duration: 15m
- task: "Stop DMS replication"
duration: 2m
- task: "Notify stakeholders"
duration: 5m
# Migration Runbook: Production Database
## Pre-Migration Checklist
- [ ] Source: PostgreSQL 15.3 on-prem (192.168.1.100:5432)
- [ ] Target: RDS PostgreSQL 15.4 (production-db.xxx.us-east-1.rds.amazonaws.com)
- [ ] DMS replication instance running (dms.c5.large)
- [ ] Full load completed successfully
- [ ] CDC replication lag < 5 seconds
- [ ] Application config updated for target DB endpoint
- [ ] Snapshot of target DB created
- [ ] Rollback plan reviewed and approved
- [ ] Stakeholders notified of maintenance window
## Cutover Commands
```bash
# 1. Stop source application
ssh app-server 'systemctl stop app-service'
# 2. Wait for CDC to catch up
aws dms describe-replication-tasks \
--filters Name=replication-task-id,Values=dms-full-load
# 3. Stop CDC replication
aws dms stop-replication-task \
--replication-task-arn arn:aws:dms:...
# 4. Verify target data
psql -h production-db.xxx.rds.amazonaws.com \
-c "SELECT count(*) FROM orders;"
# 5. Point app to target
aws rds modify-db-instance \
--db-instance-identifier production-db \
--new-db-instance-identifier production-db-primary
# 6. Start application on target
kubectl -n production set image deployment/app-service \
app=myapp:latest
# 7. Verify
curl -f https://app.example.com/health
# Create Snowball import job
aws snowball create-job \
--job-type IMPORT \
--resources '{"S3Resources":[{"BucketArn":"arn:aws:s3:::migration-data"}]}' \
--role-arn "arn:aws:iam::123456789012:role/snowball-role" \
--shipping-option SECOND_DAY \
--address-id ADDR123
# Get job manifest
aws snowball get-job-manifest --job-id JOB123
# Unlock and transfer data (on Snowball device)
# Use the Snowball Client on the device:
snowballEdge list-buckets
snowballEdge cp /data/large-dataset s3://migration-data/large-dataset/ --recursive
# After return, verify data
aws s3 sync s3://migration-data/large-dataset/ /data/verify/
# Download and configure Azure Migrate appliance
# Run assessment
az assessment create \
--assessment-name "onprem-migration" \
--project-name "MigrationProject" \
--resource-group "migration-rg" \
--sizing-criteria "PerformanceBased" \
--percentile "Percentile95" \
--time-range "Month" \
--currency "USD" \
--azure-location "eastus" \
--offer-code "MSFT-AZR-0003P" \
--reserved-instance "None" \
--vm-uptime "{\"daysPerMonth\": 30, \"hoursPerDay\": 24}"
# Create migration plan
az migration plan create \
--migration-plan-name "production-workloads" \
--resource-group "migration-rg" \
--project-name "MigrationProject"
# Install Migrate for Compute (formerly Velostrata)
gcloud services enable migrate.googleapis.com
# Create migration source
gcloud migrate sources create \
--project=$PROJECT_ID \
--source-name="onprem-vcenter" \
--source-type="vsphere" \
--host="10.0.0.1" \
--insecure=true
# Create migration wave
gcloud migrate waves create \
--project=$PROJECT_ID \
--wave-name="wave-1-pilot" \
--source-name="onprem-vcenter" \
--target-project=$TARGET_PROJECT \
--target-zone="us-central1-a" \
--target-network="production-vpc"
# Start replication
gcloud migrate replications start \
--project=$PROJECT_ID \
--wave-name="wave-1-pilot"
# Test cutover
gcloud migrate cutovers start \
--project=$PROJECT_ID \
--wave-name="wave-1-pilot" \
--cutover-name="cutover-test-1" \
--dry-run=true
# post_migration/optimize.py
"""Review post-migration for optimization opportunities."""
import boto3
def post_migration_review():
"""Check for replatforming opportunities."""
ec2 = boto3.client('ec2')
rds = boto3.client('rds')
# Check EC2 instances that could be Lambda
instances = ec2.describe_instances(
Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]
)
for reservation in instances['Reservations']:
for instance in reservation['Instances']:
instance_type = instance['InstanceType']
# Flag t2.nano/micro/small as Lambda candidates
if instance_type in ['t2.nano', 't2.micro', 't2.small']:
print(f"Candidate for Lambda: {instance['InstanceId']} ({instance_type})")
# Check RDS instances for Aurora upgrade
db_instances = rds.describe_db_instances()
for db in db_instances['DBInstances']:
if 'mysql' in db['Engine'] and db['EngineVersion'].startswith('5'):
print(f"Candidate for Aurora MySQL: {db['DBInstanceIdentifier']}")
if 'postgres' in db['Engine'] and float(db['EngineVersion'][:2]) < 13:
print(f"Candidate for version upgrade: {db['DBInstanceIdentifier']}")
┌────────────────────────────────────────────────────────┐
│ Migration Testing Pyramid │
├────────────────────────────────────────────────────────┤
│ │
│ /\ Smoke Tests (post-cutover) │
│ / \ - Health endpoints │
│ / \ - Critical user journeys │
│/______\ │
│──────── │
│ || Data Validation │
│ || - Row counts match │
│ || - Checksum verification │
│ || - Referential integrity │
│──────── │
│ || Performance Tests │
│ || - Latency comparison │
│ || - Throughput benchmarks │
│ || - Connection pool sizing │
│──────── │
│ || Functional Tests │
│ || - API contract tests │
│ || - Integration tests │
│ || - Authorization/authentication │
│──────── │
│ || Dry Run Tests │
│ || - Full migration in staging │
│ || - Timed cutover rehearsal │
│ || - Rollback procedure test │
└────────────────────────────────────────────────────────┘
| Tool | Source | Target | Migration Type | Replication | Cost |
|---|---|---|---|---|---|
| AWS MGN | VM (any hypervisor) | AWS EC2 | Rehost | Continuous | Free (pay for EC2) |
| AWS DMS | 20+ DB engines | AWS RDS/DW | Online/offline | CDC | Per instance hour |
| AWS DataSync | NFS/SMB | S3, EFS, FSx | File transfer | Scheduled | Per GB transferred |
| AWS Snowball | Physical | S3 | Offline bulk | Device shipping | Per job + shipping |
| Azure Migrate | VM, physical | Azure VM | Rehost/Replatform | Continuous | Free (pay for compute) |
| Azure DMS | DB engines | Azure SQL/Cosmos | Online/offline | CDC | Per instance hour |
| Google Migrate for Compute | VMWare, AWS, Azure | GCE | Rehost | Continuous | Free (pay for compute) |
| Google DMS | MySQL, PG, SQL Server | Cloud SQL | Online/offline | CDC | Per instance hour |
| Velostrata (now Google M4CE) | VMware | GCE | Rehost with streaming | Streaming | Free with GCE |
Moving everything to IaaS VMs without considering managed services. Replatform databases to RDS/Aurora, use Lambda for batch jobs.
Not planning for migration failure. Every migration must have a tested rollback procedure that can be executed within RTO.
Moving everything at once. Use wave-based migration: pilot → early adopters → bulk → complex.
Moving terabytes without understanding egress costs. Use Snowball/AWS DataSync for large data, and minimize cross-region traffic.
Not measuring pre-migration performance. Establish baselines (latency, throughput, error rate) before migration to validate post-migration.
Trying to replatform and migrate simultaneously. Rehost first, then replatform in a separate phase after stabilization.
Declaring victory after cutover. The real value of cloud comes from right-sizing, using managed services, and automating operations.
Testing only the first wave thoroughly. Each wave may have unique dependencies — test each wave's cutover in isolation.
Next: database-migration — detailed DB migration strategies.