Overview
Migrate VMware virtual machines to Huawei Cloud ECS in a private network environment. This applies to scenarios where the source and destination are on different network segments and are connected through a VPN.
Core Features: No public IP/EIP, VPN connectivity, proxy ECS deployment of squid+GOST+rsync to implement proxying/forwarding/file synchronization.
| Channel | Path | Description |
|---|---|---|
| Control flow proxy | SMS Agent → Cloud API:443 | Through squid HTTP proxy |
| Data flow forwarding | SMS Agent → target ECS:22/8899/8900 | Through GOST forwarding |
| Management channel | Operation end → source SSH:22 | Direct SSH management |
Supported Scope and Limitations
⚠️ Important Statement: This Skill supports only the following migration scenarios; scenarios outside this scope are not supported:
| Dimension | Supported Scope | Description |
|---|---|---|
| Network environment | Private Network only | The source and destination are on different network segments and are connected through a VPN; direct public network connection mode is not supported |
| Operating system | Linux only | Windows host migration is not supported |
| CPU architecture | x86_64 (amd64) only | ARM (aarch64/arm64) architecture migration is not supported |
| Source platform | VMware virtual machine | Block-level data synchronization is implemented through SMS Agent |
| Target platform | Huawei Cloud ECS | Automatically create the target ECS and perform migration |
Technical Reasons Why ARM Architecture Is Not Supported:
- ECS specification selection: The code actively excludes all ARM specifications (prefixes kc/ac/ai/kai/kx/ki/ah/as/at/sn) and matches only x86 specifications
- Target image: The image mapping table contains only x86_64 public image IDs and no ARM images
- rsync binary: The precompiled package provides only the x86_64 version (source compilation as a fallback can adapt to ARM, but this has not been formally verified)
Trigger Words
private network migration, private network environment migration, VPN migration, intranet migration, no public network migration, VMware private network migration, VMware intranet migration, proxy ECS migration, GOST migration, private network migration, VPN migration, offline migration
Prerequisites
Network Environment
- The source VMware environment and the Huawei Cloud VPC have been connected through a VPN
- The proxy ECS can reach the source SSH(22) and the Huawei Cloud intranet API
- The operation end can connect to the proxy ECS through SSH
Source Environment
- SMS Agent has been installed in the VMware environment (or can be installed through the proxy)
- The source SSH is reachable, and the root password or key is known
hcloud CLI and obsutil Credential Configuration
- hcloud CLI version requirement: >= 7.2.2, run
hcloud versionto verify, runhcloud configure listto check configuration - If it is not installed or the version is too low, refer to the installation guide:https://github.com/huaweicloud/huaweicloud-skills/blob/master/skills/bss/billing/huawei-cloud-billing-scout/references/cli-installation-guide.md
- hcloud permanent AK/SK configuration:
hcloud configure init(Reference:https://support.huaweicloud.com/usermanual-hcli/hcli_03_002.html) - obsutil credential configuration(requires separate installation of obsutil):
obsutil config -i=<YourAK> -k=<YourSK> -e=obs.<Region>.myhuaweicloud.com- Common endpoints: cn-north-1→obs.cn-north-1.myhuaweicloud.com, cn-north-4→obs.cn-north-4.myhuaweicloud.com, cn-east-3→obs.cn-east-3.myhuaweicloud.com, cn-south-1→obs.cn-south-1.myhuaweicloud.com, cn-southwest-2→obs.cn-southwest-2.myhuaweicloud.com
🚨 AK/SK credential configuration (highest-priority mandatory rule)
If the AI violates any of the following, it is a serious error; it must immediately stop and re-execute the configuration process:
- After completing this skill,the first thingmust be to prompt the user to configure a permanent AK/SK;skipping, delaying, or making its own judgment is absolutely not allowed
- The AI is strictly prohibited from checking existing states on its own, such as the credential cache (
~/.migration_skill/.cred_cache), hcloud configuration, etc., and assuming that configuration has already been completed — even if an existing cache is found, the user must first be asked and the user must choose- The AI is strictly prohibited from making decisions on behalf of the user — it must not choose to use the cache, skip verification, or assume credentials are valid on its own
- Only after the user explicitly confirms(such as "use the existing cache", "I have completed configuration", or the environment variables have been set) can it proceed to the next step
- Any behavior that bypasses this step and directly executes subsequent operations is a serious error
Configuration process(execute after the user confirms configuration):
- The user sets environment variables:
export migration_Access_Key='你的AK'、export migration_Secret_Access_Key='你的SK'、export HW_ACCESS_KEY='你的永久AK'、export HW_SECRET_KEY='你的永久SK', as well as the environment variables referenced by the${...}placeholders in Excel (such asexport migration_password='主机密码') - The AI reads the AK/SK from the environment variables and calls
verify_credentials()for verification (hcloud IAM KeystoneListAuthDomains read-only API, 30-second timeout) - Verification passed → cache with AES-256-GCM encryption to
~/.migration_skill/.cred_cache(permissions 600); verification failed → prompt to set again (retry up to 3 times) - Detect temporary credentials: HST prefix → reject (temporary credentials), HPUA prefix → allow (permanent credentials)
Security specifications:
- Environment variable retrieval: AK/SK is read through environment variables, not through plaintext on the command line
- Local cache: AES-256-GCM encrypted cache, permissions 600
- Temporary credentials prohibited: HST-prefixed temporary credentials are completely prohibited (including intermediate operations); after permanent credential verification passes, clear the temporary environment variables
- Change detection: when AK/SK changes, prompt the user for confirmation (yes/no); after confirmation, reconfigure hcloud CLI, SMS Agent, and obsutil together
- Masked display: AK is masked in logs (such as
HPUA****YPQY), SK is completely hidden - Information security: AK/SK is only displayed in masked form; plaintext output is prohibited; uploading to non-business storage or the public internet is prohibited
- Prohibited operations: temporary credentials used for any operation, plaintext AK/SK on the command line, IAM creating/deleting AK/SK
- Host password: the password column in Sheet1 supports the general placeholder
${env_var_name}(such as${migration_password}), read from environment variables; plaintext values are used directly (backward compatible); the proxy password in Sheet2 continues to be read directly from Excel and does not use environment variables
Excel input file structure
Migration tasks use an Excel file (.xlsx) Batch configuration, 2 Sheets:
Sheet1: Host information (source host, one migration task per row)
| Column | Field | Description | Required |
|---|---|---|---|
| A | Hostname | Source VM name | ✅ |
| B | Private IP | Source VMware VM IP | ✅ |
| C | Port number | SSH port (default 22) | ❌ |
| D | Username | SSH username (default root) | ✅ |
| E | Password | SSH password (supports ${env_var_name} placeholder or plaintext) |
✅ |
| F | region_id | Huawei Cloud region ID | ✅ |
| G | region_name | Region name | ❌ |
| H | project_id | Project ID | ✅ |
| I | project_name | Project name | ❌ |
| J | os_type | OS type (default Linux) | ❌ |
| K | use_public_ip | Whether to use public IP (FALSE=private network mode) | ❌ |
| L | target_image_id | Target image ID (empty=consistent with source) | ❌ |
| M | target_AZ | Availability zone (empty=random) | ❌ |
Sheet2: Proxy host information (jump host)
| Column | Field | Description | Required |
|---|---|---|---|
| A | Host name | Proxy ECS name | ✅ |
| B | Public IP | Proxy ECS public IP | ✅ |
| C | Private IP | Proxy ECS private IP | ✅ |
| D | Port | SSH port (default 22) | ❌ |
| E | Username | SSH username (default root) | ✅ |
| F | Password | SSH password (read directly from Excel) | ✅ |
Password placeholder rules: The Sheet1 password column supports general ${env_var_name} placeholders, scans all field values, resolves and replaces from environment variables; before running, it automatically verifies that environment variables for all placeholders are configured, and exits with an error if any are missing; Sheet2 proxy passwords do not go through placeholder resolution.
Migration process
1. Preparation stage
- Configure AK/SK (see prerequisites, 🚨 must be performed first)
- Prepare the Excel migration task file
- Verify VPN connectivity
2. Proxy ECS deployment
- Create proxy ECS (requires a public IP or internet access through a NAT gateway)
- Deploy squid proxy (control flow proxy, port 3128)
- Deploy GOST forwarding (data flow forwarding, port 8899/8900)
- Deploy rsync (file synchronization)
3. Batch migration execution
# 首次运行 (设置环境变量后,自动读取并缓存)
export migration_Access_Key='你的AK'
export migration_Secret_Access_Key='你的SK'
export migration_password='主机密码' # Excel 中 ${migration_password} 占位符引用
python scripts/batch_migrate.py tasks.xlsx \
--proxy-ip <代理ECS_IP> --proxy-user root --proxy-password <代理密码>
# 后续使用 (本地加密缓存,无需再次设置环境变量)
python scripts/batch_migrate.py tasks.xlsx --cred-cache \
--proxy-ip <代理ECS_IP> --proxy-user root --proxy-password <代理密码>
Process: read Excel → generate migration task list → execute for each task migrate_worker.py → record results and output a summary report
4. Single-machine migration process (migrate_worker.py)
- Validate target ECS name: check whether target_name complies with naming rules
- Duplicate prevention check: find existing target ECS by ownership tag
- Found ACTIVE/STOPPED ECS → reuse directly
- Found ECS in abnormal state → prompt the user to confirm, then delete and recreate
- Not found → create a new ECS
- Create target ECS: call
ecs_ops.create_target_ecs(), validate naming rules, create ECS, apply ownership tag - Configure proxy forwarding: configure GOST forwarding rules on the proxy ECS
- Install SMS Agent: Install SMS Agent on the source via the proxy
- Execute migration: Start the SMS migration task
- Verify migration: Check the target ECS status
Ownership management and duplicate creation prevention
Ownership tags
Resource ownership management is implemented through ECS tags:
| Tag key | Tag value | Description |
|---|---|---|
migration-skill |
vmware-ecs-private |
Identifies resources created by this skill |
source-ip |
Source IP | Traceability identifier |
source-name |
Source VM name | Traceability identifier |
migration-time |
Timestamp | Migration time record |
Duplicate creation prevention logic
- By
migration-skill=vmware-ecs-private+source-ip=<源IP>tag, find existing ECS - Found and status is ACTIVE/STOPPED → reuse, skip creation
- Found and status is ERROR/other → prompt the user for confirmation, then delete and recreate
- Not found → create a new ECS and tag it
Permission verification
- Before deleting/stopping/restarting ECS, verify the
migration-skilltag - For ECS not created by this skill, refuse the operation and throw
PermissionError - Only ECS with its own ownership tag can be operated on
File structure
huawei-cloud-migration-vmware-ecs-private/
├── SKILL.md # Skill 文档
├── README.md # 使用说明文档
├── scripts/
│ ├── batch_migrate.py # 批量迁移入口 (1634行)
│ ├── migrate_worker.py # 单机迁移逻辑 (1540行)
│ ├── step_tracker.py # 步骤追踪器 (250行, 耗时/阻塞/问题)
│ ├── ecs_ops.py # ECS 操作封装 (1303行)
│ ├── excel_reader.py # Excel 读取解析 (525行, 2 Sheet)
│ ├── ownership_utils.py # 所属权标签管理 (217行)
│ ├── hcloud_wrapper.py # hcloud CLI 封装/脱敏日志 (1102行)
│ ├── credential_manager.py # AK/SK 凭证管理 (775行, 环境变量+AES缓存)
│ ├── proxy_ecs_ops.py # 代理 ECS 部署 (680行)
│ ├── gost_ops.py # GOST 转发配置 (889行)
│ ├── squid_ops.py # squid 代理配置 (367行)
│ ├── sms_ops.py # SMS 迁移任务操作 (508行)
│ ├── sms_agent_push.py # SMS Agent 安装/推送 (1541行)
│ ├── ssh_utils.py # SSH 远程操作封装 (670行)
│ ├── network_ops.py # 网络资源操作 (899行)
│ ├── safety_checker.py # 安全检查 (433行)
│ ├── skill_logger.py # 日志管理 (263行)
│ ├── retry_utils.py # 重试工具 (186行)
│ ├── report.py # 迁移报告生成 (344行, 含步骤追踪)
│ ├── error_reporter.py # 错误报告 (161行)
│ ├── post_migration_verify.py # 迁移后验证 (1065行)
│ ├── smoke_test_server_id.py # 冒烟测试 (272行)
│ ├── task_name_utils.py # 任务名称工具 (128行)
│ ├── vpn_check.py # VPN 连通性检查 (347行)
│ └── agent_state_check.sh # Agent 状态检查脚本 (299行)
└── templates/
├── generate_template.py # Excel 模板生成脚本
├── 私网迁移源主机Linux相关信息1.0.xlsx # Excel 模板示例文件
└── 迁移网络设计图.png # 迁移网络架构设计图
Usage
Quick start
- Configure AK/SK (🚨 must be done first): Set the environment variable
migration_Access_Key、migration_Secret_Access_Key、HW_ACCESS_KEY、HW_SECRET_KEY, as well as the environment variables referenced by the${...}placeholders in the Excel. Configure the hcloud CLI (hcloud configure init) and obsutil (obsutil config -i=<AK> -k=<SK> -e=obs.<Region>.myhuaweicloud.com, obsutil needs to be installed separately). After AI verification passes, it is cached.Explicit user confirmation must be received before continuing - Prepare the Excel task file (refer to the template, 2 sheets; Sheet1 password column can be filled with
${env_var_name}placeholders or plaintext) - Deploy the proxy ECS and install squid+GOST+rsync
- Execute batch migration:
python scripts/batch_migrate.py tasks.xlsx --proxy-ip <IP> --proxy-user root --proxy-password <代理密码> - Subsequent use of cache: add the
--cred-cacheparameter - Run in the background (recommended): add the
-bparameter; the process runs in the background via nohup and will not be killed when the terminal is closed. Logs →migration.log,PID→migration.pid, check progress:tail -f migration.log
Command parameters
| Parameter | Description | Required |
|---|---|---|
excel |
Excel task file path (2 sheets) | ✅ |
--cred-cache |
Use credentials from the local encrypted cache | Cache mode |
--region |
Huawei Cloud region (default cn-north-4) | ❌ |
--project-id |
Huawei Cloud project ID | ❌ |
--proxy-ip |
Proxy ECS IP (overrides Excel Sheet2) | ✅ |
--proxy-port |
Proxy ECS SSH port (default 22) | ❌ |
--proxy-user |
Proxy ECS SSH user (default root) | ✅ |
--proxy-pass |
Proxy ECS SSH password | ✅ |
--vpc-id |
Existing VPC ID (automatically created if not passed) | ❌ |
--subnet-id |
Existing subnet ID (automatically created if not passed) | ❌ |
--sg-id |
Existing security group ID (automatically created if not passed) | ❌ |
--max-workers |
Maximum concurrency (default 20, supports 100 concurrent instances) | ❌ |
--max-workers-prepare |
Phase A preparation stage concurrency | ❌ |
--max-workers-migrate |
Phase B migration stage concurrency | ❌ |
--max-retries |
Maximum retry count (default 2) | ❌ |
--retry-delay |
Retry interval in seconds (default 10) | ❌ |
--task-timeout |
Single task timeout in seconds (default 10800=3 hours) | ❌ |
--security-token |
Temporary credential security token (required when AK has HST prefix) | ❌ |
--dry-run |
Validate only, do not execute | ❌ |
--deep-verify |
Deep verification mode | ❌ |
--force-update |
Force update Agent | ❌ |
--output |
Result output path (default migration-results.json) | ❌ |
--log-dir |
Log directory (default /var/log/migration-private) | ❌ |
--rsync-binary |
rsync binary path | ❌ |
--background, -b |
Run in background (nohup) | ❌ |
--log-file |
Background run log file (default migration.log) | ❌ |
--pid-file |
Background run PID file (default migration.pid) | ❌ |
Environment variables(must be set on first run):
| Environment variable | Description |
|---|---|
migration_Access_Key |
Permanent AK (HPUA prefix) |
migration_Secret_Access_Key |
Permanent SK |
HW_ACCESS_KEY |
Huawei Cloud permanent AK (used for hcloud/obsutil credential configuration) |
HW_SECRET_KEY |
Huawei Cloud permanent SK (used for hcloud/obsutil credential configuration) |
${...} Placeholder variable |
Any ${env_var_name} placeholder-referenced environment variables in the Excel; all configured ones are automatically validated before running |
Security group rules
Security group rules required for migration (automatically created or use an existing security group):
| Direction | Protocol | Port | Source/Destination | Description |
|---|---|---|---|---|
| Inbound | TCP | 22 | 0.0.0.0/0 | SSH management |
| Inbound | TCP | 8899 | 0.0.0.0/0 | GOST data channel |
| Inbound | TCP | 8900 | 0.0.0.0/0 | GOST data channel |
| Inbound | TCP | 3128 | 0.0.0.0/0 | squid proxy |
Troubleshooting
| Issue | Possible cause | Solution |
|---|---|---|
| SSH connection timeout | VPN not connected / security group not allowing traffic | Check VPN connectivity and security group rules |
| hcloud authentication failed | Invalid AK/SK or temporary credentials | Re-set the permanent AK/SK environment variables and run validation |
| SMS Agent installation failed | Proxy unreachable / source SSH unreachable | Check the proxy ECS squid/GOST configuration and source SSH |
| GOST forwarding failed | Port conflict / firewall | Check whether ports 8899/8900 are in use and firewall rules |
| Target ECS creation failed | Insufficient quota / invalid image | Check the ECS quota and image ID |
| Migration task timeout | Large disk / insufficient network bandwidth | Adjust --task-timeout, check network bandwidth |
| Credential cache corrupted | Cache file has been tampered with | Delete ~/.migration_skill/.cred_cache, re-set environment variables |
| Password placeholder not resolved | Environment variable not set | Check whether the environment variable corresponding to the ${...} placeholder in the Excel has been exported |
Logs
- Log directory:
/var/log/migration-private/(configurable via--log-dir) - Run in background:
tail -f migration.logView progress,cat migration.pidGet PID - Result file:
migration-results.json(can be modified via--output) - AK masking: In logs, AK is displayed as
HPUA****YPQYformat, SK is completely hidden