0

Ansible variable is not being updated from on unmatched conditions I have the below playbook which actually compares two routers(basically pairs) for running configuration and if there is a match and mismatch it should report out.

---
-
  hosts: '{{d1}}'
  gather_facts: no
  connection: network_cli
  tasks:
    - name: Task1 - Fetching running configuration of device A
      cli_command:
          command: show run
            #output: json
      register: runA

    #- debug:
    #    msg: "{{runA.stdout_lines}}"

-
  hosts: '{{d2}}'
  gather_facts: no
  connection: network_cli
  tasks:
    - name: Task2 - Fetching running configuraiton of device B
      cli_command:
          command: show run
            #output: json
      register: runB

    #- debug:
    #    msg: "{{runB.stdout_lines}}"

- hosts: localhost
  gather_facts: no
  roles:
    - ansible-network.network-engine
  vars:
    runconfA: "{{hostvars[d1]['runA']['stdout']}}"
    runconfB: "{{hostvars[d2]['runB']['stdout']}}"
    atomic_update_mismatch: false
  tasks:
    #- debug:
    #    msg: "{{hostvars[d1]['runA']['stdout']}}"
    - name: Task3 - Parse Atomic Update from Running config of device A
      command_parser:
        file: "parsers/atomic_update.yaml"
 content: "{{ runconfA }}"
    - name: Task4 - Save Atomic Update output
      set_fact:
        atomic_update_deviceA: "{{output}}"
    - name: Task5 - Parse Atomic Update from Running config of device B
      command_parser:
        file: "parsers/atomic_update.yaml"
        content: "{{ runconfB }}"
    - name: Task6 - Save Atomic Update output
      set_fact:
        atomic_update_deviceB: "{{output}}"
    - debug:
        msg:
          - "atomic update from device a: {{atomic_update_deviceA}}"
          - "atomic update from device b: {{atomic_update_deviceB}}"
    - name: Task7 - Compare output from both devices
      set_fact:
        atomic_update_mismatch: true
      when: atomic_update_deviceA != atomic_update_deviceB
    - debug:
        msg: "does running config has atomic update mismatch: {{atomic_update_mismatch}}"
        #msg: "check if {{atomic_update_deviceA}} == {{atomic_update_deviceB}}"
        #- "Atomic Update of device B: {{atomic_update_deviceB}}"

There is another playbook which contains the regex, where I find out using regex, when matched puts the result in variable and returns the variable to the first playbook

---
#- debug: var=runconfA
- name: Match atomic update from running-config
  export: yes
  pattern_match:
    match_all: yes
    #match_greedy: yes
    #regex: ".*\\b(atomic)\\b.*"
    regex: "^.*\\batomic\\b.*$"

  register: output

Execute using below command: ansible-playbook config_mfg_ce.yml -i inventory.txt --extra-vars "d1=A d2=B"

where d1 is A router and d2 is B router.

When I run this, If we have atomic match in router A but not router B it still updates as "there is no mismatch" which is wrong, this is due to the output variable updating router A's value/result back for router B as well and is not refreshed when router B's value is updated in the registered variable "output".

How can I pass the output variable from the regex playbook to the config_mfg_ce.yml playbook with separate updated output variable value for router A and router B?

Playbook Output:

PLAY [A] ************************************************************************************************************************************************************

TASK [Task1 - Fetching running configuration of device A] ***********************************************************************************************************************************
ok: [A]

PLAY [B] ***********************************************************************************************************************************************************

TASK [Task2 - Fetching running configuraiton of device B] ***********************************************************************************************************************************
ok: [B]

PLAY [localhost] ****************************************************************************************************************************************************************************

TASK [Task3 - Parse Atomic Update from Running config of device A] **************************************************************************************************************************
[DEPRECATION WARNING]: set_available_variables is being deprecated. Use "@available_variables.setter" instead.. This feature will be removed in version 2.13. Deprecation warnings can be
disabled by setting deprecation_warnings=False in ansible.cfg.
fatal: [localhost]: FAILED! => {"msg": "invalid directive in parser: set_fact"}

PLAY RECAP **********************************************************************************************************************************************************************************
A : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
B  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

Any help is much appreciated.

pinkbask
  • 1
  • 3

1 Answers1

0

This won't work with a registered variable, because:

Registered variables are similar to facts, with a few key differences. Like facts, registered variables are host-level variables. However, registered variables are only stored in memory. (Ansible facts are backed by whatever cache plugin you have configured.) Registered variables are only valid on the host for the rest of the current playbook run.

Ansible docs

This limitation of variables in Ansible can be mitigated by using set_fact like this by adding a set_fact for the registered output:

- set_fact:
    output: "{{ output }}"
    cacheable: yes
Henrik Pingel
  • 8,676
  • 2
  • 24
  • 38
  • I cant use set_fact in the regex yaml as it goes inside a role, I think we cannot use set_fact with role. – pinkbask Nov 12 '19 at 05:11
  • I get "fatal: [localhost]: FAILED! => {"msg": "invalid directive in parser: set_fact"}" error when I add set_fact task. Posted the output also – pinkbask Nov 12 '19 at 05:58