# Need to understand how I can write a ansible role so that it compares input / output value.

**URL:** <https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138>\
**Category:** Ansible Project\
**Created:** [December 21, 2021, 6:22am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138 "2021-12-21T06:22:34Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marian\_Saldhana](https://avatars.discourse-cdn.com/v4/letter/m/47e85d/32.png) [@Marian\_Saldhana](https://forum.ansible.com/u/Marian_Saldhana)\
**Post date:** [December 21, 2021, 6:22am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/1 "2021-12-21T06:22:34Z")

</div>

Hi All,

As I am new to ansible i need to write a role which compares input /output value.

Let me elaborate.

I need to write a role where I already have expected value, for eg hostname of ansible remote node - abc.

Now I need to write a role which first will fetch the value from the remote node and then compare the fetched value with the expected value ( abc ) I have with me.

Thanks.

---

<div class="post-metadata">

**Author:** ![Dick\_Visser](https://avatars.discourse-cdn.com/v4/letter/d/d9b06d/32.png) [@Dick\_Visser](https://forum.ansible.com/u/Dick_Visser)\
**Post date:** [December 21, 2021, 10:36am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/2 "2021-12-21T10:36:30Z")

</div>

You need to elaborate some more, I can’t make anything of your story.  
Give some real world examples of the tasks that you’re trying to automate.

---

<div class="post-metadata">

**Author:** ![Marian\_Saldhana](https://avatars.discourse-cdn.com/v4/letter/m/47e85d/32.png) [@Marian\_Saldhana](https://forum.ansible.com/u/Marian_Saldhana)\
**Post date:** [December 21, 2021, 11:15am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/3 "2021-12-21T11:15:15Z")

</div>

Thanks for your reply.

I want to automate tasks such as verifying the OS version of remote nodes.

The customer has given me the expected value i.e. Centos version 8.2

Through automation I wish to get the OS version of the remotes nodes and then compare that value with the value that I have received from the customer through ansible playbooks.

---

<div class="post-metadata">

**Author:** ![Roberto\_J\_R\_Paz](https://avatars.discourse-cdn.com/v4/letter/r/d2c977/32.png) [@Roberto\_J\_R\_Paz](https://forum.ansible.com/u/Roberto_J_R_Paz)\
**Post date:** [December 22, 2021, 12:06am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/4 "2021-12-22T00:06:21Z")

</div>

That kind of info can be obtained with “gather facts” step, which is the first step when running a playbook.

You just have to comparte returned info in ansible variables like “ansible\_distribution” and “ansible\_distribution\_version” with the expected value. You can store expected value in a local dictionary that uses hostname as the key value.

---

<div class="post-metadata">

**Author:** ![Marian\_Saldhana](https://avatars.discourse-cdn.com/v4/letter/m/47e85d/32.png) [@Marian\_Saldhana](https://forum.ansible.com/u/Marian_Saldhana)\
**Post date:** [December 28, 2021, 4:58am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/5 "2021-12-28T04:58:39Z")

</div>

Hi All,

This is my code:

---

<div class="post-metadata">

**Author:** ![Mauricio\_Tavares](https://avatars.discourse-cdn.com/v4/letter/m/b5e925/32.png) [@Mauricio\_Tavares](https://forum.ansible.com/u/Mauricio_Tavares)\
**Post date:** [December 28, 2021, 12:35pm UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/6 "2021-12-28T12:35:00Z")

</div>

var

> Hi All,
> 
> This is my code:
> 
> ---  
> # tasks file for uname
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- name: Kernel version number  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;register: uname\_a  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command: "uname -a"
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var: uname\_a.stdout\_lines
> 
> +++
> 
> TASK [uname\_tab1 : debug] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
> ok: [192.168.43.237] =\> {  
> &nbsp;&nbsp;&nbsp;&nbsp;"uname\_a.stdout\_lines": [  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Linux ansible-client 4.18.0-348.el8.x86\_64 #1 SMP Tue Oct 19 15:14:17 UTC 2021 x86\_64 x86\_64 x86\_64 GNU/Linux"  
> &nbsp;&nbsp;&nbsp;&nbsp;]  
> }  
> ok: [192.168.43.6] =\> {  
> &nbsp;&nbsp;&nbsp;&nbsp;"uname\_a.stdout\_lines": [  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Linux ansible-client1 4.18.0-348.el8.x86\_64 #1 SMP Tue Oct 19 15:14:17 UTC 2021 x86\_64 x86\_64 x86\_64 GNU/Linux"  
> &nbsp;&nbsp;&nbsp;&nbsp;]  
> }
> 
> ++++
> 
> Now I need to compare these values with the values given by the customer ( Linux ansible-client1 4.18.0-348.el8.x86\_64 ) hence request your assistance out here to write a program.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Have you considered using "when"?

- name: do something useful  
&nbsp;&nbsp;[....]  
&nbsp;&nbsp;&nbsp;when: uname\_a == some\_kernel\_version\_customer\_cares about

May probably want to do some cleaning on the uname\_a variable first so  
it only shows a string that matches what your customer is providing.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [December 29, 2021, 5:26pm UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/7 "2021-12-29T17:26:06Z")

</div>

What, exactly, do the “values given by the customer” look like? It almost certainly isn’t going to match the output of `uname -a`. (I’m guessing. But please, don’t make us guess; give us the details of the actual problem.)

---

<div class="post-metadata">

**Author:** ![Marian\_Saldhana](https://avatars.discourse-cdn.com/v4/letter/m/47e85d/32.png) [@Marian\_Saldhana](https://forum.ansible.com/u/Marian_Saldhana)\
**Post date:** [December 30, 2021, 2:46am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/8 "2021-12-30T02:46:32Z")

</div>

Thanks for your reply.

**Expected value is: - Linux hostname 4.18.0-193.el8.x86\_64 ( The customer has RHEL 8.2 running in its env )**  
I have 100 such lines given to me by the customer ( OS inventory ) where 80% of the values that I receive by running the ansible standard module matches with the expected value given by the customer. I need to understand how these values can be matched with the values given by the customer.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [December 30, 2021, 3:28pm UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/9 "2021-12-30T15:28:55Z")

</div>

Assuming “hostname” means a fully qualified domain name, then the following may help you.

```auto
---
- hosts: all
  gather_facts: True
  become: false
  tasks:
  - name: show file contents
    debug:
      msg: "{{ lookup('file', 'customer-expects.txt') }}"

  - name: Correct kernel?
    set_fact:
      # These dashes matter.
      expectation: |-
        {%- if lookup('file', 'customer-expects.txt')
              is regex([ansible_system,ansible_fqdn,ansible_kernel]|join(' ')|regex_escape()) -%}
        matched
        {%- else -%}
        missed
        {%- endif -%}

  - name: Report via Debug
    run_once: True
    debug:
      msg: |
        {% for exp in ['missed', 'matched', 'error'] %}
        Kernel_expectations_{{ exp }}:
        {% for hosti in ansible_play_hosts_all|sort %}
        {% if hostvars[hosti]['expectation']|d('error') == exp %}
        - {{ hosti }}
        {% endif %}
        {% endfor %}

        {% endfor %}

```

This produces the following output given the command

`ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook customer-expects.yml --limit flakey.sample.net,shaggy.sample.net,scooby.sample.net,clyde.sample.net -v`

```auto
Using /home/utoddl/.ansible.cfg as config file

PLAY [all] ******************************

TASK [Gathering Facts] ****************
fatal: [flakey.sample.net]: UNREACHABLE! => changed=false 
  msg: 'Failed to connect to the host via ssh: [utoddl@flakey.sample.net](mailto:utoddl@flakey.sample.net): Permission denied (publickey,gssapi-keyex,gssapi-with-mic).'
  unreachable: true
ok: [scooby.sample.net]
ok: [shaggy.sample.net]
ok: [clyde.sample.net]

TASK [show file contents] **************
ok: [clyde.sample.net] => 
  msg: |-
    Linux flakey.sample.net 5.15.11-200.fc35.x86_64
    Linux clyde.sample.net 5.15.11-200.fc35.x86_64
    Linux shaggy.sample.net 5.15.11-200.fc35.x86_64
    Linux scooby.sample.net 5.15.11-200.fc35.x86_64
    Linux loaner.sample.net 5.15.11-200.fc35.x86_64

TASK [Correct kernel?] *****************
ok: [clyde.sample.net] => changed=false 
  ansible_facts:
    expectation: matched
ok: [shaggy.sample.net] => changed=false 
  ansible_facts:
    expectation: missed
ok: [scooby.sample.net] => changed=false 
  ansible_facts:
    expectation: matched

TASK [Report via Debug] **************
ok: [clyde.sample.net] => 
  msg: |-
    Kernel_expectations_missed:
    - shaggy.sample.net
  
    Kernel_expectations_matched:
    - clyde.sample.net
    - scooby.sample.net
  
    Kernel_expectations_error:
    - flakey.sample.net

PLAY RECAP ***************************
clyde.sample.net : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0   
shaggy.sample.net : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0   
flakey.sample.net : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0   
scooby.sample.net : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0   

```

---

<div class="post-metadata">

**Author:** ![Marian\_Saldhana](https://avatars.discourse-cdn.com/v4/letter/m/47e85d/32.png) [@Marian\_Saldhana](https://forum.ansible.com/u/Marian_Saldhana)\
**Post date:** [December 31, 2021, 5:26am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/10 "2021-12-31T05:26:41Z")

</div>

Thanks Todd, appreciate your guidance.

---

<div class="post-metadata">

**Author:** ![Marian\_Saldhana](https://avatars.discourse-cdn.com/v4/letter/m/47e85d/32.png) [@Marian\_Saldhana](https://forum.ansible.com/u/Marian_Saldhana)\
**Post date:** [January 4, 2022, 8:50am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/11 "2022-01-04T08:50:38Z")

</div>

Hi Todd,

Thanks for assisting me on it, I did configure the playbook on my test machines and here is the output:

root@ansible-master /]# ansible-playbook hostname1.yml

PLAY [all] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

TASK [Gathering Facts] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [ansible-client]  
ok: [ansible-client1]

TASK [show file contents] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [ansible-client] =\> {  
“msg”: “Linux ansible-client 4.18.0-348.el8.x86\_64\nLinux ansible-client1 4.18.0-348.el8.x86\_64”  
}  
ok: [ansible-client1] =\> {  
“msg”: “Linux ansible-client 4.18.0-348.el8.x86\_64\nLinux ansible-client1 4.18.0-348.el8.x86\_64”  
}

TASK [Correct kernel?] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [ansible-client]  
ok: [ansible-client1]

TASK [Report via Debug] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [ansible-client] =\> {  
“msg”: “Kernel\_expectations\_missed:\n\nKernel\_expectations\_matched:\n- ansible-client\n- ansible-client1\n\nKernel\_expectations\_error:\n\n”  
}

PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ansible-client : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0  
ansible-client1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[root@ansible-master /]#

---

<div class="post-metadata">

**Author:** ![Marian\_Saldhana](https://avatars.discourse-cdn.com/v4/letter/m/47e85d/32.png) [@Marian\_Saldhana](https://forum.ansible.com/u/Marian_Saldhana)\
**Post date:** [January 4, 2022, 9:59am UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/12 "2022-01-04T09:59:04Z")

</div>

Hi Todd,

Can you please let me know how you have entered expected values in customer-expects.txt ( in the sample playbook that you had provided earlier )

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [January 4, 2022, 12:42pm UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/13 "2022-01-04T12:42:23Z")

</div>

Right. I did say “Assuming “hostname”means a fully qualified domain name”, which is not the case. Change `ansible_fqdn` to `ansible_hostname` in the “Correct kernel?” task and see if that helps.

Also, if you prefix your `ansible-playbook` command with `ANSIBLE_STDOUT_CALLBACK=yaml` (or export the environment variable) you may have more joy looking at your output.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [January 4, 2022, 12:45pm UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/14 "2022-01-04T12:45:03Z")

</div>

I just used a text editor (“ne”, not that it matters) and followed the example you provided.

How is your customer providing those values to you?

---

<div class="post-metadata">

**Author:** ![Marian\_Saldhana](https://avatars.discourse-cdn.com/v4/letter/m/47e85d/32.png) [@Marian\_Saldhana](https://forum.ansible.com/u/Marian_Saldhana)\
**Post date:** [January 4, 2022, 3:40pm UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/15 "2022-01-04T15:40:44Z")

</div>

Hi Todd,

Our customer has provided the values in a excel document

---

<div class="post-metadata">

**Author:** ![Marian\_Saldhana](https://avatars.discourse-cdn.com/v4/letter/m/47e85d/32.png) [@Marian\_Saldhana](https://forum.ansible.com/u/Marian_Saldhana)\
**Post date:** [January 4, 2022, 4:24pm UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/16 "2022-01-04T16:24:43Z")

</div>

For eg:

Expected value  
Red Hat Enterprise Linux release 8.2 (Ootpa)  
Linux hostname 4.18.0-193.el8.x86\_64  
Linux hostname 4.18.0-193.el8.x86\_64  
Installed Packeages  
FJSVsnap.noarch 7.00-1 @System

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [January 4, 2022, 5:10pm UTC](https://forum.ansible.com/t/need-to-understand-how-i-can-write-a-ansible-role-so-that-it-compares-input-output-value/36138/17 "2022-01-04T17:10:43Z")

</div>

The goalpost keeps moving! Is this (the six lines of data below) from one column of an Excel sheet? From what you described before, I expected

```auto
Linux hostname00 4.18.0-193.el8.x86_64
Linux hostname01 4.13.2-120.el8.x86_64
Linux hostname03 4.18.0-193.el8.x86_64
Linux hostname04 4.13.2-120.el8.x86_64
[...etc...]

```

But now I’m seeing two _identical_ lines following that pattern, mixed with other lines we’ve not heard about before, and nothing to map the “^Linux” lines to actual hosts’ names.

Or is the “Expected value” one column heading, while “Installed Packeages” [sic] is a second column heading and it just got stuck under the first b/c it was exported from Excel as a .txt file? But which host(s) are the Installed Packages matched up with, and how? Or maybe there’s a separate sheet per host in the Excel workbook? It looks like it didn’t survive exporting from Excel particularly well.

And, now that I’m seeing the “Installed Packeages” bit, I’m expecting that to turn into one or more Ansible “package” module steps, in which case there’s some other non-trivial work ahead to transform this requirements-as-spreadsheet into actionable Ansible yaml inputs, in which case the prior exercise is probably moot.

I really want this to work for you. Perhaps it would be helpful to provide the input data spreadsheet as provided by the customer before it’s undergone exporting or other transformations. Although I understand if you need to obfuscate hostnames. If you do, don’t change them all to the same string. Are the two instances of “hostname” below really literally “hostname” (and therefore identical), or do they stand in for originally distinct hosts’ names? And how do those hosts map to sets of installed packages?
