Index
Introduction
After configuring ESXi and deploying some virtual machines, I felt the need to automate the process of creating VMs since most of the times I need to spin up a clean machine just for testing some stuff and making the same process over and over again is time consuming and boring.
This is why I took some time to learn Ansible, so I could just create a playbook and the VM would be up and running.
After some time and a lot of googling I found that since I am using ESXi free version I had to use an iso file instead of a template for the VM creation. This minor detail was really important because using the template would never work without a vCenter instance.
So the plan was to have an iso file in a datastore (in this example I will be using Ubuntu OS), configure ESXi host and a VM that runs Ansible.
For this to work the VM has to be running Ansible > 2.10 since previous versions don’t support SATA.
Configuration
Configure ESXi
In the ESXi server the only thing I did was, reconfigure ssh to be able to root login, authenticate with a public key and disable the password authentication method. For that I edited the /etc/ssh/sshd_config file by adding the following commands:
PermitRootLogin yes
PubkeyAuthentication yes
PasswordAuthentication no
Configure Host Machine
The host machine used (this is where Ansible is running) was Ubuntu 20.04.2 LTS for the sake of simplicity.
Here I created a ssh key to authenticate in ESXI without the need of a password in the ssh connection.
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub | ssh ESXI_USER@ESXI_IP 'cat >> /etc/ssh/keys-root/authorized_keys'
Next step was to install Ansible and make sure the version was > 2.10.
pip3 install ansible-core
ansible --version
Before creating the playbook I had to configure some values in an hosts file. In this way Ansible knows what is the host used for the playbook and what configurations needs in run time. For that I had to create the hosts file inside /etc/ansible/ directory with the following content:
[esxi]
<ip of the esxi host>
[esxi:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_connection=ssh
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_rsa
Create The Playbook
“Playbooks are expressed in YAML format with a minimum of syntax. A playbook is composed of one or more ‘plays’ in an ordered list. The terms ‘playbook’ and ‘play’ are sports analogies. Each play executes part of the overall goal of the playbook, running one or more tasks. Each task calls an Ansible module.”
To interact with an ESXi instance I used the community.vmware.vmware_guest
module that is used to manage virtual machines in vCenter. Reading the documentation is pretty straight forward how the module works.
First I specified the host (localhost because it’s already specified in the hosts file), then I needed to say what task I was going to run (vmware_guest module). Inside that task I identified every attribute I wanted to be present in the virtual machine. Finally I delegated the task to localhost and registered as deploy_vm.
---
- hosts: localhost
gather_facts: False
tasks:
- name: Create a VM in ESXi
vmware_guest:
hostname: <ip of ESXi>
username: <username of ESXi>
password: <password of ESXi>
validate_certs: False
folder: /ha-datacenter/vm
name: <vm-name>
state: present
guest_id: ubuntu64Guest
esxi_hostname: <hostname of ESXi>
disk:
- size_gb: 100
type: thin
datastore: <relative path of datastore, like "[HDD1]">
hardware:
memory_mb: 8192
num_cpus: 4
scsi: lsilogicsas
cdrom:
- controller_number: 0
unit_number: 0
state: present
type: iso
iso_path: <relative path + iso name, like "[HDD1] debian-10.5.0-amd64-DVD-1.iso">
networks:
- name: VM Network
type: static
start_connected: true
ip: <ip>
netmask: <netmask>
gateway: <gateway>
customization:
hostname: <vm-name>
dns_servers:
- 8.8.8.8
- 8.8.4.4
delegate_to: localhost
register: deploy_vm
Final Result
Finally the last thing was to execute the playbook using ansible-playbook <playbook name>
.
Doing this was extremely helpful because now I can spin up virtual machines (either Windows or Linux) in a faster and easier way.