Skip to main content

Command Palette

Search for a command to run...

Ansible 101: Your First Ping

Updated
6 min read
Ansible 101: Your First Ping
A
DevOps engineer focused on building, automating, and securing cloud infrastructure. I work with AWS, Docker, Terraform, and CI/CD pipelines to ship scalable and reliable systems. I write about cloud services & architecture, deployment strategies, and real-world DevOps practices.

Just think for once, you have 10+ servers and a new user is to be created on every server, some xyz package to be installed. To do this you, you individually SSH into every server one by one to do the work. Half way you've already made a few typos.

I started learning ansible because I wanted a better answer to this problem. This series documents what I've learned practically and not just theory.


What is Ansible?

Ansible is an open-source configuration tool. In simple terms, it let's you define what your servers should look like and then makes them all look that way, from a single machine.

It's maintained by RedHat, and is written in python. What makes it different is it doesn't have agents. It just used SSH the same way you'd use to manually log into a server. If a machine accepts SSH connection and has python on it, ansible can manage it. That's it.


The Architecture

Ansible has two types of machines:

  1. Control Node: The machine you run ansible from.

  2. Managed Hosts: The machine you're automating. They need SSH access and Python. That's it.

Control Node                          Managed Hosts
┌──────────────────────┐
│  ansible-core        │ ──SSH──▶│   server-1
│                      │ ──SSH──▶│   server-2
│  hosts (inventory)   │ ──SSH──▶│   server-3
│  ansible.cfg         │ ──SSH──▶│   server-4
│  modules             │            │     ...
│  playbooks           │            │
└──────────────────────┘

Four things live on the control node that you'll constantly interact with:

  • inventory / hosts: A file listing all your managed machines. IPs, hostnames or both.

  • ansible.cfg: Your configuration file. Which SSH user to use, which key, whether to prompt for passwords, where your roles are, etc.

  • modules: These are small python scripts that do the actual work. There's a module for creating user, installing packages, etc. You just call them.

  • playbooks: YAML files where you define what you want done on which machine.


Basic Environment

Install ansible from here.

Verify using ansible --version.

Project-Based Setup (Do this instead of /etc/ansible)

don't work out of /etc/ansible

The default global config at /etc/ansible/ansible.cfg works, but it means every project on your machine shares the same configuration. Instead, create a dedicated project directory and put your hosts and ansible.cfg in there:

~/my-ansible-project/
├── ansible.cfg
├── hosts
├── ansible-ssh-key.pem
└── playbooks/

Ansible has a config file lookup order, it checks the current directory first. So when you cd into your project and run any Ansible command, it automatically picks up the local ansible.cfg.


The Inventory File

The inventory file is where Ansible learns about your managed hosts. By convention it's called hosts, but you can name it anything and point to it from ansible.cfg

Basic list

65.0.109.64
ec2-65-0-109-64.ap-south-1.compute.amazonaws.com

Plain and simple - one host per line. You can use IP addresses, hostnames, or mix both.

Groups

Groups let you target specific subsets of your infrastructure:

[redhat]
65.0.109.64
10.22.0.1

[ubuntu]
ec2-65-0-109-64.ap-south-1.compute.amazonaws.com

Now you can run a playbook against redhat only, or ubuntu only, or all of them. This is where Ansible starts to feel powerful.

- ansible all --list-hosts

- ansible redhat --list-hosts

Nested Groups

You can create groups of groups with the :children keyword:

[redhat]
65.0.109.64

[ubuntu]
ec2-65-0-109-64.ap-south-1.compute.amazonaws.com

[asia:children]
redhat
ubuntu

ansible asia now targets all hosts. Useful when you want regional or environment-based groupings.


ansible.cfg - The config file

This is where you define the defaults for how Ansible behaves. Here's mine:

[defaults]
inventory = ./hosts
remote_user = ansible
private_key_file = ./ansible-ssh-key.pem
host_key_checking = false
ask_pass = false
roles = ./roles

[privilege_escalation]
become = true
become_user = root
become_method = sudo
become_ask_pass = false

Now let's break this down:

[defaults] section:

Setting What it does
inventory Where to find your hosts file
remote_user The SSH user Ansible logs in as on managed hosts
private_key_file Path to your .pem / SSH private key
host_key_checking = false Skips the "are you sure you want to connect?" SSH prompt. Useful in cloud environments where hosts are frequently recreated
ask_pass = false Don't prompt for SSH password (we're using key-based auth)

[privilege_escalation] section:

This is your sudo configuration.

Setting What it does
become = true Enable privilege escalation
become_user = root Escalate to root
become_method = sudo Use sudo to escalate
become_ask_pass = false Don't prompt for sudo password

The remote_user in my setup is a dedicated ansible user that exists on all managed hosts, it has SSH key access and passwordless sudo. This is the standard pattern you'll see in real environments.


Reading outputs:

The color of the output in ansible tell you something, like:

Color Status Meaning
Red🔴 FAILED Something went wrong
Green🟢 OK Task ran successfully, nothing changed
Yellow🟡 CHANGED Task ran and made a change on the host
Blue🔵 SKIPPED Task was skipped (condition not met)

The distinction between OK and CHANGED is more important than it seems. If you run a playbook that installs a package and the output is green (OK), it means the package was already installed. Yellow (CHANGED) means it actually installed something.


First ansible command

With the basic setup in place, let's verify connectivity to all managed hosts.

ansible all -m ping

A healthy response looks like this:

If it's green, it means you're in. Everything from here on is just telling Ansible what to do with that connection.


Next, we'll move from single commands to actual playbooks, writing YAML, understanding ad-hoc commands, etc. Soon all of this will look like a walk in the park. STAY TUNED!!

Ansible

Part 1 of 1