Score:0

match item.x value with inventory_hostname

cn flag

I need some help with matching inventory_hostname with item.host (from vars_file). What is the best way to do that? I couldn't figure out this as i am a newbie.

My requirement is:

  • I must call all hosts from inventory file.

  • I must match item.host from ansible_inventory, if it's exist then run a shell command on hosts which matches with all item.hosts then exit.

  • filelist.yml is a dynamic file which is changing on daily basis, all hosts exist in inventory but I only want to leverage those which is in file.

I have list.yml file which contains hostname, disk and version info

$ cat list.yml
---
list:
  - host: host1
    diskn: disk0
    os: 7

  - host: host2
    diskn: disk4
    os: 7

  - host: lhost6
    diskn: hdisk7
    os: 7
---

In playbook i tried to match the value but had no luck.

---
- name: My playbook   
  hosts: all   
  vars_file: 
    - list.yml   
  tasks:
   - name: Remove file from client
     shell: "rm -f /tmp/me"
     when:
       - "('item.host' in inventory_hostname) and (ansible_distribution_version == 'item.os')"
     loop: "{{ list }}"
     register: fileopt
   - debug: var=fileopt
----

Please propose a solution which can resolve this issue.

Score:2
br flag

For example, given the inventory

shell> cat hosts
host01
host02
host03

and the list

list:
  - host: host01
    diskn: disk0
    os: 13.0
  - host: host02
    diskn: disk4
    os: 13.0
  - host: host06
    diskn: hdisk7
    os: 13.0

Create the list of the allowed hosts

my_hosts: "{{ list|map(attribute='host')|list }}"

gives

my_hosts:
  - host01
  - host02
  - host06

Next, create a dictionary of the allowed hosts and OS versions

my_os: "{{ list|items2dict(key_name='host', value_name='os') }}"

gives

  my_os:
    host01: 13.0
    host02: 13.0
    host06: 13.0

Now, the tasks below remove the file conditionally and display the registered results

    - name: Remove file from client
      file:
        state: absent
        path: /tmp/me
      when:
        - inventory_hostname in my_hosts
        - ansible_distribution_version ==
          my_os[inventory_hostname]|default('None')|string
      register: fileopt
    - debug:
        var: fileopt

gives

TASK [Remove file from client] *********************************************
skipping: [host03]
ok: [host02]
ok: [host01]

TASK [debug] ***************************************************************
ok: [host01] => 
  fileopt:
    changed: false
    failed: false
    path: /tmp/me
    state: absent
ok: [host02] => 
  fileopt:
    changed: false
    failed: false
    path: /tmp/me
    state: absent
ok: [host03] => 
  fileopt:
    changed: false
    skip_reason: Conditional result was False
    skipped: true

As expected, host03 which is missing from the list was skipped.


Optionally, creating a dynamic group might be more efficient if the list of the allowed hosts is much smaller compared to all hosts. For example, create a group of allowed hosts in the first play and use it in the second play

- name: Create group my_hosts
  hosts: all
  gather_facts: true
  vars:
    list:
      - host: host01
        diskn: disk0
        os: 13.0
      - host: host02
        diskn: disk4
        os: 13.0
      - host: host06
        diskn: hdisk7
        os: 13.0
    my_hosts: "{{ list|map(attribute='host')|list }}"
    my_os: "{{ list|items2dict(key_name='host', value_name='os') }}"
  tasks:
    - set_fact:
        _my_os: "{{ ansible_distribution_version ==
                    my_os[inventory_hostname]|default('None')|string }}"
    - name: Create group my_hosts
      add_host:
        name: "{{ item }}"
        groups: my_hosts
      loop: "{{ hostvars|dict2items|
                selectattr('key', 'in', my_hosts)|
                selectattr('value._my_os')|
                map(attribute='key')|
                list }}"
      run_once: true

- name: Remove file from my_hosts
  hosts: my_hosts
  gather_facts: false
  tasks:
    - name: Remove file from client
      file:
        state: absent
        path: /tmp/me
      register: fileopt
    - debug:
        var: fileopt

gives

PLAY [Create group my_hosts] ***************************************

TASK [Gathering Facts] *********************************************
ok: [host03]
ok: [host01]
ok: [host02]

TASK [set_fact] ****************************************************
ok: [host03]
ok: [host02]
ok: [host01]

TASK [Create group my_hosts] ***************************************
ok: [host01] => (item=host01)
ok: [host01] => (item=host02)

PLAY [Remove file from my_hosts] ***********************************

TASK [Remove file from client] *************************************
ok: [host01]
ok: [host02]

TASK [debug] *******************************************************
ok: [host01] => 
  fileopt:
    changed: false
    failed: false
    path: /tmp/me
    state: absent
ok: [host02] => 
  fileopt:
    changed: false
    failed: false
    path: /tmp/me
    state: absent
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.