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:
- Ansible installed (version 2.10+)
- Python (3.6+)
- PyVmomi - Python SDK for the VMware vSphere API
- VMware environment - vCenter Server or ESXi host
- Network connectivity between your Ansible control node and VMware environment
Let's install the necessary Python packages:
pip install ansible pyvmomi
To install the VMware collection of modules:
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:
[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):
# 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:
---
- 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:
---
- 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:
---
- 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:
---
- 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:
---
- 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
---
- 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:
---
- 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:
---
- 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
-
Use Ansible Vault for Credentials
Never store VMware credentials in plain text:
bashansible-vault create vcenter_secrets.yml
-
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 -
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 -
Create Modular, Reusable Playbooks
Split complex operations into smaller, focused playbooks and use
import_playbook
orinclude_tasks
. -
Implement Tags for Task Selection
Add tags to your tasks for selective execution:
yamltasks:
- name: Deploy VM
community.vmware.vmware_guest:
# parameters
tags: [create, vm] -
Leverage VMware Customization Specifications
Use existing VMware customization specifications for guest OS configuration:
yamlcommunity.vmware.vmware_guest:
# other parameters
customization:
existing_vm: yes
spec: Linux-CustomSpec
Troubleshooting Common Issues
Connection Problems
If you encounter connection issues:
---
- 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:
---
- 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:
- Ansible VMware Community Collection Documentation
- PyVmomi GitHub Repository
- VMware vSphere API Documentation
Exercises
- Create a playbook that inventories all VMs in your environment and outputs their power state.
- Develop a role that creates a three-tier application environment (web, app, and database servers).
- Write a playbook that manages VM snapshots (create, list, and delete) based on input parameters.
- Create an automated VM backup solution using Ansible and VMware snapshots.
- 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! :)