How to Create a Virtual Machine on vSphere using Ansible

 Virtualization technology has revolutionized the way IT infrastructures are managed, enabling IT admins to consolidate their resources, optimize resource utilization, and minimize infrastructure costs. VMware vSphere is one of the most popular virtualization platforms, providing a robust and reliable infrastructure for building, deploying, and managing virtual machines.

One of the key advantages of vSphere is its ability to integrate with automation tools like Ansible. Ansible is an open-source automation tool that simplifies the process of managing IT infrastructure by providing a framework for automating tasks such as deployment, configuration, and management of virtual machines. In this blog, we'll show you how to create a virtual machine on vSphere using Ansible.

Environment Setup

We have an environment with 3 hosts, an ESXi host, ansible server, and vCenter host. 

The ESXi host has the following details:

Hostname = esxi01.darole.org
CPU = 2
Memory = 8GB
Disk = 1000 (Thin disk)
Software = VMware-VMvisor-Installer-7
Hosted on = VMWare-WorkStation

The vCenter host has the following details:

Hostname = vcenter01.darole.org
CPU = 2
Memory = 12GB
Disk = 150 (Thin disk)
Software = VMware-VCSA-all-7
Hosted on = esxi01.darole.org

The ansible host has the following details:

Hostname = ans01
CPU = 1
Memory = 1 GB
Disk = 10 GB
Software: ubuntu 20
Hosted on = esxi01.darole.org

We also have a template with the following details:

Hostname = centos7-temp01
CPU = 1
Memory = 1 GB
Disk = 10 GB
Software: Centos 7
Hosted on = esxi01.darole.org

To create a virtual machine from a template, we will use Ansible. Ansible is a powerful automation tool that allows us to manage and automate IT infrastructure. Here are the steps to create a virtual machine from a template using Ansible:

Step 1: Enable SSH Login on vCenter

To get started, you need to log in to the vCenter Admin Console. 

Open your web browser and navigate to the vCenter Admin Console URL: 

https://vcenter01.darole.org:5480/#/login. 

Once you are logged in, go to the "Access" tab and enable SSH login.

 


Step 2: Enable SSH on ESXi Host

Next, log in to the ESXi host console and press F2 to customize the system settings. Navigate to "Troubleshooting Mode Options" and enable SSH.






Step 3: Edit /etc/hosts File

Now, edit the /etc/hosts file on the machine where you'll be running the Ansible playbook to include the IP address and hostnames of the ESXi hosts and vCenter server. Use the following format:

192.168.2.205 esxi01.darole.org esxi01
192.168.2.206 ans01.darole.org ans01
192.168.2.207 vcenter01.darole.org vcenter01

Step 4: Install Ansible and PyVmomi

Next, you need to install Ansible and PyVmomi. Use the following commands to install them:

# apt update
# apt install ansible
# apt install python3-pip
# pip install PyVmomi

Note: PyVmomi, a Python SDK for VMware vSphere API, enables interaction with VMware ESXi and vCenter

Step 5: Configure Ansible Hosts

Now, configure the Ansible hosts file to include the hostnames of the ESXi hosts. Use the following command to add the hostnames to the Ansible hosts file:

# cat /etc/hosts | awk '{print $3}' >> /etc/ansible/hosts

Step 6: Installed the vmware community

#cat requirements.yml
---
collections: 
  - name: community.vmware

Install vmware community

# ansible-galaxy install -r requirements.yml 

Check if the vmware community is installed. 

# ansible-galaxy collection list community.vmware 

Step 6: Create Ansible Playbook

Create an Ansible playbook to create the virtual machine. Use the following code as an example:

# cat create-vm.yml
---
- name: Create a VM from a template
hosts: localhost
gather_facts: false
collection:
-  community.vmware
connection: local
pre_tasks:
- include_vars: vars.yml

