How to pass stdout of a variable belonging to different Ansible play ?

21 views
Skip to first unread message

Mohtashim S

unread,
Aug 30, 2019, 4:22:08 AM8/30/19
to Ansible Project
How to pass "stdout" of a variable "command_result" belonging to Ansible Play-1 to shell module of a different Play-2?

My playbook looks like below:

- name: Play 1
  hosts
: localhost
  tasks
:
   
- name: "Collect Output"
     command
: ls -ltr *
     
register: command_result



- name: Play 2
  hosts
: remotehost
  tasks
:
   
- shell: "~/rollback.sh {{ Number }} '{{ InstallDir }}' '{{ hostvars[\"localhost\"][\"command_result\"].results|map(attribute=/'stdout/')|list }}' > ~/rollback.log"

I get runtime error executing shell which is of the nature below:

fatal: [10.12.34.43]: FAILED! => {"msg": "template error while templating string: unexpected '/'. String: ~/rollback.sh {{ Number }} '{{ InstallDir }}' '{{ hostvars[\"localhost\"][\"command_result\"].results|map(attribute=/'stdout/')|list }}' > ~/rollback.log"}

I tried several tweaks but not sure how to get this to work ?

Vladimir Botka

unread,
Aug 30, 2019, 4:33:25 AM8/30/19
to Mohtashim S, ansible...@googlegroups.com
On Fri, 30 Aug 2019 01:22:08 -0700 (PDT)
Mohtashim S <mohta...@gmail.com> wrote:

> How to pass "stdout" of a variable "command_result" belonging to Ansible
> Play-1 to shell module of a different Play-2?
>
> My playbook looks like below:
>
> - name: Play 1
> hosts: localhost
> tasks:
> - name: "Collect Output"
> command: ls -ltr *
> register: command_result

- set_fact:
command_result: "{{ command_result }}"

> - name: Play 2
> hosts: remotehost
> tasks:
> - shell: "~/rollback.sh {{ Number }} '{{ InstallDir }}' '{{
> hostvars[\"localhost\"][\"command_result\"].results|map(attribute=/'stdout/')|list
> }}' > ~/rollback.log"

Make the scope of "command_result" playbook-wide with "set_fact". Registered
variables belong to the host which is running the play. i.e. "localhost" in
your case. The second play runs "remotehost" who know nothing about varaibles
registered by "localhost".

Cheers,

-vlado

Vladimir Botka

unread,
Aug 30, 2019, 5:09:15 AM8/30/19
to Mohtashim S, ansible...@googlegroups.com
On Fri, 30 Aug 2019 01:22:08 -0700 (PDT)
Mohtashim S <mohta...@gmail.com> wrote:

> - name: Play 2
> hosts: remotehost
> tasks:
> - shell: "~/rollback.sh {{ Number }} '{{ InstallDir }}' '{{
> hostvars[\"localhost\"][\"command_result\"].results|map(attribute=/'stdout/')|list
> }}' > ~/rollback.log"
>
> I get runtime error executing shell which is of the nature below:
>
> fatal: [10.12.34.43]: FAILED! => {"msg": "template error while templating
> > string: unexpected '/'. String: ~/rollback.sh {{ Number }} '{{ InstallDir
> > }}' '{{
> > hostvars[\"localhost\"][\"command_result\"].results|map(attribute=/'stdout/')|list
> > }}' > ~/rollback.log"}

The problem is the string is shell. Try to create the parameters first. For
example

- set_fact:
my_list: "{{ hostvars['localhost'].command_result.results|
map(attribute='stdout')|list }}"

- shell: "~/rollback.sh {{ Number }} '{{ InstallDir }}' '{{ my_list }}' > ~/rollback.log"

Message has been deleted

Mohtashim S

unread,
Aug 30, 2019, 5:30:30 AM8/30/19
to Ansible Project
I tried the set_fact suggestion but seems I need more help / understanding.

Below is the error i get:

FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'command_result' is undefined\n\nThe error appears to be in '/app/rollback.yml': line 88, column 6, but may\nbe elsewhere in the file depending on the exact syntax problem.

Below is my updated playbook:

- name: Play 1
  hosts
: localhost
  tasks
:
   
- name: "Collect Output"
     command
: ls -ltr *
     
register: command_result
   
- set_fact:
       command_result
: "{{ command_result }}"

- name: Play 2
  hosts
: remotehost
  tasks
:

   
- shell: "~/rollback.sh {{ Number }} '{{ InstallDir }}' '{{ command_result.stdout }}' > ~/rollback.log"


Mohtashim S

unread,
Aug 30, 2019, 5:41:13 AM8/30/19
to Ansible Project
The solution given with "my_list" is complaining of the below error:

 FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'results'\n\nThe error appears to be in

Guess we need to relook at this proposed code snippet:

my_list: "{{ hostvars['localhost'].command_result.results|map(attribute='stdout')|list }}"

Something is still wrong.

Vladimir Botka

unread,
Aug 31, 2019, 4:24:15 AM8/31/19
to Mohtashim S, ansible...@googlegroups.com
On Fri, 30 Aug 2019 02:41:12 -0700 (PDT)
Mohtashim S <mohta...@gmail.com> wrote:

> The solution given with "my_list" is complaining of the below error:
> >
> > FAILED! => {"msg": "The task includes an option with an undefined
> > variable. The error was: 'dict object' has no attribute 'results'\n\nThe
> > error appears to be in
>
> Guess we need to relook at this proposed code snippet:
>
> my_list: "{{
> hostvars['localhost'].command_result.results|map(attribute='stdout')|list
> }}"
>
> Something is still wrong.

[SOLVED]

The playbook below

- hosts: localhost
tasks:
- set_fact:
Number: '42'
- set_fact:
InstallDir: '/usr/local'
- name: 'Collect Output'
command: "sh -c 'ls -1 /scratch/tmp/*.db'"
register: result

- hosts: test_01
tasks:
- set_fact:
My_list: "{{ hostvars['localhost'].result.stdout_lines|join(',') }}"
- set_fact:
Number: "{{ hostvars['localhost'].Number }}"
- set_fact:
InstallDir: "{{ hostvars['localhost'].InstallDir }}"
- shell: "/root/rollback.sh {{ Number }}
{{ InstallDir }}
{{ My_list }} > /root/rollback.log"
...

With the script

root@test_01:~ # cat /root/rollback.sh
#!/usr/local/bin/bash
echo $1
echo $2
echo $3

gives

root@test_01:~ # cat /root/rollback.log
42
/usr/local
/scratch/tmp/test1.db,/scratch/tmp/test2.db,/scratch/tmp/test3.db

--
Reply all
Reply to author
Forward
0 new messages