Search code examples
ansibleansible-facts

How to compare two registered values in Ansible?


I am a noobie in Ansible and struggling with comparing two registered values in my playbook.

I am fetching a list of codes from 2 different hosts and trying to compare them, but fail.

Expectation is that if all values are the same, then will display the message that "The variables are the same", if not then "The variables are different".

Output of values look like this, but I am getting the message that values are not equal.

ok: [localhost] => {
    "res_green": [
        "CodeListString=01,03,04,05,07,12,13,V2,V7,V8,V9,X1,X2,X3,X4"
    ]
}`

`ok: [remotehost] => {
    "res_blue": [
        "CodeListString=01,03,04,05,07,12,13,V2,V7,V8,V9,X1,X2,X3,X4"
    ]
}
---
- name: compare remote file to a local reference
  hosts: all
  gather_facts: no
  become: true
  vars:
    local_reference: "{{ local_folder }}server_output_green.txt" 
    remote_files_2_check: "{{ remote_folder }}server-config.properties" 
    res_green: []
    res_blue: []
 
  tasks:
    - name: Check the bad debts results from green side
      shell: grep CodeListString {{ local_reference }}  
      register: result_green
      when: inventory_hostname == groups['localhost'][0]

    - set_fact:
        res_green: "{{ result_green.stdout_lines|list }}"
      when: inventory_hostname == groups['localhost'][0]

    - debug:
        var: res_green
      when: inventory_hostname == groups['localhost'][0]
    
    - name: Check the paymentgateway bad debt codes
      shell: grep CodeListString {{ remote_files_2_check }}  
      register: result_blue
      when: inventory_hostname == groups['remotehost'][0]

    - set_fact:
        res_blue: "{{ result_blue.stdout_lines|list }}"
      when: inventory_hostname == groups['remotehost'][0]

    - debug:
        var: res_blue
      when: inventory_hostname == groups['remotehost'][0]

    - name: Vars are equal
      debug: 
        msg: 'Vars are equal'
      when: res_green == res_blue 
   
    - name: Vars are not equal 
      fail:
        msg: 'The variables are different'
      when: res_green != res_blue

Outcome sample:

PLAY [compare remote file to a local reference] ***********************************************************************************************************************************
    
    TASK [Check the bad debts results from green side] ********************************************************************************************************************************
    skipping: [remotehost]
    changed: [localhost]
    
    TASK [set_fact] *******************************************************************************************************************************************************************
    ok: [localhost]
    skipping: [remotehost]
    
    TASK [debug] **********************************************************************************************************************************************************************
    ok: [localhost] => {
        "res_green": "CodeListString=01,03,04,05,07,12,13,V2,V7,V8,V9,X1,X2,X3,X4"
    }
    skipping: [remotehost]
    
    TASK [Check the paymentgateway bad debt codes] ************************************************************************************************************************************
    skipping: [localhost]
    changed: [remotehost]
    
    TASK [set_fact] *******************************************************************************************************************************************************************
    skipping: [localhost]
    ok: [remotehost]
    
    TASK [debug] **********************************************************************************************************************************************************************
    skipping: [localhost]
    ok: [remotehost] => {
        "res_blue": "CodeListString=01,03,04,05,07,12,13,V2,V7,V8,V9,X1,X2,X3,X4"
    }
    
    TASK [Vars are equal] *************************************************************************************************************************************************************
    skipping: [localhost]
    skipping: [remotehost]
    
    TASK [Vars are not equal] *********************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "The variables are not equal"
    }
    ok: [remotehost] => {
        "msg": "The variables are not equal"
    }
    
    PLAY RECAP ************************************************************************************************************************************************************************
    remotehost : ok=4    changed=1    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0   
    localhost : ok=4    changed=1    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0   ```

I don't know how to break down the list element by element and compare it with what is found in the other list.

Expectation is that the playbook doesn't fail when values are equal OR fail when the values are not equal.


Solution

  • A minimal example playbook

    ---
    - hosts: localhost
      become: false
      gather_facts: false
    
      tasks:
    
      - name: Gather green_csv
        shell:
          cmd: grep CodeListString green.csv | cut -d '=' -f 2
        register: green_csv
    
      - name: Generate green_list
        set_fact:
          green_list: "{{ green_csv.stdout | split(',') }}"
    
      - name: Gather red_csv
        shell:
          cmd: grep CodeListString red.csv | cut -d '=' -f 2
        register: red_csv
    
      - name: Generate red_list
        set_fact:
          red_list: "{{ red_csv.stdout | split(',') }}"
    
      - name: Show the difference
        debug:
          msg:
           - "There are {{ difference | length }} different elements."
           - "The elements are: {{ difference }}."
        vars:
          difference: "{{ green_list | difference(red_list) }}"
    

    will result into an output of

    TASK [Gather green_csv] *********
    changed: [localhost]
    
    TASK [Generate green_list] ******
    ok: [localhost]
    
    TASK [Gather red_csv] ***********
    changed: [localhost]
    
    TASK [Generate red_list] ********
    ok: [localhost]
    
    TASK [Show the difference] ******
    ok: [localhost] =>
      msg:
      - There are 0 different elements.
      - 'The elements are: [].'
    

    It is possible to make it a lot easier by


    Another approach could be fact_diff module – Find the difference between currently set facts

      - name: Show the difference in JSON format
        ansible.utils.fact_diff:
          before: "{{ green_list }}"
          after: "{{ red_list }}"
    

    resulting into an output of

    TASK [Show the difference in JSON format] **************************************************************************************************************************
    --- before
    +++ after
    @@ -1,8 +1,8 @@
     01
    +02
     03
    -04
    -05
    -07
    +06
    +08
     12
     13
     V2
    

    if there is any difference (annot.: ... and which I've created to show the behavior).