Automating workflow in Red Hat Virtualization using Ansible

Michael Kotelnikov
8 min readJun 21, 2020

Introduction

Lately, I have noticed that the first thing that comes into mind when you speak about virtualization is VMware ESXI. People tend to think that the only “good” solution for virtualization in an enterprise organization is provided by VMware.

Even though VMware provides a nice solution for virtualization, in this short blog I’m going to challenge the preposition by providing an alternative for large scale virtualization. A product named Red Hat Virtualization, or RHV if you like acronyms.

Of course that Red Hat is best known for its operation system (Red Hat Enterprise Linux), but, the company also invests into a large variety of technologies, providing both infrastructure, middleware, automation, provisioning and security solutions. You can name an issue or a goal you are trying to achieve, and its most likely that Red Hat has a product that can help you run towards success.

So, in my opinion RHV is a great product. It is based on an open source product called oVirt, and it allows you to grow and implement a large scale, highly available and easily managed virtual infrastructure.

Even though RHV is a great platform, and I would love to describe the architecture behind it, I’m writing this blog in a purpose of describing my favorite part about RHV — How easy it is to implement your automated workload on top of RHV!

Nowadays, automation became a crucial part of every organization. Each organization has thousands of servers, and it does not make sense to configure anything manually.

To demonstrate the power of RHV in an automated environment, I’m going to use Ansible — An opensource automation tool. Using Ansible, I’m going to create a virtual machine on top of RHV, and host a web server on top of it. It is important to understand that even though this demo might seem simple, I’m mainly using it to prove a concept. You can also implement a huge infrastructure, running very sophisticated workload on top of it.

Demo

In the next demonstration I’m going to use two Git repositories (containing Ansible roles) I’ve created to automate VM creation on top of any RHV cluster. The templates are super generic, and you can implement the roles in any environment, connected or disconnected from the internet.

My Setup

Before I continue with the demo, I will describe the setup I’m working with:

  • RHEL 8.1 workstation — I’m going to run the demonstration from my laptop, running RHEL 8.1 (Of course that Ansible can be run from managed servers like Ansible Tower or AWX, but, in my demo I want to demonstrate the simplicity of configuring web servers in 5 minutes with the familiarity of your own desktop :) ).
  • RHV 4.3 cluster — I’m going to use a 3 node hyper converged RHV cluster.
  • A rhel7.6 template with cloud-init installed on it.
  • Ansible 2.8.10
  • python3-ovirt-engine-sdk4.x86_64 — I’m going to install the package on my laptop to interact with the RHV api using Ansible.

Lets Start!

The first part of the workflow is deploying the VM itself. As mentioned before, I’m going to use an ansible role I wrote to deploy the VM. The documentation for the role can be found here. The role will create a virtual machine for our httpd server. After the machine is created, Ansible will create an Ansible group, and add the newly created virtual machine to it for gathering facts.

Ansible gathering facts— Used to gather useful variables about remote hosts that can be used in playbooks. Ansible provides many facts about the system, automatically.

After adding the newly created machine to the Ansible group. Ansible will start running the web server configuration on the machine.

STEP 1 — Preparing your working directory

So, after understanding the automation flow, lets take a look at how your working directory should look like.

Make sure to create a working directory with customized files to fit your environment. You can use the files and contents of the blog as a reference.

[mkotelni@mkotelni workdir]$ tree
.
├── ansible.cfg
├── create-vm.yml
├── group_vars
│ └── webservers.yml
├── host_vars
│ └── localhost
└── requirements.yml

As you can see, I have quite a bit of files and directory sets in my working directory.

ansible.cfg — A file containing extra configurations regarding the runtime of Ansible. The file is used when you want to tune Ansible behavior for your purposes.

[mkotelni@mkotelni workdir]$ cat ansible.cfg 
[defaults]
# Set this to “False” if you want to avoid host key checking by the underlying tools Ansible uses to connect to the host
host_key_checking = false

create-vm.yml — The playbook used by Ansible to create the automated environment. It has a reference to both roles, and is used to configure the environment from 0 to 100.

[mkotelni@mkotelni workdir]$ cat create-vm.yml 
---
- hosts: localhost
roles:
- rhev-ansible
- hosts: webservers
roles:
- ansible-httpd-demo-role

group_vars/webservers.yml — A variable file that will be applied to every member of the webservers Ansible group. In our case it will be only one server. The variables in this file should be your Red Hat account, and password (Not too secure, but it is not the purpose of the blog).

[mkotelni@mkotelni workdir]$ cat group_vars/webservers.yml
---
redhat_user: "it_is_not_my_email@redhat.com"
redhat_password: "it_is_not_my_real_password"

host_vars/localhost — The most important file of them all. This file defines the virtual machines that you want to create. In our case I will deploy a simple VM with basic configurations. Take note that if you try to deploy it by yourself, you will probably need to define new values for the variables.

[mkotelni@mkotelni workdir]$ cat host_vars/localhost 
---
rhv_vm:
- name: "httpd-vm"
memory: "4GiB"
cpu_cores: "1"
template: "rhel76template"
url: "https://rhv.example.com/ovirt-engine/api"
rhv_user: "admin@internal"
rhv_password: "not_the_real_admin_password"
insecure: "true"
nics:
- name: "nic1"
network: "ovirtmgmt"
profile_name: "ovirtmgmt"
cloud_init:
user_name: "root"
root_password: "password"
host_name: "httpd-vm"
nic_name: "eth0"
nic_boot_protocol: "static"
nic_ip_address: "10.0.0.1"
nic_netmask: "255.255.255.0"
nic_gateway: "10.0.0.254"
nic_on_boot: true
dns_servers: "10.0.0.200"
ansible_host: "10.0.0.1" // The IP that Ansible will do the httpd server configurations on
ansible_group_list:
- webservers // The Ansible group that the VM will be added to

