This is an Ansible collection (os_migrate.vmware_migration_kit) that provides tools for migrating virtual machines from VMware (ESXi/vCenter) environments to OpenStack clouds. The collection uses a hybrid approach combining Ansible automation with custom Golang modules for high-performance migration operations.
Version: 2.0.9 License: Apache-2.0 Repository: https://github.com/os-migrate/vmware-migration-kit
-
Ansible Roles (
roles/):prelude: Initial setup and validationconversion_host: Deploys and configures OpenStack instances as conversion hostsexport_metadata: Extracts VM metadata from VMware environmentconvert_metadata: Transforms VMware metadata to OpenStack formatimport_workloads: Handles the actual VM migration and import
-
Golang Modules (
plugins/modules/src/):migrate: Core migration engine using nbdkit for disk transferscreate_server: OpenStack instance creationcreate_network_port: Network port managementflavor_info: Flavor information retrievalbest_match_flavor: Automatic flavor selectionvolume_info: Cinder volume operationsvolume_metadata_info: Volume metadata management
-
Module Utilities (
plugins/module_utils/):vmware/: VMware vCenter/ESXi interaction codeopenstack/: OpenStack API integration (Gophercloud)nbdkit/: NBD server management for disk streaminglogger/: Structured loggingconnectivity/: Network connectivity checksansible/: Ansible module interface utilities
The collection supports three migration approaches:
- NBDkit (Default): Uses nbdkit server on a conversion host for high-performance streaming
- Virt-v2v: Traditional virt-v2v-based conversion with conversion host
- Local NFS: Direct migration from shared NFS storage
- Change Block Tracking (CBT): Near-zero-downtime migrations by syncing only changed blocks
- Parallel Migrations: Multiple concurrent migrations on same conversion host
- Network Mapping: Automatic network configuration translation
- Flavor Matching: Intelligent OpenStack flavor selection/creation
- Multi-disk/Multi-NIC: Full support for complex VM configurations
- Windows Support: Includes Windows 10 and Server 2022 support
- AAP Compatible: Works with Ansible Automation Platform
vmware-migration-kit/
├── galaxy.yml # Collection metadata
├── Makefile # Build automation
├── playbooks/ # Main playbooks
│ ├── migration.yml # Primary migration playbook
│ ├── migration_v2v.yml # Virt-v2v workflow
│ ├── convert_metadata.yml # Metadata conversion
│ └── ...
├── roles/ # Ansible roles
│ ├── prelude/ # Setup and validation
│ ├── conversion_host/ # Conversion host deployment
│ ├── export_metadata/ # VMware metadata extraction
│ ├── convert_metadata/ # Metadata transformation
│ └── import_workloads/ # VM import and migration
├── plugins/
│ ├── modules/
│ │ └── src/ # Golang module sources
│ │ ├── migrate/ # Core migration module
│ │ ├── create_server/ # Instance creation
│ │ └── ...
│ └── module_utils/ # Shared utilities
│ ├── vmware/ # VMware SDK integration
│ ├── openstack/ # Gophercloud integration
│ ├── nbdkit/ # NBDKit server management
│ └── logger/ # Logging framework
├── tests/ # Test suite
├── doc/ # Architecture diagrams (SVG)
└── scripts/ # Build and utility scripts
make binaries: Build all Golang modules in containermake build: Build complete Ansible collection tarballmake clean-binaries: Remove compiled binariesmake clean-build: Remove collection tarballmake install: Install collection with dependenciesmake tests: Run all tests (pytest, ansible-lint, ansible-sanity, golangci-lint)make test-pytest: Run Python testsmake test-ansible-sanity: Run Ansible sanity checksmake test-ansible-lint: Run Ansible lintingmake test-golangci-lint: Run Go linting
- Uses containerized builds (Podman/Docker) with CentOS Stream 10
- Golang modules are compiled to native binaries
- SELinux-aware container security options
- Python 3.12 virtual environments for testing
VMware Source:
vcenter_hostname: vCenter server addressvcenter_username: vCenter usernamevcenter_password: vCenter passwordvcenter_datacenter: Datacenter nameesxi_hostname: ESXi host address
OpenStack Destination:
dst_cloud: OpenStack cloud credentials (auth dict)openstack_private_network: Network UUIDsecurity_groups: Security group UUIDssh_key_name: SSH key pair name (optional)
Migration Settings:
vms_list: Array of VM names to migrateos_migrate_vmw_data_dir: Working directory (default:/opt/os-migrate)already_deploy_conversion_host: Reuse existing conversion host (boolean)import_workloads_cbt_sync: Enable CBT synchronization (boolean)import_workloads_cutover: Perform final cutover (boolean)
Flavor Options:
use_existing_flavor: Find best matching flavor or create new one (boolean)flavor_uuid: Specify exact flavor UUID (useful for host aggregation/targeted placement)
Conversion Host Egress:
- 443/TCP → VMware vCenter (authentication, management)
- 902/TCP → VMware ESXi (NFC/NBD disk access)
- Various → OpenStack APIs (see OpenStack firewall docs)
Conversion Host Ingress:
- 22/TCP ← Ansible controller (management)
Internal:
- 10809/TCP: NBDKit server (localhost only)
ansible-playbook -i inventory.yml \
os_migrate.vmware_migration_kit.migration \
-e @secrets.yml \
-e @myvars.ymlPhase 1 - Initial Sync:
import_workloads_cbt_sync: true
import_workloads_cutover: falsePhase 2 - Cutover:
import_workloads_cbt_sync: false
import_workloads_cutover: trueGolang modules can run independently:
export OS_AUTH_URL=https://...
export OS_PROJECT_NAME=admin
# ... other OS_* variables
cat > args.json <<EOF
{
"user": "root",
"password": "...",
"server": "vcenter.example.com",
"vmname": "my-vm",
"dst_cloud": { ... }
}
EOF
./plugins/modules/migrate/migrate- Create module directory:
plugins/modules/src/my_module/ - Implement
main.gowith Ansible module interface - Add to
scripts/build.shcompilation list - Run
make binariesto compile - Create
.pywrapper inplugins/modules/ - Add documentation and argument specs
- Run
make teststo validate
# Run all tests
make tests
# Individual test suites
make test-pytest # Python unit tests
make test-ansible-lint # Ansible best practices
make test-ansible-sanity # Ansible module validation
make test-golangci-lint # Go code qualityAnsible Collections:
community.vmware>= 1.0.0vmware.vmware>= 2.4.0vmware.vmware_rest>= 4.9.0openstack.cloud>= 2.0.0 (legacy, being phased out)os_migrate.os_migrate>= 0.0.1
Runtime (Conversion Host):
- NBDKit with VDDK plugin
- virtio-win >= 1.40 (for Windows support)
- CentOS Stream 10 or RHEL 9.5+ recommended
Build:
- Golang toolchain
- Python 3.12+
- Ansible 2.9+
Conversion Host:
/tmp/osm-nbdkit-<vm-name>-<random-id>.log: Migration logs
Ansible Controller:
<os_migrate_vmw_data_dir>/<vm-name>/migration.log: Pulled on failure
Enable verbose logging:
import_workloads_debug: trueMinimum vCenter permissions needed:
| Category | Privileges |
|---|---|
| Datastore | Browse datastore |
| Virtual Machine | Guest operations: All |
| Provisioning: Disk access, file access, download | |
| Service configuration: Notifications, polling, read config | |
| Snapshot: Create, remove, rename, revert |
| OS Family | Version | Status |
|---|---|---|
| RHEL | 9.4, 9.3, 8.5 | ✅ Tested |
| CentOS | 9, 8 | ✅ Tested |
| Fedora | 38+ | ✅ Tested |
| Ubuntu Server | 24 | ✅ Tested |
| Windows | 10 | ✅ Tested |
| Windows Server | 2022 | ✅ Tested |
- BTRFS support requires Fedora conversion host (RHEL/CentOS kernels lack BTRFS)
- Support only for latest collection version
- External dependencies (community.vmware, etc.) not covered by support
- Cold migration only for local NFS workflow
- Golang Binaries: All
plugins/modules/*/binaries are compiled fromplugins/modules/src/*/Go code - Don't Edit Binaries: Always edit
.gosource files, then runmake binaries - Ansible Wrappers: Python files in
plugins/modules/*.pyare thin wrappers around Go binaries - Container Builds: Makefile uses containers for reproducible builds - don't assume local Go toolchain
- Version Sync: Keep
galaxy.ymlversion in sync withCHANGELOG.md - CBT Metadata: Cinder volumes store CBT changeID in metadata properties
- Parallel Execution: NBDKit uses Unix sockets to allow parallel migrations on same host
- Support Scope: Only support collection code, not external dependencies
- Minor fix to create_instance task for AAP compatibility
- Added vmware.vmware and vmware.vmware_rest collections as dependencies
- Added flavor_uuid option for explicit flavor specification (enables host aggregation)
- Fixed ansible test sanity issues
- Added unit test for workload name sanitization
- Fixed VM name sanitization for invalid characters
- Replaced openstack.cloud modules with native Gophercloud bindings
- Reorganized Golang binaries with proper documentation
- Added golangci-lint integration
- Improved Makefile build system with SELinux awareness
# Build and install locally
make install
# Run migration
ansible-playbook -i inventory.yml \
os_migrate.vmware_migration_kit.migration \
-e @vars.yaml
# Check migration logs on conversion host
tail -f /tmp/osm-nbdkit-*.log
# Install from Galaxy
ansible-galaxy collection install os_migrate.vmware_migration_kit
# Generate VMware thumbprint (for virt-v2v)
openssl s_client -connect ESXI_SERVER:443 </dev/null | \
openssl x509 -in /dev/stdin -fingerprint -sha1 -noout- Documentation: README.md, role-specific READMEs
- Architecture Diagrams:
doc/*.svg(workflow visualizations) - Examples:
vars.yaml,localhost_inventory.yml - Demo: https://www.youtube.com/watch?v=XnEQ8WVGW64
- Issues: https://github.com/os-migrate/vmware-migration-kit/issues