Ansible: Stdout des Befehls in neuer Variable speichern?


85

In meinem Playbook möchte ich eine Variable erstellen, die die Ausgabe eines externen Befehls enthält. Danach möchte ich diese Variable in einigen Vorlagen verwenden.

Hier sind die relevanten Teile des Spielbuchs:

  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

und sagen wir, das ist meine Vorlage:

[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

(Beachten Sie die {{ string_to_echo }})

Ich suche also im Grunde nach einer Möglichkeit, den Inhalt von command_output.stdout(der während der ersten Aufgabe generiert / abgerufen wird) in einer neuen Variablen zu speichern string_to_echo.
Diese Variable möchte ich anschließend in mehreren Vorlagen verwenden.

Ich denke, ich könnte nur {{command_output.stdout}}in meinen Vorlagen verwenden, aber ich möchte das aus Gründen der .stdoutLesbarkeit loswerden .

Antworten:



69

Es ist nicht nötig, eine Tatsache festzulegen.

    - shell: cat "hello"
      register: cat_contents

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

13
Dies ist hilfreich, bedeutet jedoch, dass Sie später, wenn Sie die Variable verwenden, auch daran denken müssen, sie zu verwenden .stdout.
Tim Malone

20

Eine geringfügige Änderung, die über die Antwort von @ udondan hinausgeht. Ich verwende die registrierten Variablennamen gerne wieder mit set_fact, um die Unordnung auf ein Minimum zu beschränken.

Wenn ich mich also mit der Variablen registrieren pskwürde, würde ich beim Erstellen der Variablen denselben Variablennamen verwenden set_fact.

Beispiel

- 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

Dann, wenn ich es laufen lasse:

$ 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

7

Ich bin ein Neuling in Ansible, aber ich würde die nächste Lösung vorschlagen:

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

Es sollte funktionieren (und funktioniert für mich), da Ansible eine verzögerte Auswertung verwendet. Aber es scheint, dass es die Gültigkeit vor dem Start überprüft, also muss ich command_output_full.stdoutin vars definieren .

Und wenn es im varsAbschnitt zu viele solcher Vars gibt , sieht es natürlich hässlich aus.


7

Wenn Sie einen komplexen Befehl zum Vergleichen des Textergebnisses speichern möchten, z. B. zum Vergleichen der Betriebssystemversion, kann dies möglicherweise hilfreich sein:

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

Wenn Sie weiter gehen und genau die gewünschten Informationen aus den Playbook-Ergebnissen extrahieren möchten, verwenden Sie eine JSON-Abfragesprache wie jmespath, ein Beispiel:

  - 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') }}"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.