Skip to main content

Ansible VMware Integration

Introduction

Ansible VMware Integration allows you to automate your VMware infrastructure management tasks using Ansible's simple, yet powerful, automation framework. This integration bridges the gap between traditional VMware administration and modern infrastructure-as-code practices, enabling you to manage your virtualized environments with the same tools you use for the rest of your infrastructure.

In this guide, we'll explore how Ansible connects with VMware's ecosystem, the prerequisites needed, and practical examples of automating common VMware tasks. By the end, you'll have a solid understanding of how to leverage Ansible to streamline your VMware operations.

Prerequisites

Before diving into Ansible VMware automation, ensure you have the following:

  1. Ansible installed (version 2.10+)
  2. Python (3.6+)
  3. PyVmomi - Python SDK for the VMware vSphere API
  4. VMware environment - vCenter Server or ESXi host
  5. Network connectivity between your Ansible control node and VMware environment

Let's install the necessary Python packages:

bash
pip install ansible pyvmomi

To install the VMware collection of modules:

bash
ansible-galaxy collection install community.vmware

Understanding the Ansible VMware Architecture

Ansible communicates with VMware environments through the vSphere API using PyVmomi. Here's a simplified view of the architecture:

This communication path allows Ansible to:

  • Gather facts about your VMware environment
  • Create and manage virtual machines
  • Configure networking
  • Manage datastores and storage
  • Handle VMware cluster operations

Setting Up Inventory and Variables

Let's create a basic inventory structure for our VMware environment:

ini
[vcenter]
vcenter.example.com

[esxi_hosts]
esxi01.example.com
esxi02.example.com

[virtual_machines]
vm01.example.com
vm02.example.com

Next, let's define variables for authentication (typically stored in an encrypted vault file):

yaml
# group_vars/vcenter.yml
---
ansible_connection: local
vcenter_hostname: "vcenter.example.com"
vcenter_username: "[email protected]"
vcenter_password: "secure_password"
vcenter_validate_certs: false # Set to true in production

Basic VMware Operations with Ansible

1. Gathering VMware Information

Let's start with a simple playbook to gather information about your VMware environment:

yaml
---
- name: Gather VMware Environment Info
hosts: localhost
connection: local
gather_facts: no

vars_files:
- vcenter_vars.yml

tasks:
- name: Get VM info
community.vmware.vmware_vm_info:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
register: vm_info

- name: Display VM names
debug:
msg: "VM Name: {{ item.guest_name }}"
loop: "{{ vm_info.virtual_machines }}"

Expected output:

TASK [Display VM names] ********************************************************
ok: [localhost] => (item={'guest_name': 'web-server-01', ...}) => {
"msg": "VM Name: web-server-01"
}
ok: [localhost] => (item={'guest_name': 'db-server-01', ...}) => {
"msg": "VM Name: db-server-01"
}
ok: [localhost] => (item={'guest_name': 'app-server-01', ...}) => {
"msg": "VM Name: app-server-01"
}

2. Creating a Virtual Machine

Now, let's create a new virtual machine:

yaml
---
- name: Create a new VM
hosts: localhost
connection: local
gather_facts: no

vars_files:
- vcenter_vars.yml

tasks:
- name: Clone a virtual machine from template
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: new-web-server
template: ubuntu-20.04-template
datacenter: DC1
folder: /DC1/vm/Web Servers
state: present
cluster: Production
datastore: datastore1
hardware:
memory_mb: 4096
num_cpus: 2
scsi: paravirtual
networks:
- name: VM Network
ip: 192.168.1.100
netmask: 255.255.255.0
gateway: 192.168.1.1
wait_for_ip_address: yes
register: deploy_vm

- name: Display new VM info
debug:
var: deploy_vm

3. Managing VMware Host Power States

Managing power states of your ESXi hosts:

yaml
---
- name: Manage ESXi Host Power
hosts: localhost
connection: local
gather_facts: no

vars_files:
- vcenter_vars.yml

tasks:
- name: Enter maintenance mode
community.vmware.vmware_maintenancemode:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
esxi_hostname: esxi01.example.com
state: present
evacuate: yes
timeout: 3600
register: maintenance_result

- name: Display result
debug:
var: maintenance_result

Creating Reusable Roles

For more complex VMware operations, it's best to organize your code into Ansible roles. Here's an example structure for a VMware provisioning role:

roles/
└── vmware_provision/
├── defaults/
│ └── main.yml
├── tasks/
│ ├── main.yml
│ ├── create_vm.yml
│ ├── configure_network.yml
│ └── finalize.yml
└── templates/
└── vm_config.j2

Example main.yml task file:

yaml
---
- name: Include VM creation tasks
include_tasks: create_vm.yml

- name: Configure VM networking
include_tasks: configure_network.yml

- name: Finalize VM setup
include_tasks: finalize.yml

Then, you can use the role in a playbook:

yaml
---
- name: Provision VMware Infrastructure
hosts: localhost
connection: local
gather_facts: no

vars_files:
- vcenter_vars.yml

roles:
- role: vmware_provision
vars:
vm_name: app-server-02
vm_template: rhel8-template
vm_cpu: 4
vm_memory_mb: 8192

Advanced VMware Operations

Managing VM Snapshots

yaml
---
- name: Manage VM Snapshots
hosts: localhost
connection: local
gather_facts: no

vars_files:
- vcenter_vars.yml

tasks:
- name: Create VM snapshot
community.vmware.vmware_guest_snapshot:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
datacenter: DC1
folder: /DC1/vm/Web Servers
name: web-server-01
state: present
snapshot_name: "pre-update-snapshot"
description: "Snapshot before system update"
memory_dump: no
quiesce: yes
register: snapshot_result

