Ansible: memorizzare lo stdout del comando in una nuova variabile?


86

All'interno del mio playbook vorrei creare una variabile contenente l'output di un comando esterno. Successivamente voglio utilizzare quella variabile in un paio di modelli.

Ecco le parti rilevanti del 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

e diciamo che questo è il mio modello:

[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

(Notare il {{ string_to_echo }})

Quindi quello che sto cercando fondamentalmente è un modo per memorizzare il contenuto di command_output.stdout(che viene generato / recuperato durante la prima attività) in una nuova variabile string_to_echo.
Quella variabile che vorrei utilizzare in più modelli in seguito.

Immagino di poterlo usare solo {{command_output.stdout}}nei miei modelli, ma voglio sbarazzarmene .stdoutper la leggibilità.

Risposte:



71

Non è necessario stabilire un dato di fatto.

    - shell: cat "hello"
      register: cat_contents

    - shell: echo "I cat hello"
      when: cat_contents.stdout == "hello"

14
Questo è utile, ma significa che in seguito, quando usi la variabile, devi ricordarti di usare .stdoutanche tu .
Tim Malone

21

Una leggera modifica oltre la risposta di @udondan. Mi piace riutilizzare i nomi delle variabili registrate con il set_factper aiutare a mantenere il disordine al minimo.

Quindi, se dovessi registrarmi usando la variabile, pskuserei lo stesso nome di variabile con la creazione del file set_fact.

Esempio

- 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

Quindi quando lo eseguo:

$ 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

8

Sono un principiante in Ansible, ma suggerirei la prossima soluzione:

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 }}"

Dovrebbe funzionare (e funziona per me) perché Ansible utilizza una valutazione pigra. Ma sembra che controlli la validità prima del lancio, quindi devo definire command_output_full.stdoutin vars.

E, naturalmente, se sono troppe di queste variabili in varssezione, sembrerà brutto.


7

Nel caso in cui desideri memorizzare un comando complesso per confrontare il risultato del testo, ad esempio per confrontare la versione del sistema operativo, forse questo può aiutarti:

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

1

Se vuoi andare oltre ed estrarre le informazioni esatte che desideri dai risultati del Playbook, usa un linguaggio di query JSON come jmespath, un esempio:

  - 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') }}"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.