Skip to content
Learni
View all tutorials
DevOps

How to Get Started with Ansible for Automation in 2026

Lire en français

Introduction

Ansible is an open-source IT automation tool that configures, deploys, and orchestrates infrastructure without agents, using SSH. Unlike tools like Puppet or Chef that require agents, Ansible uses declarative YAML playbooks, making automation accessible even for beginners.

Why adopt it in 2026? With the rise of hybrid clouds and Kubernetes, Ansible excels at idempotent management: run a playbook multiple times, and the result stays the same. It handles thousands of servers in parallel, reduces human errors, and speeds up deployments. This tutorial guides you step by step to install Ansible, create an inventory, run simple playbooks (ping, package installs), and use variables. By the end, you'll automate your first Linux servers like a pro.

Prerequisites

  • Linux or macOS system (Ubuntu/Debian recommended)
  • Python 3.9+ installed
  • SSH access to target machines (user with passwordless sudo ideal)
  • A target machine for testing (VirtualBox VM or VPS)
  • Basic command-line knowledge

Install Ansible

install-ansible.sh
#!/bin/bash

# Update packages (Ubuntu/Debian)
sudo apt update
sudo apt upgrade -y

# Install Ansible via PPA (recommended for latest stable version)
sudo apt install software-properties-common -y
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt update
sudo apt install ansible -y

# Verify installation
ansible --version

This script installs Ansible on Ubuntu/Debian via the official PPA for the latest stable version. Use pip for a dev version if preferred: pip install ansible. Always check the version to confirm (e.g., Ansible 2.16+). Avoid Snap, which has SSH issues.

Configure the Inventory

The inventory defines your target hosts. It's a simple file listing IPs or hostnames, grouped logically. Ansible defaults to /etc/ansible/hosts, but create a local one for testing.

Create the Inventory File

inventory.ini
[webservers]
web1 ansible_host=192.168.1.10 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa
web2 ansible_host=192.168.1.11 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa

[dbservers]
db1 ansible_host=192.168.1.20 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa

[all:vars]
ansible_python_interpreter=/usr/bin/python3

This INI file defines two groups: webservers and dbservers. Vars like ansible_host (IP), ansible_user, and ansible_ssh_private_key_file avoid passwords. [all:vars] sets Python 3 globally. Test with ansible-inventory -i inventory.ini --list.

First Connection Test

Before playbooks, test connectivity with the ping module. It's idempotent and quick.

Ping Playbook

ping.yml
---
- name: Test de connexion
  hosts: all
  gather_facts: yes
  tasks:
    - name: Ping les hôtes
      ansible.builtin.ping:

This minimal playbook targets all hosts, gathers facts, and runs ping. It checks SSH/Python without changes. Run with ansible-playbook -i inventory.ini ping.yml. Success shows 'pong' for each host. Pitfall: forget sudo for passwordless SSH.

Automate Package Installation

Let's do a real task: update packages and install Nginx. Use modules like apt for Debian.

Install Nginx Playbook

install-nginx.yml
---
- name: Installer et configurer Nginx
  hosts: webservers
  become: yes
  gather_facts: yes
  tasks:
    - name: Mettre à jour apt cache
      ansible.builtin.apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Installer Nginx
      ansible.builtin.apt:
        name: nginx
        state: present

    - name: Démarrer Nginx
      ansible.builtin.systemd:
        name: nginx
        state: started
        enabled: yes

    - name: Vérifier que Nginx écoute
      ansible.builtin.uri:
        url: http://localhost
        status_code: 200

This playbook targets webservers, uses become: yes for sudo, updates apt, installs/starts Nginx, and verifies with uri. Idempotent: rerun safely. cache_valid_time avoids unnecessary updates. Test on a VM.

Using Variables and Handlers

Variables make playbooks reusable. Handlers handle notifications for changes (e.g., service restarts).

Playbook with Variables and Handlers

nginx-config.yml
---
- name: Configurer Nginx avec variables
  hosts: webservers
  become: yes
  vars:
    nginx_port: 8080
    nginx_user: www-data
  handlers:
    - name: Restart Nginx
      ansible.builtin.systemd:
        name: nginx
        state: restarted
  tasks:
    - name: Créer config Nginx personnalisée
      ansible.builtin.template:
        src: nginx.conf.j2
        dest: /etc/nginx/sites-available/default
        notify: Restart Nginx
      changed_when: false  # Pour test

    - name: Activer site
      ansible.builtin.file:
        src: /etc/nginx/sites-available/default
        dest: /etc/nginx/sites-enabled/default
        state: link
      notify: Restart Nginx

  post_tasks:
    - name: Flush handlers
      ansible.builtin.meta: flush_handlers

Define local vars (port, user). Handlers like Restart Nginx run if notified. template needs a nginx.conf.j2 file (create it). flush_handlers forces execution. Pitfall: without become, permissions fail.

Run the Playbooks

run-playbooks.sh
#!/bin/bash

INVENTORY="inventory.ini"

# Test ping
ansible-playbook -i $INVENTORY ping.yml -vvv

# Installer Nginx
echo "Installation Nginx..."
ansible-playbook -i $INVENTORY install-nginx.yml

# Config Nginx
echo "Configuration Nginx..."
ansible-playbook -i $INVENTORY nginx-config.yml

# Ad-hoc : arrêter tous les services Nginx
ansible webservers -i $INVENTORY -m systemd -a "name=nginx state=stopped"

This script runs all playbooks with -i for inventory and -vvv for verbose output. Ad-hoc ansible for one-shot tasks. Use --check for dry-run. Run chmod +x run-playbooks.sh first.

Best Practices

  • Always use dedicated inventories: Avoid /etc/ansible/hosts for production.
  • Enable gather_facts for machine facts (OS, packages).
  • YAML for variables: More readable than INI for complex ones.
  • Roles for modularity: Structure playbooks into reusable roles.
  • Vault for secrets: Encrypt passwords with ansible-vault.

Common Errors to Avoid

  • SSH not configured: 'UNREACHABLE' → check SSH keys and firewall (port 22).
  • Missing Python: 'No Python interpreter' → install python3 on targets.
  • Become without sudoers: 'insufficient privileges' → add user to sudoers.
  • Non-idempotent playbooks: Avoid raw shell; prefer dedicated modules.

Next Steps

Master roles, Galaxy (ansible-galaxy install), AWX/Tower for GUI, and GitHub Actions integration.

Check out our Learni trainings on DevOps and Ansible for certification paths. Official docs: docs.ansible.com.