Exploring Basics of Ansible

Rajesh GurajalaRajesh Gurajala
7 min read

🌐 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

  1. set passwordAuthentication to yes

  2. sudo systemctl restart ssh # To restart server to apply change we made

  3. 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 :

  1. Your playbook is becoming large and hard to maintain
    β†’ Roles help separate concerns using tasks/, vars/, defaults/, etc., improving readability and maintainability.

  2. You need modularity
    β†’ Break complex tasks into reusable, organized components (e.g., a role for setting up nginx, another for firewall, etc.).

  3. 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 by notify (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 the copy: 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.

0
Subscribe to my newsletter

Read articles from Rajesh Gurajala directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rajesh Gurajala
Rajesh Gurajala