tasks:
- name: Clone the template
vmware_guest:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
name: "{{ vm_name }}"
state: present
template: "{{ template_name }}"
folder : "/darole-dc/vm"
datacenter: "darole-dc"
hardware:
memory_mb: 1024
num_cpus: 1
scsi: paravirtual



Step 7: Create vars.yml File

Create a vars.yml file that

# cat vars.yml
---
vcenter_hostname: "vcenter01.darole.org"
vcenter_username: "administrator@vsphere.local"
vcenter_password: "Azure#12345678"
vm_name: "test-vm01"
template_name: "centos7-temp"
virtual_machine_datastore: "esxi01-datastore1"
vcenter_validate_certs: false
cluster_name: "my-cluster"
vcenter_datacenter: "darole-dc"
vm_folder: "test01"
vm_disk_gb: 2
vm_disk_type: "thin"
vm_disk_datastore: "esxi01-datastore2"
vm_disk_scsi_controller: 1
vm_disk_scsi_unit: 1
vm_disk_scsi_type: "paravirtual"
vm_disk_mode: "persistent"


In this example, we are using the vcenter_hostname, vcenter_username, and vcenter_password variables to specify the credentials required to authenticate with the vSphere environment. We are also specifying the vm_name, template_name, and virtual_machine_datastore variables to specify the name of the new virtual machine, the name of the template from which we will clone the virtual machine, and the name of the datastore where the virtual machine will be deployed.

In this example, we are defining a playbook that will run on the localhost host and includes the vars.yml file that we created earlier. The playbook contains a single task that uses the vmware_guest module to clone the specified template and deploy a new virtual machine.

Before running the playbook, we can use the --syntax-check option to check the syntax of the playbook:

# ansible-playbook create-vm.yml --syntax-check

Assuming the syntax check is successful, we can then run the playbook using the following command:

# ansible-playbook create-vm.yml


Once the playbook completes successfully, we can log in to the vCenter server using the URL

https://vcenter01.darole.org/



https://galaxy.ansible.com/community/vmware 

Below playbook is to collect the VM information. 

ansible@ans01:~/vmware$ cat vm_info.yml
---
- name: info vm demo
hosts: localhost
become: false
gather_facts: false
collections:
- community.vmware
pre_tasks:
- include_vars: vars.yml
tasks:
- name: get VM info
vmware_guest_info:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ vcenter_datacenter }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: "{{ vm_name }}"
register: detailed_vm_info

- name: print VM info
ansible.builtin.debug:
var: detailed_vm_info
- name: print VM UUID
ansible.builtin.debug:
var: detailed_vm_info.instance.instance_uuid
- name: print VM host name
ansible.builtin.debug:
var: detailed_vm_info.instance.hw_name
ansible@ans01:~/vmware$

Playbook to start VM 

ansible@ans01:~/vmware$ cat vm_start.yml
---
- name: start vm demo
hosts: localhost
become: false
gather_facts: false
collections:
- community.vmware
pre_tasks:
- include_vars: vars.yml
tasks:
- name: power on
vmware_guest_powerstate:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "{{ vm_name }}"
validate_certs: "{{ vcenter_validate_certs }}"
state: powered-on

ansible@ans01:~/vmware$

Playbook to stop VM.

ansible@ans01:~/vmware$ cat vm_stop.yml
---
- name: stop vm demo
hosts: localhost
become: false
gather_facts: false
collections:
- community.vmware
pre_tasks:
- include_vars: vars.yml
tasks:
- name: guest shutdown
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: 120
register: shutdown
ignore_errors: true

- name: poweroff
vmware_guest_powerstate:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: "{{ vm_name }}"
state: powered-off
when: shutdown.failed
ansible@ans01:~/vmware$

Playbook to take snapshot 

ansible@ans01:~/vmware$ cat vm_snapshot_create.yml
---
- name: vm snapshot demo
hosts: localhost
become: false
gather_facts: false
collections:
- community.vmware
pre_tasks:
- include_vars: vars.yml
tasks:
- name: create snapshot
vmware_guest_snapshot:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ vcenter_datacenter }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: "{{ vm_name }}"
state: present
snapshot_name: "Ansible Managed Snapshot"
folder: "{{ vm_folder }}"
description: "This snapshot is created by Ansible Playbook"

