skip to Main Content

I am reading some Ansible code that looks like this:

---
- meta: end_play
  when: centos is defined

- name: Set centos variable
  set_fact:
    centos: "{{ hostvars[item]['ansible_distribution_version'][0:1] }}"
  with_inventory_hostnames: all
  delegate_to: "{{ item }}"
  delegate_facts: true
  run_once: true

I have nobody to ask as the developer is long gone. Is this a common Ansible pattern?
If so, could someone explain why might this needs to be done? Are they trying to stop recursion or does it just look cool?

2

Answers


  1. Be careful not to confuse playbook and play.
    You can have multiple plays in a playbook.

    Here is an example playbook:

    - hosts: localhost
      gather_facts: false
    
      tasks:
        - meta: end_play
    
        - debug:
            msg: I am not played
    
    - hosts: localhost
      gather_facts: false
    
      tasks:
        - debug:
            msg: I am still played
    

    That would still print the debug task of the second play, although not printing the one of the first, due to the meta task:

    Actual output:

    PLAY [localhost] *********************************************************
    
    TASK [meta] **************************************************************
    
    PLAY [localhost] *********************************************************
    
    TASK [debug] *************************************************************
    ok: [localhost] => 
      msg: I am still played
    

    So, yes, most probably, the snippet of YAML you are providing is there to ensure the variable centos is defined, and if it is already, skip the whole play to act on the variable in a further play.

    Given the playbook:

    - hosts: localhost
      gather_facts: false
    
      tasks:
        - meta: end_play
          when: centos is defined
    
        - set_fact:
            centos: defined in play 1
    
    - hosts: localhost
      gather_facts: false
    
      tasks:
        - debug:
            var: centos
    
    • The second play’s debug would yield
      ok: [localhost] => 
        centos: defined in play 1
      
    • But, when you run the playbook with --extra-vars "centos='from extra-vars'", it would, then, yield
      ok: [localhost] => 
        centos: from extra-vars
      
    Login or Signup to reply.
  2. Let me comment on the second task

    - name: Set centos variable
      set_fact:
        centos: "{{ hostvars[item]['ansible_distribution_version'][0:1] }}"
      with_inventory_hostnames: all
      delegate_to: "{{ item }}"
      delegate_facts: true
      run_once: true
    

    This task runs once and iterates set_fact for all hosts. The loop

    with_inventory_hostnames: all
    

    is equal to

    loop: "{{ ansible_play_hosts_all }}"
    

    Each iteration is delegated to a host and the facts are delegated too. All these settings do exactly the same as the simple below task

    - name: Set centos variable
      set_fact:
        centos: "{{ ansible_distribution_version[0:1] }}"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search