How to check the OS version of host which in dynamically added to inventory

Viewed 241

I'm trying to get server name as user input and if the server OS is RHEL7 it will proceed for further tasks. I'm trying with hostvars but it is not helping, kindly help me to find the OS version with when condition:

---
- name: Add hosts
  hosts: localhost
  vars:
    - username: test
      password: test
  vars_prompt:
    - name: server1
      prompt: Server_1 IP or hostname
      private: no
    - name: server2
      prompt: Server_2 IP or hostname
      private: no

  tasks:
    - add_host:
        name: "{{ server1 }}"
        groups:
          - cluster_nodes
          - primary
          - management
        ansible_user: "{{ username }}"
        ansible_password: "{{ password}}"

    - add_host:
        name: "{{ server2 }}"
        groups:
          - cluster_nodes
          - secondary
        ansible_user: "{{ username }}"
        ansible_password: "{{ password}}"

    - debug:
        msg: "{{ hostvars['server1'].ansible_distribution_major_version }}"

When I execute the playbook, I'm getting below error:

fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: \"hostvars['server1']\" is undefined\n\nThe error appears to be in '/var/lib/awx/projects/pacemaker_RHEL_7_ST/main_2.yml': line 33, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n    - debug:\n      ^ here\n"}
1 Answers

You need to gather_facts on the newly added host before you consume the variable. As an example, this will do it with automatic facts gathering.

---
- name: Add hosts
  hosts: localhost
  vars:
    - username: test
      password: test
  vars_prompt:
    - name: server1
      prompt: Server_1 IP or hostname
      private: no
    - name: server2
      prompt: Server_2 IP or hostname
      private: no

  tasks:
    - add_host:
        name: "{{ server1 }}"
        groups:
          - cluster_nodes
          - primary
          - management
        ansible_user: "{{ username }}"
        ansible_password: "{{ password}}"

    - add_host:
        name: "{{ server2 }}"
        groups:
          - cluster_nodes
          - secondary
        ansible_user: "{{ username }}"
        ansible_password: "{{ password}}"

- name: Gather facts for newly added targets
  hosts: cluster_nodes
  # gather_facts: true <= this is the default

- name: Do <whatever> targeting localhost again
  hosts: localhost
  gather_facts: false  # already gathered in play1

  tasks:
    # Warning!! bad practice. Looping on a group usually
    # shows you should have a play targeting that specific group
    - debug:
        msg: "OS version for {{ item }} is 7"
      when: hostvars[item].ansible_distribution_major_version | int == 7
      loop: "{{ groups['cluster_nodes'] }}"

If you don't want to rely on automatic gathering, you can manually play the setup module, e.g. for the second play:

- name: Gather facts for newly added targets
  hosts: cluster_nodes
  gather_facts: false
  
  tasks:
    - name: get facts from targets
      setup:
Related