Ansible: Lưu trữ stdout của lệnh trong biến mới?


85

Bên trong playbook của tôi, tôi muốn tạo một biến giữ đầu ra của một lệnh bên ngoài. Sau đó, tôi muốn sử dụng biến đó trong một vài mẫu.

Dưới đây là các phần liên quan của 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

và giả sử đây là mẫu của tôi:

[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

(Lưu ý {{ string_to_echo }})

Vì vậy, những gì tôi cơ bản đang tìm kiếm là một cách để lưu trữ nội dung của command_output.stdout(được tạo / truy xuất trong tác vụ đầu tiên) trong một biến mới string_to_echo.
Biến đó tôi muốn sử dụng trong nhiều mẫu sau đó.

Tôi đoán tôi chỉ có thể sử dụng {{command_output.stdout}}trong các mẫu của mình, nhưng tôi muốn loại bỏ điều đó .stdoutđể dễ đọc.

Câu trả lời:



69

Không cần thiết phải đặt ra một sự thật.

    - shell: cat "hello"
      register: cat_contents

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

13
Điều này rất hữu ích, nhưng nó có nghĩa là sau này khi bạn sử dụng biến, bạn cũng phải nhớ để sử dụng .stdout.
Tim Malone

20

Một sửa đổi nhỏ ngoài câu trả lời của @ udondan. Tôi muốn sử dụng lại các tên biến đã đăng ký với set_factđể giúp giảm thiểu sự lộn xộn.

Vì vậy, nếu tôi đăng ký bằng cách sử dụng biến psk, tôi sẽ sử dụng cùng tên biến đó với việc tạo set_fact.

Thí dụ

- 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

Sau đó, khi tôi chạy nó:

$ 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

Tôi là người mới trong Ansible, nhưng tôi sẽ đề xuất giải pháp tiếp theo:

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

Nó sẽ hoạt động (và hiệu quả với tôi) vì Ansible sử dụng tính năng đánh giá lười biếng. Nhưng có vẻ như nó kiểm tra tính hợp lệ trước khi khởi chạy, vì vậy tôi phải xác định command_output_full.stdouttrong vars.

Và, tất nhiên, nếu nó có quá nhiều vars như vậy trong varsphần, nó sẽ trông xấu xí.


7

Trong trường hợp bạn muốn lưu trữ một lệnh phức tạp để so sánh kết quả văn bản, chẳng hạn như để so sánh phiên bản hệ điều hành, có thể điều này có thể giúp bạn:

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

Nếu bạn muốn đi xa hơn và trích xuất thông tin chính xác bạn muốn từ kết quả Playbook, hãy sử dụng ngôn ngữ truy vấn JSON như jmespath, ví dụ:

  - 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') }}"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.