Migrating VMs from VMware to OpenStack with Pure Storage – Part 3: Complete Automation

Welcome back to our three-part series on migrating VMware VMs to OpenStack using Pure Storage! In Part 1, we covered the foundational concepts and manual workflow. In Part 2, we dove into the technical implementation details and individual automation components.

Now, in this final installment, we’re bringing everything together with a complete, production-ready Ansible automation solution that orchestrates the entire migration process from start to finish.

🎯 What We’ve Built

Our automation solution is a comprehensive Ansible role that handles the complete migration workflow:

  1. Graceful VM shutdown in VMware
  2. Storage vMotion to Pure Storage vVols datastore
  3. vVol discovery and mapping
  4. Volume disconnection from VMware hosts
  5. Cinder volume adoption into OpenStack
  6. OpenStack instance creation with migrated volumes

The entire process is driven by a simple configuration file and can migrate multiple VMs in a single playbook run.

🏗️ Architecture Overview

The solution leverages several key Pure Storage and OpenStack features:

  • Pure Storage vVols: Provides the bridge between VMware and OpenStack storage
  • OpenStack Cinder Volume Groups: Introduced in OpenStack 2025.1 (Epoxy), enabling efficient volume adoption
  • Pure Storage Cinder Driver: Handles the low-level volume management and cloning
  • FlashArray Pod: Ensures volumes reside in an unstretched pod for optimal cloning performance

📋 Prerequisites

Before running the automation, ensure you have:

Required Ansible Collections

ansible-galaxy collection install community.vmware
ansible-galaxy collection install purestorage.flasharray
ansible-galaxy collection install openstack.cloud

⚠️ Important Note: The openstack.cloud.volume_manage module used in this automation is currently upstream in the OpenStack Cloud Collection but has not yet been included in an official release. You’ll need to install the collection directly from the GitHub master branch:

ansible-galaxy collection install git+https://github.com/openstack/ansible-collections-openstack.git

Infrastructure Requirements

  • VMware vSphere environment with vCenter
  • Pure Storage FlashArray with vVols support
  • OpenStack environment with Cinder volume groups support (2025.1+)
  • Temporary vVols datastore on an unstretched FlashArray Pod

🚀 Getting Started

1. Clone the Repository

git clone https://github.com/your-org/vmware-openstack-migration.git
cd vmware-openstack-migration

2. Configure Your Environment

Edit group_vars/all.yaml with your environment details:

# VMware vCenter Configuration
vcenter_hostname: "vcsa.example.com"
vcenter_username: "administrator@example.com"
vcenter_password: "{{ vault_vcenter_password }}"
vcenter_validate_certs: true
datacenter: "My-Datacenter"

# Pure Storage FlashArray Configuration
pure_fa_url: "my-fa01"
pure_fa_api_token: "{{ vault_pure_api_token }}"
temp_vvol_datastore_name: "temp-vvols01"
cinder_manage_host_string: "cinder-host01@myfa01#my-fa1"
cinder_volume_id_type: "source-name"
cinder_volume_type: "pure-iscsi"

# OpenStack Configuration
os_auth_url: "https://openstack.example.com/identity"
os_user: "admin"
os_password: "{{ vault_os_password }}"
os_project: "admin"
os_domain: "default"
os_cloud: "openstack"

# Default Instance Settings
os_default_flavor: "m1.small"
os_default_network: "public"
os_default_keypair: "my-ssh-key"
os_default_security_groups: ["default"]

# VMs to Migrate
vms_to_migrate:
  - name: "web-server-01"
    os_instance_name: "web-server-01"
    os_flavor: "m1.medium"
    os_network: "internal"
  - name: "db-server-01"
    os_instance_name: "database-01"
    os_flavor: "m1.large"
  - name: "app-server-01"
    os_instance_name: "app-server-01"

3. Secure Your Credentials

Use Ansible Vault to encrypt sensitive information:

ansible-vault create group_vars/vault.yaml

Add your encrypted credentials:

vault_vcenter_password: "your-vcenter-password"
vault_pure_api_token: "your-pure-api-token"
vault_os_password: "your-openstack-password"

4. Run the Migration

Execute the playbook:

ansible-playbook -i inventory.ini migrate_vms.yaml --ask-vault-pass

🔧 Deep Dive: How It Works

The Migration Workflow

Our Ansible role (vmware2openstack) orchestrates seven key steps:

Step 1: VM Shutdown

- name: "Shut down guest OS"
  community.vmware.vmware_guest_powerstate:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: "{{ vcenter_validate_certs }}"
    name: "{{ vm.name }}"
    state: shutdown-guest
    state_change_timeout: 300

Step 2: Storage vMotion to vVols

- name: "Storage vMotion to VVol datastore"
  community.vmware.vmware_vmotion:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: "{{ vcenter_validate_certs }}"
    vm_name: "{{ vm.name }}"
    destination_datastore: "{{ temp_vvol_datastore_name }}"

