Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible: Store command's stdout in new variable?

Inside my playbook I'd like to create a variable holding the output of an external command. Afterwards I want to make use of that variable in a couple of templates.

Here are the relevant parts of the playbook:

  tasks:
    - name: Create variable from command
      command: "echo Hello"
      register: command_output
    - debug: msg="{{command_output.stdout}}"

    - name: Copy test service
      template: src=../templates/test.service.j2 dest=/tmp/test.service
    - name: Enable test service
      shell: systemctl enable /tmp/test.service
    - name: Start test service
      shell: systemctl start test.service

and let's say this is my template:

[Unit]
Description=MyApp
After=docker.service
Requires=docker.service

[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox1
ExecStartPre=-/usr/bin/docker rm busybox1
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox1 busybox /bin/sh -c "while true; do echo {{ string_to_echo }}; sleep 1; done"

[Install]
WantedBy=multi-user.target

(Notice the {{ string_to_echo }})

So what I'm basically looking for is a way to store the contents of command_output.stdout (which is generated/retrieved during the first task) in a new variable string_to_echo.
That variable I'd like to use in multiple templates afterwards.

I guess I could just use {{command_output.stdout}} in my templates, but I want to get rid of that .stdout for readability.

like image 305
Forivin Avatar asked Mar 17 '16 11:03

Forivin


People also ask

How do you store output of a command in a variable in Ansible?

The command module runs the shell command, and the registar argument then accepts the results and puts them in "command_output". We then take the standard output of that and put it into the ansible variable "string_to_echo" which can then be used later in the ansible playbooks.

How do I display stdout in Ansible?

To achieve this, we use the 'register' parameter to record the output to a variable. Then use the 'debug' module to display the variable's content to standard out.

What is stdout in Ansible?

stdout. Some modules execute command line utilities or are geared for executing commands directly (raw, shell, command, and so on). This field contains the normal output of these utilities. "stdout": "foo!"

How do I print Ansible output?

To do this, you have to specify which variable to save the results into. Do this with the register parameter, independently of the module used. Here register tells ansible to save the response of the module into the shell_result variable, and then we use the debug module to print the variable out.


Video Answer


6 Answers

You have to store the content as a fact:

- set_fact:
    string_to_echo: "{{ command_output.stdout }}"
like image 136
udondan Avatar answered Oct 04 '22 20:10

udondan


There's no need to set a fact.

    - shell: cat "hello"
      register: cat_contents

    - shell: echo "I cat hello"
      when: cat_contents.stdout == "hello"
like image 44
Karel Striegel Avatar answered Oct 04 '22 22:10

Karel Striegel


A slight modification beyond @udondan's answer. I like to reuse the registered variable names with the set_fact to help keep the clutter to a minimum.

So if I were to register using the variable, psk, I'd use that same variable name with creating the set_fact.

Example

- name: generate PSK
  shell: openssl rand -base64 48
  register: psk
  delegate_to: 127.0.0.1
  run_once: true

- set_fact: 
    psk={{ psk.stdout }}

- debug: var=psk
  run_once: true

Then when I run it:

$ ansible-playbook -i inventory setup_ipsec.yml

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

 TASK [Gathering                                                                                                                                                                     Facts] *************************************************************************************************************************************************************
 ok: [hostc.mydom.com]
 ok: [hostb.mydom.com]
 ok: [hosta.mydom.com]

 TASK [libreswan : generate                                                                                                                                                          PSK] ****************************************************************************************************************************************************
 changed: [hosta.mydom.com -> 127.0.0.1]

 TASK [libreswan :                                                                                                                                                                   set_fact] ********************************************************************************************************************************************************
 ok: [hosta.mydom.com]
 ok: [hostb.mydom.com]
 ok: [hostc.mydom.com]

 TASK [libreswan :                                                                                                                                                                   debug] ***********************************************************************************************************************************************************
 ok: [hosta.mydom.com] => {
     "psk": "6Tx/4CPBa1xmQ9A6yKi7ifONgoYAXfbo50WXPc1kGcird7u/pVso/vQtz+WdBIvo"
 }

 PLAY                                                                                                                                                                                RECAP *************************************************************************************************************************************************************************
 hosta.mydom.com    : ok=4    changed=1    unreachable=0    failed=0
 hostb.mydom.com    : ok=2    changed=0    unreachable=0    failed=0
 hostc.mydom.com    : ok=2    changed=0    unreachable=0    failed=0
like image 28
slm Avatar answered Oct 04 '22 21:10

slm


I'm a newbie in Ansible, but I would suggest next solution:

playbook.yml

...
vars:
  command_output_full:
    stdout: will be overriden below
  command_output: {{ command_output_full.stdout }}
...
...
...
tasks:
  - name: Create variable from command
    command: "echo Hello"
    register: command_output_full
  - debug: msg="{{ command_output }}"

It should work (and works for me) because Ansible uses lazy evaluation. But it seems it checks validity before the launch, so I have to define command_output_full.stdout in vars.

And, of course, if it is too many such vars in vars section, it will look ugly.

like image 36
Dmitry Avatar answered Oct 04 '22 20:10

Dmitry


In case than you want to store a complex command to compare text result, for example to compare the version of OS, maybe this can help you:

tasks:
       - shell: echo $(cat /etc/issue | awk {'print $7'})
         register: echo_content

       - shell: echo "It works"
         when: echo_content.stdout == "12"
         register: out
       - debug: var=out.stdout_lines
like image 25
BrennQuin Avatar answered Oct 04 '22 20:10

BrennQuin


If you want to go further and extract the exact information you want from the Playbook results, use JSON query language like jmespath, an example:

  - name: Sample Playbook
    // Fill up your task
    no_log: True
    register: example_output

  - name: Json Query
    set_fact:
      query_result:
        example_output:"{{ example_output | json_query('results[*].name') }}"
like image 32
Santhosh Balasa Avatar answered Oct 04 '22 21:10

Santhosh Balasa