Ansible is an agentless Orchestrator and an Automation tool that makes Linux/Windows applications and systems easier to provision, deploy, and do configuration management tasks. In this blog, we will focus on installing Ansible on our Redhat 9 and this install will form the base for our Aria Automation stack we will build on later during our journey.
Components of Ansible Engine
- Control Node – Also known as the brain of the system that has Ansible installed.
- Managed Node – These are the clients in simple terms.
- Host Inventory – List of all hosts that can be managed with Ansible eg: Webservers
- PlayBooks – are a set of group-related tasks that are to be executed on a managed node eg; Prod Dev, etc
- Modules – ready-to-use codes that help in package installation, file manipulation and service management that are run when a playbook is run. Modules are stored in the /lib/ansible/modules.
To list all repositories on the VM, run dnf repolist . Ansible Core package is by default included in the AppStream repository in RHEL9
[root@aap ~]# useradd awkWe will allow Linux users to run any commands anywhere by adding an entry in /etc/sudoers, this entry should be an all-managed server as well for Ansible to execute commands as a admin user if necessary.
## Allow root to run any commands anywhere without prompting for password
awk ALL=(ALL) NOPASSWD:ALLThe below option can be used in case we wish to input a password following the execution of an Ansible command
## Allow root to run any commands anywhere without prompting for password
awk ALL=(ALL) PASSWD:ALLGenerate SSH keys for the ariaadm user
[awk@aap root]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ariaadm/.ssh/id_rsa):Copy the ssh key on every Ansible-managed node for us to do password-less login to all servers managed with Ansible via SSH.
[awk@aap root]$ ssh-copy-id ariaadm@webserver01
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ariaadm/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are
We also need to ensure we add a visudo if we wish to login and execute commands as non root

On EVERY host you want Ansible to manage:
- SSH in as
awk - Run:
sudo -n true - If it says
OK→ done - If it asks for a password → add:
awk ALL=(ALL) NOPASSWD:ALL
The main configuration files on ansible are under /etc/ansible. The two important files in here are the /etc/ansible/hosts (also known as inventory file), etc/ansible/ansible.cfg ( also known as config file). Update lists of hosts to be managed by ansible into an inventory file or the host’s file below.The default location for the host inventory file is /etc/ansible/hosts.

Create a directory for playbooks to add our yaml playbooks

Tweak the following parameter in Ansible config file /etc/ansible/ansible.cfg to enable privilege escalation that will enable us to run commands as root. Here inventory = ./hosts is the host file
[defaults]
#inventory = ./inventory.ini
inventory = ./hosts
ansible_python_interpreter = /usr/bin/python3
forks = 5
host_key_checking = False
[privilege_escalation]
#become = False
become=true
become_method=sudo
become_user=root
become_ask_pass=False
host_key_checking=false
remote_user = awk
ask_pass = FalseCreate an inventory file in /etc/ansible and and define hosts into groups as shown
What this means:
- We have Ubuntu machines
- We have Zorin OS (Ubuntu‑based)
- We have CentOS machines
Each group can be targeted separately:
cat /etc/ansible/hosts
[ubuntu]
gitlab ansible_host=GitLab.ash.local ansible_user=awk ansible_become=yes
[zorin]
platform ansible_host=platform.ash.local ansible_user=awk ansible_become=yes
[centos]
centos01 ansible_host=centos01.ash.local ansible_user=awk ansible_become=yes
centos02 ansible_host=centos02.ash.local ansible_user=awk ansible_become=yes
Run the following Ansible command to perform an Ansible check from the control node to the managed node
#This will run on all defined under [hosts] in the /etc/ansible/hosts
ansible all -m shell -a “ifconfig”

Each group can be targeted separately:
#This will run on all defined under [hosts] in the /etc/ansible/hosts for a specific group
ansible <ubuntu>-m shell -a "ifconfig"
ansible ubuntu -m ping # for ping to ubuntu hosts
ansible zorin -m ping # for ping to zentos hosts
ansible centos -m ping # for ping to centos hosts
So here we will run ifconfig against a category