requirements.yml — The Ansible requirements file. It is used to fetch the Ansible roles I’ve created from GitHub. We will pull the roles to our workstation later in the demo.

[mkotelni@mkotelni workdir]$ cat requirements.yml 
---
- name: rhev-ansible
src: https://gitlab.com/michael.kot/rhev-ansible
scm: git
- name: ansible-httpd-demo-role
src: https://github.com/michaelkotelnikov/ansible-httpd-demo-role
scm: git

STEP 2 — Fetching the Ansible roles and running the workflow!

As described in the previous section. We need to pull the Ansible roles from GitHub, since they are not present on your workstation locally (for now).

To pull the the Ansible roles, you will need to use the ansible-galaxy command

[mkotelni@mkotelni workdir]$ ansible-galaxy install -r requirements.yml - extracting rhev-ansible to /home/mkotelni/.ansible/roles/rhev-ansible
- rhev-ansible was installed successfully
[WARNING]: Meta file /home/mkotelni/.ansible/roles/rhev-ansible is empty. Skipping dependencies.
- extracting ansible-httpd-demo-role to /home/mkotelni/.ansible/roles/ansible-httpd-demo-role
- ansible-httpd-demo-role was installed successfully
[WARNING]: Meta file /home/mkotelni/.ansible/roles/ansible-httpd-demo-role is empty. Skipping dependencies.

The roles are now imported to your workstation! By default the roles will be saved in your ~/.ansible/roles directory.

[mkotelni@mkotelni workdir]$ tree ~/.ansible/roles/
/home/mkotelni/.ansible/roles/
├── ansible-httpd-demo-role
│ ├── files
│ │ └── index.html
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── README.md
│ ├── requirements.yml
│ └── tasks
│ └── main.yml
└── rhev-ansible
├── defaults
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── requirements.yml
└── tasks
├── add-to-hosts.yml
├── config-vm.yml
├── create-all-vms.yml
└── main.yml
9 directories, 14 files

After importing the roles, and configuring the working dir with the correct variables, you can run the Ansible playbook and create your first web server on top of Red Hat Virtualization!

[mkotelni@mkotelni workdir]$ ansible-playbook create-vm.ymlPLAY [localhost] *********************************************************************************************************************************TASK [Gathering Facts] ***************************************************************************************************************************
ok: [localhost]
TASK [rhev-ansible : Run the required rhv task] **************************************************************************************************
included: /home/mkotelni/.ansible/roles/rhev-ansible/tasks/create-all-vms.yml for localhost
TASK [rhev-ansible : Deploy all vms] *************************************************************************************************************included: /home/mkotelni/.ansible/roles/rhev-ansible/tasks/config-vm.yml for localhostTASK [rhev-ansible : Set defaults as needed] *****************************************************************************************************
ok: [localhost]
TASK [rhev-ansible : Create HD for vms] **********************************************************************************************************TASK [rhev-ansible : Create the vm] **************************************************************************************************************
changed: [localhost]
TASK [rhev-ansible : Add the vm to the inventory if needed] **************************************************************************************
included: /home/mkotelni/.ansible/roles/rhev-ansible/tasks/add-to-hosts.yml for localhost
TASK [rhev-ansible : Add the vms to your inventory] **********************************************************************************************
changed: [localhost]
PLAY [webservers] ********************************************************************************************************************************TASK [Gathering Facts] ***************************************************************************************************************************
ok: [httpd-vm]
TASK [ansible-httpd-demo-role : register the machine to subsription-manager] *********************************************************************
changed: [httpd-vm]
TASK [ansible-httpd-demo-role : Install httpd package] *******************************************************************************************
changed: [httpd-vm]
TASK [ansible-httpd-demo-role : Copy the template index.html file] *******************************************************************************
changed: [httpd-vm]
TASK [ansible-httpd-demo-role : Start the httpd server] ******************************************************************************************
changed: [httpd-vm]
TASK [ansible-httpd-demo-role : Add http service to firewalld] ***********************************************************************************
changed: [httpd-vm]
RUNNING HANDLER [ansible-httpd-demo-role : restart httpd] ****************************************************************************************
changed: [httpd-vm]
PLAY RECAP ***************************************************************************************************************************************
httpd-vm : ok=7 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=7 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

After the playbook completes, you will be able to see the VM created in your RHV environment.

The Virtual Machine as seen in the RHV UI

Without doing any extra configurations, or logging into the virtual machine, try to access the newly created web server — http://<ip-address>

The web page hosted on the web server you have just created

You have successfully deployed a web server on RHV using Ansible!

Conclusion

As you can see, working with RHV is quite easy. By using Ansible together with it, you will be able to deploy and manage large scale environments at ease. Ansible will describe a state of the environment you want to deploy on top of RHV, and RHV will reliably run it.

Take note that the procedure of the web server deployment took exactly 1 minute. From provisioning the virtual machine to deploying the web server. The procedure is easy and satisfying.

Give RHV a chance and try it out!

Feel free to leave comments with your thoughts and questions :)

--

--