ansible@ans01:~/vmware$

Playbook delete the snapshot ( note: snapshot name much be correct.)

ansible@ans01:~/vmware$ cat vm_snapshot_remove.yml
---
- name: vm snapshot demo
hosts: localhost
become: false
gather_facts: false
collections:
- community.vmware
pre_tasks:
- include_vars: vars.yml
tasks:
- name: remove snapshot
vmware_guest_snapshot:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
datacenter: "{{ vcenter_datacenter }}"
validate_certs: "{{ vcenter_validate_certs }}"
name: "{{ vm_name }}"
folder: "{{ vm_folder }}"
snapshot_name: "Ansible Managed Snapshot"
state: absent

ansible@ans01:~/vmware$

Playbook for adding / extending the disk.(ensure you use correct scsi parameters  )

ansible@ans01:~/vmware$ cat vm_add_disk.yml
---
- name: vm disk demo
hosts: localhost
become: false
gather_facts: false
collections:
- community.vmware
pre_tasks:
- include_vars: vars.yml
tasks:
- name: add disk to vm
vmware_guest_disk:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: "{{ vcenter_validate_certs }}"
datacenter: "{{ vcenter_datacenter }}"
name: "{{ vm_name }}"
disk:
- size_gb: "{{ vm_disk_gb }}"
type: "{{ vm_disk_type }}"
datastore: "{{ vm_disk_datastore }}"
state: present
scsi_controller: "{{ vm_disk_scsi_controller }}"
unit_number: "{{ vm_disk_scsi_unit }}"
scsi_type: "{{ vm_disk_scsi_type }}"
disk_mode: "{{ vm_disk_mode }}"

ansible@ans01:~/vmware$

To get dynamic inventory of VM.

ansible@ans01:~/vmware$ cat ansible.cfg
[inventory]
enable_plugins = vmware_vm_inventory

ansible@ans01:~/vmware$ cat inventory.vmware.yml
plugin: vmware_vm_inventory
strict: False
hostname: vcenter01.darole.org
username: administrator@vsphere.local
password: Pass@1234
validate_certs: False
with_tags: False
groups:
VMs: True
ansible@ans01:~/vmware$ ansible-inventory -i inventory.vmware.yml --list

Playbook to start multiple servers. 

ansible@ans01:~/vmware$ cat dr_start.yml
---
- name: start vm demo
hosts: localhost
become: false
gather_facts: false
collections:
- community.vmware
pre_tasks:
- include_vars: dr_vars.yml
tasks:
- name: power on
vmware_guest_powerstate:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
name: "{{ item }}"
validate_certs: "{{ vcenter_validate_certs }}"
state: powered-on
with_items:
- "{{ vm_name }}"

ansible@ans01:~/vmware$ cat dr_vars.yml
---
vcenter_hostname: "vcenter01.darole.org"
vcenter_username: "administrator@vsphere.local"
vcenter_password: "Pass@1234"
template_name: "ubuntu"
virtual_machine_datastore: "esxi02-datastore2"
vcenter_validate_certs: false
cluster_name: "my-cluster"
vcenter_datacenter: "darole-dc"
vm_folder: "test01"
vm_disk_gb: 2
vm_disk_type: "thin"
vm_disk_datastore: "esxi02-datastore2"
vm_disk_scsi_controller: 1
vm_disk_scsi_unit: 1
vm_disk_scsi_type: "paravirtual"
vm_disk_mode: "persistent"
vm_name:
- "pup01"
- "zap01"
- "lamp01"
- "web01"
- "db01"
- "dock01"
ansible@ans01:~/vmware$

Below github location for above script. 

https://github.com/vdarole/ansible/tree/main/vmware

No comments:

Post a Comment