Ansible Playbook: From Introduction to Mastery (Part 7)

Ansible Playbook

Ansible Playbooks use YAML format and have strict indentation requirements. A playbook consists of multiple plays.

Playbook Example

---
- name: init    # Define the name of the Playbook
  hosts: all    # Define the range of managed hosts
  tasks:        # Define the tasks to be executed, each - corresponds to one task (a - indicates a list)
  - name: set hostname        # Name of the first task
    ansible.builtin.hostname:    # Module used in the first task
      name: "{{ inventory_hostname }}.{{ host_search_name }}"    # Module options
  - name: dnf install package    # Name of the second task
    ansible.builtin.dnf:        # Module used in the second task
      name:                        # Module options
      - bash-completion
      - vim
      - gcc
      - make
      - git
      - wget
      - tar
      - bzip2
      - unzip
      - python3
      - sysstat
      state: present
  - name: set hosts
    ansible.builtin.template:
      src: ./templates/hosts.j2
      dest: /etc/hosts
      owner: root
      group: root
      mode: '0644'

<span>---</span>: indicates the document separator in a YAML file. Multiple YAML documents can be placed in one file, separated by <span>---</span>.

<span>- name</span>: used to define the names of the Playbook and Play, similar to comments.

<span>hosts</span>: defines the range of hosts affected by the Playbook.

<span>tasks</span>: defines multiple automation tasks in the Playbook, containing multiple tasks below.

YAML has strict indentation requirements. For example, <span>- name</span> and <span>hosts</span> are at the same level (in a list), so the indentation is aligned. The <span>tasks</span> section’s <span>- name</span> and <span>ansible.builtin.hostname</span> are its sub-items (part of the <span>tasks</span> list), so they are indented two spaces more (indentation counts from the first letter, ignoring <span>-</span>).

  - name: set hosts
    ansible.builtin.template:
      src: ./templates/hosts.j2
      dest: /etc/hosts
      owner: root
      group: root
      mode: '0644'

This represents a play, with the play named set hosts, using the module <span>ansible.builtin.template</span>, with parameters including <span>src</span>, <span>dest</span>, <span>owner</span>, <span>group</span>, and <span>mode</span>.

Common Options for Ansible Playbook Commands

  1. 1. You can execute a Playbook using the <span>ansible-playbook</span> command, and use <span>-v</span> to view more detailed information.
  • <span>-v</span>: provides detailed information about task and host status, but does not include variable values and detailed debug information.
  • <span>-vv</span>: provides more detailed task execution information, including variable values.
  • <span>-vvv</span>: displays more debug information, including variable expansion and task details.
  • <span>-vvvv</span>: displays all debug information, including detailed HTTP request and response content.
  • 2. You can check the format of the Playbook using the <span>--syntax-check</span> option.
  • 3. You can execute the Playbook using <span>--check</span>, but it will not make any actual changes.
  • Error Handling Mechanism in Ansible Playbook Queues

    The mechanism of Ansible Playbook is that if a Play fails on a host, that host will be removed from the execution queue, and all subsequent Plays related to that host will not be executed.

    Ansible Playbook: From Introduction to Mastery (Part 7)
    image-20250407233502883

    Sometimes we may want the tasks to continue executing after an error occurs, in which case we can use <span>ignore_errors: yes</span> to achieve this.

      - name: dnf install package
        ansible.builtin.dnf:
          name:    sysstat
          state: present
        ignore_errors: yes

    Ansible Handlers

    Ansible Handlers represent a set of special tasks that are only executed under specific conditions. For example, configuring the sssd service can be achieved using Ansible Handlers to ensure that the sssd service is restarted only if its configuration file has changed.

    Ansible Handlers have two common options: notify, handlers, and listen.

    handlers: defines special tasks that are executed only under certain conditions, which are related to <span>notify</span>.

    notify: when appended under a play, indicates that after the play executes successfully and makes changes, it triggers a special task in <span>handlers</span>.

    Ansible Handlers Example

    ---
    - name: set sssd
      hosts: all
      gather_facts: false
      vars:
        sssd_packages:
        - sssd
        - sssd-tools
        - oddjob
        - oddjob-mkhomedir
        - libsss_sudo
      tasks:
      - name: install packages
        ansible.builtin.yum:
          name: "{{ sssd_packages }}"
          state: present
      - name: set sssd.conf
        ansible.builtin.template:
          src: templates/sssd.conf.j2
          dest: /etc/sssd/sssd.conf
          mode: '0600'
          owner: root
          group: root
        notify: set_pam_and_service
      - name: set oddjob service
        ansible.builtin.systemd:
          name: oddjobd
          state: started
          enabled: true
      handlers:
      - name: set authselect
        ansible.builtin.command: "authselect select sssd with-sudo with-mkhomedir --force"
        listen: set_pam_and_service
      - name: set sssd service
        ansible.builtin.systemd:
          name: sssd
          state: restarted
        listen: set_pam_and_service

    In this Playbook, under the play named set sssd.conf, a <span>notify</span> is defined, named set_pam_and_service. Then, two plays are defined in <span>handlers</span>, namely set authselect and set sssd service, both having a <span>listen</span> option with the content set_pam_and_service. The result is that when set sssd.conf executes successfully and makes changes, it triggers the tasks set authselect and set sssd service. If set sssd.conf does not make changes, the tasks set authselect and set sssd service will be skipped.

    In the above example, one play triggers two <span>handlers</span>. If the play triggered in <span>handlers</span> is only one, then <span>listen</span> is not needed; you can directly set the <span>name</span> of the play in <span>handlers</span> to be the same as the content of <span>notify</span>. (If multiple plays in <span>handlers</span> have the name set_pam_and_service, only the first play will be executed.)

    ---
    - name: set sssd
      hosts: all
      gather_facts: false
      tasks:
      - name: set sssd.conf
        ansible.builtin.template:
          src: templates/sssd.conf.j2
          dest: /etc/sssd/sssd.conf
          mode: '0600'
          owner: root
          group: root
        notify: set_pam_and_service
      handlers:
      - name: set_pam_and_service
        ansible.builtin.systemd:
          name: sssd
          state: restarted

    Force Executing Handlers

    The mechanism of Ansible is that if a Play fails on a host, that host will be removed from the execution queue, and all subsequent Plays related to that host will not be executed. Therefore, to ensure that <span>handlers</span> can execute normally, you can add the <span>force_handlers: true</span> option, so that regardless of whether there are error tasks, <span>handlers</span> will execute normally.

    ---
    - name: set sssd
      hosts: all
      gather_facts: false
      force_handlers: true
      tasks:
      ...

    Leave a Comment