ansibletagsansible-facts

Ansible not gathering facts on tags


I'm habituated to use --tags when I'm using ansible-playbook to filter what tasks will be executed. I recently switched from Ansible 2.7 to 2.9 (huge gap, eh ?).

I was surprised ansible did not gathering facts exclusively when I'm using --tags. And I saw multiple similar cases closed in GitHub like this one or this one. It seems affects ansible since 2.8 version, but shown as resolved. Is anybody can confirm this behavior ? It seems happening from 2.8.

ANSIBLE VERSION :

ansible --version

ansible 2.9.9.post0
  config file = None
  configured module search path = [u'/opt/ansible/ansible/library']
  ansible python module location = /opt/ansible/ansible/lib/ansible
  executable location = /opt/ansible/ansible/bin/ansible
  python version = 2.7.6 (default, Nov 13 2018, 12:45:42) [GCC 4.8.4]

ANSIBLE CONFIG :

ansible-config dump --only-changed

DEFAULT_MODULE_PATH(env: ANSIBLE_LIBRARY) = [u'/opt/ansible/ansible/library']

STEPS TO REPRODUCE :

playbook test.yml :

- name: First test
  hosts: localhost
  connection: local
  gather_facts: yes
  roles:
    - { role: test, tags: test }
  tags: first

- name: Second test
  hosts: localhost
  connection: local
  gather_facts: yes
  roles:
    - { role: test, tags: test }
  tags: second

role : roles/test/tasks/main.yml

- debug:
    msg: System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}

Results :

ansible-playbook test.yml --check

= No errors.


ansible-playbook test.yml --check --tags "test"

= failed: 1

"The task includes an option with an undefined variable. The error was: 'ansible_product_uuid' is undefined [...]"

And I can see on the output that facts are not gathered.


Solution

  • Well, it seems to be a purposed behaviour when you have tags on a play level:

    This is intended behavior. Tagging a play with tags applies those tags to the gather_facts step and removes the always tag which is applied by default. If the goal is to tag the play, you can add a setup task with tags in order to gather facts.

    samdoran commented on 11 Jun 2019


    Please note that this is, then, not linked to the usage of roles, as it can be reproduced by simply doing:

    - name: First test
      hosts: all
      tags:
        - first
    
      tasks:
        - debug:
            msg: System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}
          tags: test
    

    Which yields the failing recap:

    $ ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook play.yml --tags "test"
    
    PLAY [First test] *************************************************************************************************
    
    TASK [debug] ******************************************************************************************************
    fatal: [localhost]: FAILED! => {}
    
    MSG:
    
    The task includes an option with an undefined variable. The error was: 'ansible_product_uuid' is undefined
    
    The error appears to be in '/ansible/play.yml': line 7, column 7, but may
    be elsewhere in the file depending on the exact syntax problem.
    
    The offending line appears to be:
    
      tasks:
        - debug:
          ^ here
    
    
    PLAY RECAP ********************************************************************************************************
    localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0  
    

    So you'll either have to remove the tag of you play level, or use the setup module, as prompted.

    This can be done inside your role, so your role stops relying on variables that could possibly not be set.

    Given the role roles/test/tasks/main.yml

    - setup:
    - debug:
        msg: System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}
    

    And the playbook:

    - name: First test
      hosts: all
      tags:
        - first
    
      roles:
        - role: test
          tags: 
            - test
    
    - name: Second test
      hosts: all
      tags: 
        - second
    
      roles:
        - role: test
          tags: 
            - test
    

    Here would be the run and recap for it:

    $ ansible-playbook play.yml --tags "test"
    
    PLAY [First test] *************************************************************************************************
    
    TASK [test : setup] ***********************************************************************************************
    ok: [localhost]
    
    TASK [test : debug] ***********************************************************************************************
    ok: [localhost] => {
        "msg": "System localhost has uuid 3fc44bc9-0000-0000-b25d-bf9e26ce0762"
    }
    
    PLAY [Second test] ************************************************************************************************
    
    TASK [test : setup] ***********************************************************************************************
    ok: [localhost]
    
    TASK [test : debug] ***********************************************************************************************
    ok: [localhost] => {
        "msg": "System localhost has uuid 3fc44bc9-0000-0000-b25d-bf9e26ce0762"
    }
    
    PLAY RECAP ********************************************************************************************************
    localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    

    All this run on:

    ansible 2.9.9
      config file = None
      configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
      ansible python module location = /usr/lib/python3.8/site-packages/ansible
      executable location = /usr/bin/ansible
      python version = 3.8.3 (default, May 15 2020, 01:53:50) [GCC 9.3.0]