Home > other >  How to deal with multiple when condition for registered variable in ansible
How to deal with multiple when condition for registered variable in ansible

Time:10-07

I have a playbook 3 raw task (or more) with sample commands like below:

Playbook mytest.yml

- hosts: remotehost
  gather_facts: no
  tasks:
    - name: Execute command1
      raw: "ls -ltr"
      register: cmdoutput
      when: remcmd == "list"

    - name: Execute command2
      raw: "hostname"
      register: cmdoutput
      when: remcmd == "host"

    - name: Execute command3
      raw: "uptime"
      register: cmdoutput
      when: remcmd == "up"

- hosts: localhost
  gather_facts: no
  tasks:
    - debug:
        msg: "Printing {{ hostvars['remotehost']['cmdoutput'] }}"

This is my nventory myhost.yml

[remotehost]
myserver1

Here is how I run the playbook:

ansible-playbook -i myhost.yml mytest.yml -e remcmd="host"

PLAY [remotehost] ***************************************************************************************************************

TASK [Execute command1] *********************************************************************************************************
Thursday 06 October 2022  07:06:06 -0500 (0:00:00.013)       0:00:00.013 ******
skipping: [myserver1]

TASK [Execute command2] *********************************************************************************************************
Thursday 06 October 2022  07:06:06 -0500 (0:00:00.023)       0:00:00.036 ******
changed: [myserver1]

TASK [Execute command3] *********************************************************************************************************
Thursday 06 October 2022  07:06:06 -0500 (0:00:00.521)       0:00:00.557 ******
skipping: [myserver1]

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

TASK [debug] ********************************************************************************************************************
Thursday 06 October 2022  07:06:06 -0500 (0:00:00.032)       0:00:00.590 ******
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: \"hostvars['remotehost']\" is undefined\n\nThe error appears to be in '/home/wladmin/mytest.yml': line 22, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - debug:\n      ^ here\n"}

PLAY RECAP **********************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
myserver1                : ok=1    changed=1    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

My requirement is no matter what value is passed for remcmd my localhost play should print stdoutlines of cmdoutput

CodePudding user response:

Preliminary notes:

  1. Using raw is evil.
  2. Don't use raw unless to install prereqs (i.e. python) on the target host. Then switch to modules or at the very least command/shell
  3. If you still intend to use raw, go back to point 1 above
  4. In case your forgot to go back to point 1: using raw is evil

Don't register several tasks with the same var name (the last one always win, even if skipped). Don't create tasks you can avoid up-start.

As an illustration of the above principles

- hosts: remotehost
  gather_facts: no

  vars:
    cmd_map:
      list: ls -ltr
      host: hostname
      up: uptime
  
  tasks:
    - name: Make sure remcmd is known
      assert:
        that: remcmd in cmp_map.keys()
        fail_msg: "remcmd must be one of: {{ cmd_map.keys() | join(', ') }}"

    - name: Execute command
      command: "{{ cmd_map[remcmd] }}"
      register: cmdoutput

    - name: Show entire result from above task
      debug:
        var: cmdoutput

CodePudding user response:

my localhost play should print stdout_lines of cmdoutput

As far as I understand "How the debug module works", it can only print on the Control Node.

Therefore you could just remove three (3) lines in your example

- hosts: localhost
  gather_facts: no
  tasks:

and give it a try with

- hosts: remotehost
  gather_facts: no

  tasks:

    - name: Execute command1
      raw: "ls -ltr"
      register: cmdoutput
      when: remcmd == "list"

    - name: Execute command2
      raw: "hostname"
      register: cmdoutput
      when: remcmd == "host"

    - name: Execute command3
      raw: "uptime"
      register: cmdoutput
      when: remcmd == "up"

    - debug:
        msg: "Printing {{ cmdoutput }}"

and independently of which task became executed the result would be provided.

Apart from the answer about "How the debug module works" here, I like to recommended to proceed further with the answer of Zeitounator, since it will address your possible use case more complete.

  • Related