Prefix the above Ansible command with –become to perform an Ansible check from the control node to the managed node elevating us as a root user.
[ariaadm@aap ansible]$ ansible -m command -a "lvs" webs --become
webserver02 | CHANGED | rc=0 >>
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root rhel_unknown -wi-ao---- 11.91g
swap rhel_unknown -wi-ao---- 1.50g
webserver01 | CHANGED | rc=0 >>
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root rhel_unknown -wi-ao---- 11.91g
swap rhel_unknown -wi-ao---- 1.50g If we wish to type a password following the execution of a command we use the option K
[ariaadm@aap ansible]$ ansible -m command -a "lvs" webs --become -K
BECOME password:
webserver01 | CHANGED | rc=0 >>
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root rhel_unknown -wi-ao---- 11.91g
swap rhel_unknown -wi-ao---- 1.50g
webserver02 | CHANGED | rc=0 >>
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root rhel_unknown -wi-ao---- 11.91g
swap rhel_unknown -wi-ao---- 1.50g
[ariaadm@aap ansible]$
Install and remove software packages via Ansible Playbooks
To apply a playbook we use the command ansible-playbook
Our ansible.cfg file will have by default inventory for all hosts on it so if you just run the below command it will apply settings across the whole lot of hosts inside the inventory file
ansible-playbook install-vlc-ubuntu.yml
To apply to a specific host for example, we will just write a new yaml and just be very specific to a set of “ubuntu” hosts defined in the main ansible hosts file

So here is the config is applied just to be ubuntu category.
awk@ansible:/etc/ansible/playbooks$ cat remove-vlc-ubuntu.yml
---
- hosts: ubuntu
become: true
tasks:
- name: remove vlc Ubuntu
apt:
name: vlc
state: absent
when: ansible_distribution == 'Ubuntu'
awk@ansible:/etc/ansible/playbooks$
As expected we can see its removed from just the ubuntu host

#Lets just apply it back and see what happens on the zorin category

So here is the config is applied just to be zorin category.
awk@ansible:/etc/ansible/playbooks$ cat install-vlc-ubuntu.yml
---
- hosts: zorin
become: true
tasks:
- name: install vlc Ubuntu
apt:
name: vlc
when: ansible_distribution == 'Ubuntu'
Next we will install it back
ansible-playbook --ask-become-pass install-vlc-ubuntu.yml
Lets check the package installed
ansible zorin -m shell -a “apt list –installed”

Upgrading hosts via Ansible
So i’ll just define a new yaml as upgrade-ubuntu-packages.yml
---
- hosts: platform
become: true
gather_facts: true
tasks:
- name: Update apt cache
ansible.builtin.apt:
update_cache: yes
cache_valid_time: 3600
when: "'Ubuntu' in (ansible_distribution_like | default([])) or ansible_distribution == 'Zorin OS'"
- name: Upgrade all packages
ansible.builtin.apt:
upgrade: dist
when: "'Ubuntu' in (ansible_distribution_like | default([])) or ansible_distribution == 'Zorin OS'"
Run the ansible commands for the yaml

Installing Multiple apps

cat multiple-apps-ubuntu.yml
- hosts: all
become: true
tasks:
- name: Install Nginx and Git on Ubuntu
apt:
name:
- nginx
- git
state: latest
update_cache: yes
when: ansible_distribution == "Ubuntu"

How to remove applications properly on Ubuntu/Zorin
ansible zorin -m shell -a "dpkg -l | grep vlc"
ansible zorin -m shell -a "apt list --installed | grep vlc"
You need to remove all VLC-related packages, not just vlc.
ansible zorin -m package -a "name=vlc state=absent"
Here’s the correct Ansible command for Zorin
ansible zorin -m shell -a "apt purge -y 'vlc' 'libvlc'"
Then clean up:
ansible zorin -m shell -a "apt autoremove -y"

