What is Ansible?
Ansible is an open-source automation tool that lets you configure servers, deploy applications, and orchestrate complex workflows — all using simple YAML files called playbooks.
Why developers love Ansible:
- Agentless — no software to install on target machines, just SSH
- YAML-based — human-readable, version-controllable
- Idempotent — run playbooks multiple times safely
- Batteries included — 3,000+ built-in modules for every task
Prerequisites
- A Linux/macOS machine (or Windows with WSL) — see How to Install Ansible
- Basic terminal/command-line knowledge
- SSH access to at least one remote host (or use
localhost)
Step 1: Install Ansible
# Quick install via pip
pip3 install ansible
# Verify
ansible --version
Or try our Ansible Playground — run playbooks in your browser with zero setup.
Step 2: Create Your Inventory
The inventory defines which hosts Ansible manages:
# inventory.ini
[webservers]
web1 ansible_host=192.168.1.10 ansible_user=ubuntu
web2 ansible_host=192.168.1.11 ansible_user=ubuntu
[dbservers]
db1 ansible_host=192.168.1.20 ansible_user=centos
Test connectivity:
ansible all -i inventory.ini -m ping
Step 3: Write Your First Playbook
Create first-playbook.yml:
---
- name: My first Ansible playbook
hosts: webservers
become: true
tasks:
- name: Ensure Apache is installed
ansible.builtin.apt:
name: apache2
state: present
update_cache: true
- name: Start Apache service
ansible.builtin.service:
name: apache2
state: started
enabled: true
- name: Deploy index page
ansible.builtin.copy:
content: "<h1>Hello from {{ inventory_hostname }}</h1>"
dest: /var/www/html/index.html
Run it:
ansible-playbook -i inventory.ini first-playbook.yml
Step 4: Understand Key Concepts
Modules
Modules are the units of work in Ansible. Common ones:
| Module | Purpose | Example |
|---|---|---|
ansible.builtin.apt | Install packages (Debian) | apt: name=nginx state=present |
ansible.builtin.yum | Install packages (RHEL) | yum: name=httpd state=present |
ansible.builtin.copy | Copy files | copy: src=file.txt dest=/tmp/ |
ansible.builtin.template | Template files with Jinja2 | template: src=app.conf.j2 dest=/etc/ |
ansible.builtin.service | Manage services | service: name=nginx state=started |
ansible.builtin.file | Manage files/directories | file: path=/data state=directory |
ansible.builtin.user | Manage users | user: name=deploy state=present |
ansible.builtin.debug | Print messages | debug: msg="Hello" |
Variables
---
- name: Using variables
hosts: webservers
vars:
http_port: 8080
app_name: myapp
tasks:
- name: Show variables
ansible.builtin.debug:
msg: "{{ app_name }} runs on port {{ http_port }}"
Loops
- name: Install multiple packages
ansible.builtin.apt:
name: "{{ item }}"
state: present
loop:
- nginx
- git
- curl
- htop
Conditionals
- name: Install on Debian only
ansible.builtin.apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: Install on RHEL only
ansible.builtin.yum:
name: nginx
state: present
when: ansible_os_family == "RedHat"
Handlers
Handlers run only when notified by a task that made a change:
tasks:
- name: Deploy nginx config
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
handlers:
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
Step 5: Organize with Roles
Roles structure your automation into reusable components:
roles/
webserver/
tasks/
main.yml
handlers/
main.yml
templates/
nginx.conf.j2
defaults/
main.yml
vars/
main.yml
Use a role in a playbook:
---
- name: Configure web servers
hosts: webservers
become: true
roles:
- webserver
Create a role skeleton:
ansible-galaxy init roles/webserver
Step 6: Use Ansible Vault for Secrets
Never store passwords in plain text:
# Create encrypted file
ansible-vault create secrets.yml
# Edit encrypted file
ansible-vault edit secrets.yml
# Run playbook with vault
ansible-playbook playbook.yml --ask-vault-pass
Common Ad-Hoc Commands
# Ping all hosts
ansible all -m ping
# Check uptime
ansible all -m command -a "uptime"
# Copy a file
ansible webservers -m copy -a "src=file.txt dest=/tmp/"
# Install a package
ansible webservers -m apt -a "name=nginx state=present" --become
# Restart a service
ansible webservers -m service -a "name=nginx state=restarted" --become
# Gather facts
ansible web1 -m setup
What's Next?
- Practice — Use the Ansible Playground to experiment
- Follow Learning Paths — Structured courses at /learning-paths
- Browse 800+ Tutorials — Real-world examples at /articles
- Read the Books — Check out Luca Berton's Ansible books
Related Articles
- How to Install Ansible — Installation on all platforms
- Ansible Facts — Gather system information
- Ansible Vault — Encrypt secrets
- Ansible Dry Run — Test playbooks safely
- Ansible vs Terraform — When to use each tool
- Ansible Training — Courses and certifications
- FQCN in Ansible — Fully Qualified Collection Names
- Ansible Error Handling — Handle failures gracefully
This tutorial is part of AnsibleByExample — 800+ practical Ansible tutorials by Luca Berton.