DevOps Classroom notes 16/Jun/2026

Ansible – Variables & Notify/Handlers


1. Ansible Variables

Variables store values that can be reused across tasks, playbooks, and roles.


1.1 Defining Variables

In a Playbook (vars block)

- name: Demo playbook
  hosts: webservers
  vars:
    http_port: 80
    app_name: myapp
  tasks:
    - name: Print app name
      debug:
        msg: "App is {{ app_name }} on port {{ http_port }}"
- name: demo
  become: yes
  hosts: ubuntu
  tasks:
    - name: Print app name
      ansible.builtin.debug:
        msg: "App is {{ app_name }} on port {{ http_port }}"

ansible-playbook -i ubuntu --user ansible -e "app_name=demo-vars http_port=8080" demo.yaml

In Separate Variable Files

# vars/main.yml
db_host: localhost
db_port: 5422
db_name: production
# Reference in playbook
- name: Setup DB
  hosts: dbservers
  vars_files:
    - vars/main.yml
  tasks:
    - debug:
        msg: "DB at {{ db_host }}:{{ db_port }}"
ansible-playbook playbook.yml -e "@vars_file.yml"

1.2 Variable Precedence (Low → High)

Priority Source
1 (lowest) Role defaults (defaults/main.yml)
2 Inventory group vars
2 Inventory host vars
4 Playbook group_vars/
5 Playbook host_vars/
6 Playbook vars: block
7 vars_files:
8 vars_prompt:
9 Task vars:
10 set_fact / registered vars
11 Extra vars -e (highest)

Rule of thumb: -e (extra vars) always wins.


1.3 group_vars and host_vars Directory Structure

inventory/
├── hosts                  # inventory file
├── group_vars/
│   ├── all.yml            # applies to ALL hosts
│   ├── webservers.yml     # applies to webservers group
│   └── dbservers.yml
└── host_vars/
    ├── web1.yml           # applies to host web1 only
    └── web2.yml
# group_vars/webservers.yml
nginx_version: "1.24"
max_workers: 4

1.4 Registering Variables

Capture the output of a task into a variable.

- name: Check disk usage
  command: df -h /
  register: disk_output

- name: Show disk info
  debug:
    msg: "{{ disk_output.stdout }}"

Common register attributes:

Attribute Description
.stdout Standard output as string
.stdout_lines Output as list of lines
.stderr Standard error output
.rc Return code (0 = success)
.failed Boolean – did the task fail?
.changed Boolean – did something change?

1.5 set_fact – Dynamic Variables

- name: Set a computed variable
  set_fact:
    full_url: "http://{{ ansible_host }}:{{ http_port }}/{{ app_name }}"

- name: Use the computed variable
  debug:
    msg: "URL is {{ full_url }}"

1.6 vars_prompt – Interactive Variables

- name: Deploy app
  hosts: all
  vars_prompt:
    - name: deploy_env
      prompt: "Enter environment (dev/staging/prod)"
      private: no
  tasks:
    - debug:
        msg: "Deploying to {{ deploy_env }}"

1.7 Extra Vars (Command Line)

# Pass single variable
ansible-playbook deploy.yml -e "version=2.1"

# Pass multiple variables
ansible-playbook deploy.yml -e "version=2.1 env=prod"

# Pass a vars file
ansible-playbook deploy.yml -e "@vars/prod.yml"

1.8 Variable Filters (Jinja2)

vars:
  names: ["alice", "bob", "charlie"]
  score: 85.6789

tasks:
  - debug:
      msg: "{{ names | join(', ') }}"         # alice, bob, charlie

  - debug:
      msg: "{{ score | round(2) }}"           # 85.68

  - debug:
      msg: "{{ undefined_var | default('N/A') }}"  # N/A if not defined

  - debug:
      msg: "{{ app_name | upper }}"           # MYAPP

2. Notify & Handlers

Handlers are tasks that run only when notified — used to trigger actions like restarting services after config changes.


2.1 Basic Notify + Handler Pattern

- name: Configure Nginx
  hosts: webservers
  tasks:
    - name: Copy nginx config
      copy:
        src: nginx.conf
        dest: /etc/nginx/nginx.conf
      notify: Restart Nginx           # ← triggers handler IF task changes

  handlers:
    - name: Restart Nginx             # ← must match notify string exactly
      service:
        name: nginx
        state: restarted

