I have been teaching Ansible since 2016 through Ansible Pilot (6.1K YouTube subscribers, 1M+ views) and 8 books. This is the tutorial I wish I had when starting.
What Is Ansible?
Ansible is an automation tool that lets you manage servers without installing anything on them. You write YAML files describing what you want, and Ansible makes it happen over SSH.
Why Ansible:
- No agents to install (uses SSH)
- Human-readable YAML syntax
- Thousands of pre-built modules
- Works on Linux, Windows, network devices, cloud
- Free and open source (backed by Red Hat)
Installation
# Ubuntu/Debian
sudo apt update && sudo apt install ansible -y
# RHEL/Fedora
sudo dnf install ansible-core -y
# macOS
brew install ansible
# pip (any OS)
pip3 install ansible
# Verify
ansible --versionYour First Inventory
The inventory tells Ansible which servers to manage:
# inventory.ini
[webservers]
web1.example.com
web2.example.com
[databases]
db1.example.com
[all:vars]
ansible_user=admin
ansible_ssh_private_key_file=~/.ssh/id_ed25519For testing on localhost:
# inventory.ini
[local]
localhost ansible_connection=localAd-Hoc Commands (Quick Start)
Run commands on remote servers without writing a playbook:
# Ping all servers
ansible all -i inventory.ini -m ping
# Check uptime
ansible all -i inventory.ini -m command -a "uptime"
# Install a package
ansible webservers -i inventory.ini -m apt -a "name=nginx state=present" --become
# Copy a file
ansible all -i inventory.ini -m copy -a "src=./app.conf dest=/etc/app.conf"
# Gather facts (system info)
ansible all -i inventory.ini -m setupYour First Playbook
Playbooks are YAML files describing automation tasks:
---
# site.yml - My first playbook
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install Nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: Start Nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true
- name: Deploy index page
ansible.builtin.copy:
content: |
<h1>Hello from {{ inventory_hostname }}</h1>
<p>Deployed by Ansible</p>
dest: /var/www/html/index.htmlRun it:
ansible-playbook -i inventory.ini site.ymlVariables
---
- name: Deploy with variables
hosts: webservers
become: true
vars:
app_name: myapp
app_port: 8080
packages:
- nginx
- python3
- git
tasks:
- name: Install packages
ansible.builtin.apt:
name: "{{ packages }}"
state: present
- name: Deploy config
ansible.builtin.template:
src: app.conf.j2
dest: "/etc/{{ app_name }}/config.yml"Handlers (Restart Only When Needed)
tasks:
- name: Update 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: restartedHandlers only run if the task reports a change. Efficient.
Conditionals and Loops
tasks:
# Conditional
- name: Install on Ubuntu only
ansible.builtin.apt:
name: ubuntu-specific-package
when: ansible_distribution == "Ubuntu"
# Loop
- name: Create multiple users
ansible.builtin.user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
loop:
- { name: alice, groups: sudo }
- { name: bob, groups: developers }
- { name: carol, groups: "sudo,developers" }Roles (Reusable Automation)
Roles organize your automation into reusable packages:
# Create a role structure
ansible-galaxy init roles/webserver
# Directory structure:
# roles/webserver/
# tasks/main.yml
# handlers/main.yml
# templates/
# files/
# vars/main.yml
# defaults/main.yml# roles/webserver/tasks/main.yml
---
- name: Install web server
ansible.builtin.apt:
name: nginx
state: present
- name: Deploy configuration
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart NginxUse roles in playbooks:
---
- name: Configure servers
hosts: webservers
become: true
roles:
- webserver
- monitoring
- securityBest Practices
- Always use FQCNs โ
ansible.builtin.copynotcopy - Use
--check --diffbefore applying changes - Keep secrets in Ansible Vault โ
ansible-vault encrypt secrets.yml - Use roles for reusable automation
- Tag everything for selective runs
- Test with Molecule for role testing

