Ansible is an agentless automation tool that uses SSH to configure systems. Playbooks are YAML files that define automation tasks. No agent needed on target hosts — only Python and SSH.
| Item | Syntax / Value | Description |
|---|---|---|
| Playbook | List of plays targeting host groups | Top-level YAML file: - name: / hosts: / tasks: |
| Play | Maps hosts to tasks | - name: Configure web servers hosts: webservers become: true |
| Task | Single unit of work | - name: Install Apache ansible.builtin.apt: name: apache2 |
| Module | Reusable action unit | apt, yum, copy, template, service, command, shell, file, user |
| Handler | Task triggered by notify | Restart service only when config changed |
| notify | Trigger a handler | notify: Restart Apache |
| vars | Variable definitions in play | vars: app_port: 8080 |
| vars_files | Load vars from external YAML file | vars_files: - vars/secrets.yml |
| group_vars/ | Variables for host groups | group_vars/webservers.yml |
| host_vars/ | Variables for specific hosts | host_vars/webserver01.yml |
| register | Capture task output | register: result - debug: var=result.stdout |
| when | Conditional task execution | when: ansible_os_family == 'Debian' |
| loop | Iterate over a list | loop: ['nginx', 'python3', 'git'] |
| with_items | Legacy loop (use loop instead) | with_items: - apache2 - mysql-server |
| block | Group tasks for error handling | block: / rescue: / always: |
| become | Privilege escalation (sudo) | become: true become_user: root |
| tags | Label tasks for selective run | tags: [install, configure] |
| ignore_errors | Continue on failure | ignore_errors: true |
| changed_when | Custom changed condition | changed_when: result.rc != 0 |
| failed_when | Custom failure condition | failed_when: result.rc > 1 |
| delegate_to | Run task on different host | delegate_to: localhost |
| run_once | Run task only once | run_once: true |
| serial | Rolling update batch size | serial: 2 # or '25%' |
| pre_tasks / post_tasks | Run before/after roles | pre_tasks: - name: Update cache |
| gather_facts | Collect host facts (default: true) | gather_facts: false # speeds up if not needed |
# site.yml — Complete Ansible Playbook
---
- name: Configure MyWebUniversity Web Servers
hosts: webservers
become: true
gather_facts: true
vars:
app_user: www-data
app_dir: /var/www/React/prod
cgi_dir: /usr/lib/cgi-bin
app_port: 80
app_name: mywebuniversity
vars_files:
- vars/secrets.yml # vault-encrypted secrets
pre_tasks:
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
when: ansible_os_family == 'Debian'
tasks:
- name: Install required packages
ansible.builtin.apt:
name:
- apache2
- python3
- python3-pip
- git
- curl
state: present
- name: Enable Apache CGI module
community.general.apache2_module:
name: "{{ item }}"
state: present
loop:
- cgid
- rewrite
- ssl
- headers
notify: Restart Apache
- name: Create application directory
ansible.builtin.file:
path: "{{ app_dir }}"
state: directory
owner: "{{ app_user }}"
group: "{{ app_user }}"
mode: '0755'
- name: Deploy HTML files
ansible.builtin.copy:
src: "files/html/"
dest: "{{ app_dir }}/"
owner: "{{ app_user }}"
mode: '0644'
notify: Reload Apache
- name: Deploy CGI scripts
ansible.builtin.copy:
src: "files/cgi-bin/"
dest: "{{ cgi_dir }}/"
owner: "{{ app_user }}"
mode: '0755'
- name: Configure Apache virtual host
ansible.builtin.template:
src: templates/vhost.conf.j2
dest: /etc/apache2/sites-available/{{ app_name }}.conf
owner: root
mode: '0644'
notify: Restart Apache
- name: Enable virtual host
ansible.builtin.command:
cmd: a2ensite {{ app_name }}.conf
changed_when: true
notify: Restart Apache
- name: Disable default site
ansible.builtin.command:
cmd: a2dissite 000-default.conf
changed_when: true
notify: Restart Apache
- name: Ensure Apache is running and enabled
ansible.builtin.service:
name: apache2
state: started
enabled: true
- name: Verify web server responds
ansible.builtin.uri:
url: "http://{{ ansible_default_ipv4.address }}/"
status_code: 200
register: health_check
- name: Display result
ansible.builtin.debug:
msg: "Server {{ inventory_hostname }} responded: {{ health_check.status }}"
handlers:
- name: Restart Apache
ansible.builtin.service:
name: apache2
state: restarted
- name: Reload Apache
ansible.builtin.service:
name: apache2
state: reloaded
# Run: ansible-playbook -i inventory/production site.yml
# Check: ansible-playbook -i inventory/production site.yml --check
# Limit: ansible-playbook -i inventory/production site.yml --limit webserver01
# Tags: ansible-playbook -i inventory/production site.yml --tags install