Step 3: vVol Discovery and Mapping

This is where the magic happens. Our automation:

  1. Queries vCenter for VM disk information
  2. Extracts vVol namespace UUIDs from disk paths
  3. Calls Pure Storage API to correlate vVols with actual volumes
  4. Maps VMware disks to Pure Storage volume names

The process involves sophisticated regex parsing to extract vVol identifiers from paths like:

[temp-vvols01] rfc4122.12345678-1234-1234-1234-123456789abc/disk-001.vmdk

Step 4: Volume Disconnection

Before adoption into OpenStack, volumes must be cleanly disconnected from VMware hosts:

- name: Disconnect vvol volume from host
  purestorage.flasharray.purefa_host:
    name: "{{ host.host }}"
    volume: "{{ volume }}"
    state: absent
    fa_url: "{{ pure_fa_url }}"
    api_token: "{{ pure_fa_api_token }}"

Step 5: Cinder Volume Adoption

Each Pure Storage volume is adopted into OpenStack Cinder:

- name: "Adopt vvol volume into Cinder"
  openstack.cloud.volume_manage:
    auth: "{{ openstack_auth }}"
    state: present
    name: "{{ vm.name }}-{{ disk.label }}"
    host: "{{ cinder_manage_host_string }}"
    source_name: "{{ disk.pure_storage_vvol_name }}"
    id_type: "{{ cinder_volume_id_type }}"
    bootable: "{{ disk.is_boot_disk | bool }}"
    volume_type: "{{ cinder_volume_type }}"

Step 6: OpenStack Instance Creation

Finally, the new OpenStack instance is created with the migrated volumes:

- name: "Create OpenStack instance booting from volume"
  openstack.cloud.server:
    auth: "{{ openstack_auth }}"
    state: present
    name: "{{ vm.os_instance_name }}"
    flavor: "{{ vm.os_flavor | default(os_default_flavor) }}"
    boot_volume: "{{ boot_volume_id }}"
    volumes: "{{ data_volume_ids }}"
    nics:
      - net-name: "{{ vm.os_network | default(os_default_network) }}"

🎪 Demo: Real-World Migration

To showcase the solution’s capabilities, we’ve included a demonstration migrating a three-node MicroK8s cluster running a PostgreSQL deployment. This represents a moderately complex scenario with:

  • Multiple interconnected VMs
  • Stateful workloads (PostgreSQL database)
  • Kubernetes networking requirements
  • Boot and data volumes for each node

The demo shows the entire migration completing successfully with minimal downtime and full data integrity.

🛡️ Production Considerations

Security Best Practices

  1. Use Ansible Vault for all credentials
  2. Enable certificate validation in production
  3. Implement least-privilege access for service accounts
  4. Audit all API calls and changes

Performance Optimization

  1. Parallel VM migration using Ansible’s serial parameter
  2. Batch processing for large environments
  3. Network optimization between sites
  4. Storage performance tuning on Pure Storage arrays

Monitoring and Troubleshooting

The playbook includes comprehensive error handling and status reporting:

- name: Final migration summary
  ansible.builtin.debug:
    msg: "Migration process completed for {{ vm_ready_for_openstack | length }} VMs"
  when: vm_ready_for_openstack is defined

Key monitoring points:

  • VM shutdown timeouts
  • Storage vMotion progress
  • API call failures
  • Volume adoption status
  • Instance creation success

🔮 Future Enhancements

This automation framework provides a solid foundation for additional features:

Network Migration

  • Automated network mapping between VMware and OpenStack
  • Security group translation
  • Load balancer migration

Advanced Scheduling

  • Maintenance window integration
  • Rollback capabilities
  • Multi-site coordination

Integration Options

  • CI/CD pipeline integration
  • Monitoring system notifications
  • Change management system integration

📚 Resources and Next Steps

Documentation

Community

🎉 Conclusion

Over the course of this three-part series, we’ve taken you from the conceptual understanding of VMware to OpenStack migration through to a complete, production-ready automation solution.

The combination of Pure Storage’s vVols technology, OpenStack’s Cinder volume groups, and Ansible’s orchestration capabilities creates a powerful, repeatable migration process that can handle complex enterprise workloads with minimal downtime and maximum data integrity.

Whether you’re migrating a few VMs or an entire data center, this automation framework provides the foundation for a successful transition to OpenStack. The modular design allows for customization to meet specific requirements while maintaining the reliability and repeatability that enterprise migrations demand.

Ready to start your migration journey? Download the complete automation solution and begin planning your move to OpenStack today!


This concludes our three-part series on VMware to OpenStack migration with Pure Storage. We hope you found this comprehensive guide valuable for your cloud transformation projects. Happy migrating!

Leave a Reply

Your email address will not be published. Required fields are marked *