Exploring Basics of Ansible

π What is Ansible?
Ansible is an open-source IT automation tool developed by Red Hat. It is used to automate configuration management, application deployment, infrastructure provisioning, orchestration, and more.
π‘ Why Ansible?
Imagine you manage 10, 100, or even 1000 servers. Now think about applying a software update, changing a configuration, or deploying an app on all of them. Doing it manually would be slow and error-prone. Ansible solves this by:
π§ Being simple and human-readable (uses YAML-based playbooks)
π Being agentless (no software required on remote machines except SSH and Python)
β‘ Running tasks in parallel (across multiple systems)
π οΈ Being idempotent (you can run the same playbook multiple times with the same outcome)
π Scalability (from a few servers to thousands)
To run Ansible commands or playbooks without entering a password every time, you need to set up SSH key-based authentication between your control machine (your laptop) and the managed host (e.g., a server).
π Setting up Password less authentication :
There are 2 ways using with either password or ssh key file.
Through ssh key file:
ssh-copy-id -f "-o IdentityFile ./qwerty.pem" ubuntu@< PUBLIC-IPV4-ADDRESS >
# actual command for actual password-less auth. by providing public ip addr. and ssh key file
Through password:
Iβm trying this with a AWS EC2 instance which by default has authentication via ssh key file.
So i will be logging in to instance with key file and will enable password auth. through these steps which u can ignore if u are having password auth. by default to ur servers ( Eg: azure vmβs etc.. )
0 a ) sudo vim /etc/ssh/sshd_config.d/60-cloudimg-settings.conf # To enable password auth
0 b ) sudo vim /etc/ssh/sshd_config
# To enable password auth if etc/ssh/sshd_config.d/60-cloudimg-settings.conf was not found
set passwordAuthentication to yes
sudo systemctl restart ssh # To restart server to apply change we made
sudo passwd ubuntu # Set a new password
Now, a password is set to oue EC2 instance. lets try ssh-copy-id with a password now.
ssh-copy-id ubuntu@<ip-addr> # Asks password, enter and then ur done
π Inventory file:
The Inventory File in Ansible lists all the hosts (remote machines) that Ansible manages.
It defines groups of hosts, connection details, and optional variables.
It can be written in INI, YAML, or Dynamic inventory scripts.
Either create a hosts file in /etc/ansible folder so that u dont need to mention location of inventory file, every time u run ansible commands or u can simply save it in any location and mention it with -i argument in ansible commands.
Structure:
1) Basic:
user_name_1@public_ip_1
user_name_2@public_ip_2
and so on β¦β¦.
2) Grouping hosts:
[dev]
user_name_1@public_ip_1
user_name_2@public_ip_2
[prod]
user_name_3@public_ip_3
user_name_4@public_ip_4
β‘ Ansible Adhoc commands:
In Ansible, ad-hoc commands are one-liners you run directly in the terminal to perform quick tasks on your managed nodes β without writing a full playbook.
π§ͺ Syntax of an Ad-Hoc Command:
Copy
Copy
ansible <host-pattern> -m <module-name> -a "<module-options>"
πΉ Components:
ansible
: the CLI tool.<host-pattern>
: inventory group or host (all
,webservers
,192.168.1.10
).-m <module-name>
: specify which module to use.-a "<args>"
: module arguments in quotes.
Know more on adhoc commands at https://learning-ansible.hashnode.dev/ansible-ad-hoc-commands
π§Ύ Ansible Adhoc Play books:
An Ansible Playbook is a YAML file that defines a set of instructions (tasks) to automate configuration, deployment, or orchestration of systems. Unlike ad-hoc commands, playbooks are reusable, organized, and scalable.
π Key Points:
Written in YAML format
Can target multiple hosts or groups
Supports variables, conditionals, loops, handlers, etc.
More powerful and structured than ad-hoc commands
π Basic Structure of a Playbook (having a single play) :
---
- name: Install and start Apache
hosts: webservers
become: yes
tasks:
- name: Install Apache
apt:
name: apache2
state: present
- name: Ensure Apache is running
service:
name: apache2
state: started
enabled: true
π§Ύ Ansible Playbook with 2 Plays β Example :
---
- name: Play 1 - Install NGINX on webservers
hosts: webservers
become: yes
tasks:
- name: Install NGINX
apt:
name: nginx
state: present
update_cache: yes
- name: Start NGINX
service:
name: nginx
state: started
enabled: true
- name: Play 2 - Install MySQL on dbservers
hosts: dbservers
become: yes
tasks:
- name: Install MySQL
apt:
name: mysql-server
state: present
update_cache: yes
- name: Ensure MySQL is running
service:
name: mysql
state: started
enabled: true
βΆοΈ Run a Playbook
ansible-playbook playbook.yml
π With a Custom Inventory File
ansible-playbook -i inventory.ini playbook.yml
π Ansible Roles:
Ansible roles provide a structured way to organize and reuse code by encapsulating related tasks, variables, files, templates, and handlers into a self-contained directory hierarchy.
This modular design allows complex playbooks to be broken down into smaller, manageable, and reusable components that follow a standardized format, improving readability, scalability.
Each role represents a specific function or service (like installing Apache, configuring users, or deploying applications), and can be easily shared across projects or teams.
β When and why to use roles over playbooks :
Your playbook is becoming large and hard to maintain
β Roles help separate concerns usingtasks/
,vars/
,defaults/
, etc., improving readability and maintainability.You need modularity
β Break complex tasks into reusable, organized components (e.g., a role for setting upnginx
, another forfirewall
, etc.).Ansible Galaxy
β U can share ur roles in github, ansible galaxy and u can also use existing roles from ansible galaxy.
βΆοΈ To create a role:
ansible-galaxy init <NAME>
πΉ Example:
ansible-galaxy init webserver
πΉ This creates the following structure:
webserver/
βββ defaults/
β βββ main.yml
βββ files/
βββ handlers/
β βββ main.yml
βββ meta/
β βββ main.yml
βββ tasks/
β βββ main.yml
βββ templates/
βββ tests/
β βββ inventory
β βββ test.yml
βββ vars/
βββ main.yml
This is the complete role skeleton, ready to fill in with your logic
components in an Ansible role folder:
π tasks/
Contains:
main.yml
Purpose:
Holds the main list of tasks to execute in order.β This is mandatory; role execution starts here.
π handlers/
Contains:
main.yml
Purpose:
Stores handlersβspecial tasks triggered bynotify
(e.g., restarting a service after a config change).π Runs only if notified by a task.
π defaults/
Contains:
main.yml
Purpose:
Defines default variables for the role, which users can override easily.πͺΆ Lowest priority in variable precedence.
π vars/
Contains:
main.yml
Purpose:
Stores variables that are hard-coded and have higher precedence than defaults.
π files/
Contains: Any static files (e.g.,
.conf
,.sh
,.txt
)Purpose:
Holds static files that are copied to target machines using thecopy:
module.
π templates/
Contains: Jinja2 template files (
.j2
)Purpose:
Holds dynamic templates with variables (e.g., config files with placeholders).π§ Used with the
template:
module.
π meta/
Contains:
main.yml
Purpose:
Metadata about the role: author, license, dependencies, etc.π Supports
dependencies:
to include other roles automatically.
π tests/
Contains:
inventory
β Test inventory file (e.g., localhost)test.yml
β A sample playbook that uses the role
structuring a play book with ansible role
Lets structure a playbook with ansible role:
THE PLAYBOOK:
---
- hosts: all
become: true
tasks:
- name: Install Apache HTTP Server
ansible.builtin.apt:
name: apache2
state: present
update_cache: yes
- name: Copy index.html to Apache web directory
ansible.builtin.copy:
src: index.html
dest: /var/www/html/index.html
owner: root
group: root
mode: '0644'
β Now, lets organise this.
STEP 1:
Cut all the plays under tasks, and paste it undertasks > main.yaml
STEP 2:
place index.html
in the files folder, and in tasks > main.yaml
change src : index.html
to src : files/index.html
STEP 3:
In our playbook under become : true
, include this:
roles:
- temp
STEP 4:
Now u can run playbook with ansible-playbook playbook.yaml
command, and u will see same result.
Subscribe to my newsletter
Read articles from Rajesh Gurajala directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
