What is Ansible?
Ansible is an open-source automation tool used for:
- Configuration management – Automatically setting up and maintaining software and systems.
- Application deployment – Deploying code to multiple servers.
- Task automation – Running repetitive tasks like backups or updates.
Ansible uses YAML-based files called Playbooks to define automation instructions. It connects over SSH and does not require any agent software on the managed machines.
What are Roles in Ansible?
Roles in Ansible are a way to organize and reuse code. Instead of writing large, monolithic playbooks, you can break them into smaller, modular components.
Key Benefits of Roles:
- Reusability across multiple playbooks or projects.
- Better organization of files (tasks, handlers, variables, templates).
- Easier collaboration and maintenance.
A Role has a specific directory structure:
my_role/
├── defaults/
│ └── main.yml # Default variables
├── files/
│ └── ... # Static files to copy
├── handlers/
│ └── main.yml # Handlers (e.g., restart service)
├── meta/
│ └── main.yml # Role metadata (dependencies, etc.)
├── tasks/
│ └── main.yml # The main list of tasks to run
├── templates/
│ └── ... # Jinja2 templates
├── vars/
│ └── main.yml # Variables with higher priority
Example usage
Ansible can be used in a multi-user (admin) environment. The Ansible playbooks are stored in Git, a distributed version control system.
Each user has their own copy of the Ansible playbooks via Git, which they can maintain and test before pushing changes to the main Ansible repository.
In my setup, I’ve configured a post-update hook in the Ansible Git repository that automatically pulls the latest changes into the Ansible master directory.
User config
~/.ansible.cfg:
user admin or ansible:
inventory = /home/<USER>/ansible/hosts
inventory_dir = /home/<USER>/ansible
playbook_dir = /home/<USER>/ansible/playbooks
collections_paths = /home/<USER>/ansible/
Inventory hosts file
[ONT]
server01-o
server02-o
[TEST]
server01-t
server02-t
[ACC]
server01-a
server02-a
[PROD]
server01-p
server02-p
[APACHE:children]
ONT
TEST
ACC
PROD
Search path for variables are group_vars/all -> group_vars/groups -> host_vars/hosts
ansible
├── admin_playbooks #playbooks for test and one time usage.
├── ansible_collections #external plugins
│ └── vmware
├── files #Storage of files, endpoints of links from roles to keep everything in one place.
├── group_vars #Variables which is common in groups
│ ├── ACC
│ ├── APACHE
│ ├── DMZ
│ ├── ONT
│ ├── PROD
│ ├── TEST
│ ├── all
├── hosts #Inventory
├── host_vars #Variables specific for hosts
│ ├── server01-a
│ ├── server02-a
│ ├── server01-o
│ ├── server02-o
│ ├── server01-t
│ ├── server02-t
│ ├── server01-p
│ ├── server02-p
├── playbooks
│ ├── apache.yml
│ ├── autofs.yml
│ ├── defaults.yml
│ ├── postfix.yml
│ ├── roles
│ │ ├── apache
│ │ │ ├── handlers
│ │ │ │ └── main.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── tasks
│ │ │ │ ├── main.yml
│ │ │ ├── templates
│ │ │ │ └── postfix
│ │ │ │ ├── main.cf.j2
│ │ │ │ └── master.cf.j2
│ │ │ └── tests
│ │ │ ├── inventory
│ │ │ └── test.yml
│ │ ├── autofs
│ │ │ ├── handlers
│ │ │ │ └── main.yml
│ │ │ └── tasks
│ │ │ └── main.yml
│ │ ├── defaults
│ │ │ ├── handlers
│ │ │ │ └── main.yml
│ │ │ └── tasks
│ │ │ └── main.yml
│ │ ├── postfix
│ │ │ ├── defaults
│ │ │ │ └── main.yml
│ │ │ ├── handlers
│ │ │ │ └── main.yml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── tasks
│ │ │ │ └── main.yml
│ │ │ ├── templates
│ │ │ │ └── postfix
│ │ │ │ ├── main.cf.j2
│ │ │ │ ├── main.dmz_cf.j2
│ │ │ │ └── master.cf.j2
│ │ │ └── tests
│ │ │ ├── inventory
│ │ │ └── test.yml
├── README.md
└── scripts
Example autofs role
playbooks/roles/autofs/tasks/main.yml
- name: install packages voor automount
yum:
name:
- autofs
state: present
- name: enable autofs on system reboot
service:
name: autofs
enabled: yes
- name: auto.master
lineinfile:
path: /etc/auto.master
regexp: '^(.*){{ item.file }}(.*)$'
line: "{{ item.path | regex_replace(' ', '') }} {{ item.file | regex_replace(' ', '') }} {{ item.master_options }}"
state: "{{ item.state }}"
backup: yes
with_items:
- "{{autofs}}"
notify:
- restart autofs
- name: auto.nfs
lineinfile:
path: "{{ item.file }}"
regexp: '^(.*){{ item.directory }}(.*)$'
line: "{{ item.directory }} {{ item.options }} {{ item.mount }}"
state: "{{ item.state }}"
create: yes
backup: yes
with_items:
- "{{autofs}}"
when: '"nfs" in item.options'
notify: restart autofs
Variables in the host_vars/server...
autofs:
- { file: '/etc/auto.shares',
path: '/mnt/share',
link: '/appl/share',
directory: 'share',
options: '-fstype=nfs,rw,soft,intr',
master_options: '--timeout=60 ',
mount: '172.16.01:/appl/share',
state: 'present',
}
playbooks/roles/autofs/handlers/main.yml
---
# handlers file for autofs
- name: restart autofs
service:
name: autofs
state: reloaded
playbooks/autofs.yml
---
- hosts: all
become_user: root
become: yes
roles:
- { role: autofs, when: autofs is defined }
Running the autofs role playbook for a specific group:
ansible-playbook playbooks/autofs.yml -l ONT
A lot of ansible playbook roles can be found at Github or Gitlab.