Key behaviour:

  • Handler runs only if the task reports changed
  • Handler runs once at the end of the play — even if notified multiple times
  • If a task doesn’t change anything, the handler is NOT called

2.2 Notifying Multiple Handlers

tasks:
  - name: Update app config
    template:
      src: app.conf.j2
      dest: /etc/app/app.conf
    notify:
      - Restart App
      - Reload Firewall

handlers:
  - name: Restart App
    service:
      name: myapp
      state: restarted

  - name: Reload Firewall
    service:
      name: firewalld
      state: reloaded

2.2 Handler Triggered by Multiple Tasks

tasks:
  - name: Update nginx.conf
    copy:
      src: nginx.conf
      dest: /etc/nginx/nginx.conf
    notify: Restart Nginx

  - name: Update SSL cert
    copy:
      src: cert.pem
      dest: /etc/nginx/ssl/cert.pem
    notify: Restart Nginx             # same handler notified twice

handlers:
  - name: Restart Nginx               # runs ONCE at end of play
    service:
      name: nginx
      state: restarted

2.4 Forcing Handler Execution with meta

tasks:
  - name: Update config
    copy:
      src: app.conf
      dest: /etc/app/app.conf
    notify: Restart App

  - name: Flush handlers NOW (don't wait for end of play)
    meta: flush_handlers

  - name: Run smoke test (after restart)
    uri:
      url: http://localhost:8080/health
      status_code: 200

meta: flush_handlers forces all pending handlers to run immediately at that point.


2.5 Handlers in Roles

roles/
└── webserver/
    ├── tasks/
    │   └── main.yml
    └── handlers/
        └── main.yml      ← handlers live here in roles
# roles/webserver/handlers/main.yml
- name: Restart Nginx
  service:
    name: nginx
    state: restarted

- name: Reload Nginx
  service:
    name: nginx
    state: reloaded

2.6 Listening to Multiple Notifications

handlers:
  - name: Restart web stack
    service:
      name: nginx
      state: restarted
    listen: "web stack changed"       # alias topic name

tasks:
  - name: Update nginx config
    copy:
      src: nginx.conf
      dest: /etc/nginx/nginx.conf
    notify: "web stack changed"       # notifies by topic

  - name: Update PHP config
    copy:
      src: php.ini
      dest: /etc/php/php.ini
    notify: "web stack changed"       # same topic

2.7 changed_when — Controlling Handler Triggering

- name: Run custom script
  command: /opt/scripts/check_config.sh
  register: result
  changed_when: result.rc == 1       # Only "changed" if exit code is 1
  notify: Apply new config
- name: This task never triggers handlers
  command: /opt/scripts/read_only.sh
  changed_when: false
---
- name: demo
  become: yes
  hosts: localhost
  tasks:
    - ansible.builtin.debug:
        msg: "Installing tree package"

    - name: Install apache httpd (state=present is optional)
      ansible.builtin.apt:
        name: apache2
        update_cache: yes
        state: present
      notify: restart service apcahe

    - name: Install unzip
      ansible.builtin.apt:
        name: unzip
        state: present

    - name: Download gaming html
      ansible.builtin.get_url:
        url: https://templatemo.com/tm-zip-files-2020/templatemo_589_lugx_gaming.zip
        dest: /tmp/templatemo_589_lugx_gaming.zip
        mode: '0755'
      notify: restart service apcahe

    - name: unzip templated in apache2 html
      ansible.builtin.unarchive:
        src: /tmp/templatemo_589_lugx_gaming.zip
        dest: /tmp/
        remote_src: yes

    - name: copy files
      ansible.builtin.copy:
        src: /tmp/templatemo_589_lugx_gaming/
        dest: /var/www/html/
        remote_src: yes
        owner: www-data
        group: www-data
        mode: '0755'
      notify: restart service apcahe

    - ansible.builtin.debug:
        msg: "completed tasks"

  handlers:
    - name: restart service apcahe
      ansible.builtin.systemd_service:
        name: apache2
        enabled: yes
        state: restarted

Task:

  1. update existing playbook with variable
  2. create new playbook add print message disk space all nodes
  3. update playbook use handlers which will required when any change happend.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Please turn AdBlock off
Animated Social Media Icons by Acurax Responsive Web Designing Company

Discover more from Direct DevOps from Quality Thought

Subscribe now to keep reading and get access to the full archive.

Continue reading

Visit Us On FacebookVisit Us On LinkedinVisit Us On Youtube