VM Resource Management

Adjust VM resources based on demand:

yaml
---
- name: Adjust VM Resources
hosts: localhost
connection: local
gather_facts: no

vars_files:
- vcenter_vars.yml

tasks:
- name: Increase VM CPU and memory
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: web-server-01
state: present
hardware:
memory_mb: 8192
num_cpus: 4
hotadd_cpu: yes
hotadd_memory: yes
register: vm_adjust

Real-World Scenario: Automating VM Deployment Pipeline

Let's look at a comprehensive example that might be used in a real-world scenario to create a development environment:

yaml
---
- name: Deploy Development Environment
hosts: localhost
connection: local
gather_facts: no

vars_files:
- vcenter_vars.yml

vars:
dev_environment:
- name: dev-web-01
template: web-server-template
cpu: 2
memory_mb: 4096
networks:
- name: "Dev Network"
ip: "10.10.10.11"
- name: dev-app-01
template: app-server-template
cpu: 4
memory_mb: 8192
networks:
- name: "Dev Network"
ip: "10.10.10.21"
- name: dev-db-01
template: db-server-template
cpu: 4
memory_mb: 16384
networks:
- name: "Dev Network"
ip: "10.10.10.31"

tasks:
- name: Deploy VMs
community.vmware.vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: "{{ item.name }}"
template: "{{ item.template }}"
datacenter: DC1
folder: /DC1/vm/Development
state: present
cluster: Dev-Cluster
datastore: fast-storage
hardware:
memory_mb: "{{ item.memory_mb }}"
num_cpus: "{{ item.cpu }}"
networks: "{{ item.networks }}"
wait_for_ip_address: yes
loop: "{{ dev_environment }}"
register: deployed_vms

- name: Create host group for deployed VMs
add_host:
name: "{{ item.instance.hw_name }}"
groups: new_vms
ansible_host: "{{ item.instance.ipv4 }}"
loop: "{{ deployed_vms.results }}"
when: deployed_vms.results is defined

- name: Configure newly deployed VMs
hosts: new_vms
gather_facts: yes

tasks:
- name: Update system packages
apt:
update_cache: yes
upgrade: yes
become: yes
when: ansible_distribution == "Ubuntu"

- name: Install common packages
package:
name:
- htop
- vim
- git
- curl
state: present
become: yes

Best Practices for Ansible VMware Integration

  1. Use Ansible Vault for Credentials

    Never store VMware credentials in plain text:

    bash
    ansible-vault create vcenter_secrets.yml
  2. Organize Your Inventory Effectively

    Group your VMware resources logically:

    ini
    [vcenter]
    vcenter.example.com

    [clusters]
    production
    development

    [templates]
    ubuntu-template
    rhel-template

    [resource_pools]
    prod-pool
    dev-pool
  3. Leverage Dynamic Inventory

    Use the VMware dynamic inventory plugin:

    yaml
    # vmware_inventory.yml
    plugin: community.vmware.vmware_vm_inventory
    strict: false
    hostname: vcenter.example.com
    username: [email protected]
    password: secure_password
    validate_certs: false
    with_tags: true
  4. Create Modular, Reusable Playbooks

    Split complex operations into smaller, focused playbooks and use import_playbook or include_tasks.

  5. Implement Tags for Task Selection

    Add tags to your tasks for selective execution:

    yaml
    tasks:
    - name: Deploy VM
    community.vmware.vmware_guest:
    # parameters
    tags: [create, vm]
  6. Leverage VMware Customization Specifications

    Use existing VMware customization specifications for guest OS configuration:

    yaml
    community.vmware.vmware_guest:
    # other parameters
    customization:
    existing_vm: yes
    spec: Linux-CustomSpec

Troubleshooting Common Issues

Connection Problems

If you encounter connection issues:

yaml
---
- name: Test VMware Connection
hosts: localhost
connection: local
gather_facts: no

vars_files:
- vcenter_vars.yml

tasks:
- name: Ping vCenter
uri:
url: "https://{{ vcenter_hostname }}/rest/com/vmware/cis/session"
method: POST
user: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
status_code: 200
register: ping_result

- name: Display result
debug:
var: ping_result

Permission Issues

If you face permission errors, verify your role permissions in vCenter:

yaml
---
- name: Get Current User Permissions
hosts: localhost
connection: local
gather_facts: no

vars_files:
- vcenter_vars.yml

tasks:
- name: Get permissions
community.vmware.vmware_object_role_permission_info:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
register: permissions

- name: Display permissions
debug:
var: permissions

Summary

Ansible VMware Integration provides a powerful way to automate VMware infrastructure management tasks. In this guide, we've covered:

  • Setting up the necessary prerequisites for Ansible VMware integration
  • Basic VMware operations using Ansible modules
  • Creating and managing virtual machines
  • Implementing advanced operations like snapshot management
  • Real-world deployment scenarios
  • Best practices for effective automation
  • Troubleshooting common issues

By leveraging Ansible's simplicity and VMware's robust virtualization platform, you can create efficient, repeatable, and scalable infrastructure management workflows that reduce human error and save time.

Additional Resources

Here are some resources to help you continue learning about Ansible VMware Integration:

Exercises

  1. Create a playbook that inventories all VMs in your environment and outputs their power state.
  2. Develop a role that creates a three-tier application environment (web, app, and database servers).
  3. Write a playbook that manages VM snapshots (create, list, and delete) based on input parameters.
  4. Create an automated VM backup solution using Ansible and VMware snapshots.
  5. Implement a playbook that migrates VMs between datastores during off-hours.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)