Làm cách nào để viết một trình xử lý Ansible với nhiều tác vụ?


81

Để đáp ứng với một thay đổi, tôi có nhiều tác vụ liên quan sẽ chạy. Làm cách nào để viết một trình xử lý Ansible với nhiều tác vụ?

Ví dụ: tôi muốn một trình xử lý chỉ khởi động lại một dịch vụ khi đã bắt đầu:

- name: Restart conditionally
  shell: check_is_started.sh
  register: result

- name: Restart conditionally step 2
  service: name=service state=restarted
  when: result

Câu trả lời:


95

Có giải pháp thích hợp cho vấn đề này kể từ Ansible 2.2.

người xử lý cũng có thể “lắng nghe” các chủ đề chung chung và các nhiệm vụ có thể thông báo cho các chủ đề đó như sau:

handlers:
    - name: restart memcached
      service: name=memcached state=restarted
      listen: "restart web services"
    - name: restart apache
      service: name=apache state=restarted
      listen: "restart web services"

tasks:
    - name: restart everything
      command: echo "this task will restart the web services"
      notify: "restart web services"

Việc sử dụng này giúp kích hoạt nhiều trình xử lý dễ dàng hơn nhiều. Nó cũng tách các trình xử lý khỏi tên của chúng, giúp chia sẻ các trình xử lý giữa các vở kịch và vai trò dễ dàng hơn

Cụ thể cho câu hỏi, điều này sẽ hoạt động:

- name: Check if restarted
  shell: check_is_started.sh
  register: result
  listen: Restart processes

- name: Restart conditionally step 2
  service: name=service state=restarted
  when: result
  listen: Restart processes

và trong tác vụ, thông báo cho người xử lý qua 'Khởi động lại quy trình'

http://docs.ansible.com/ansible/playbooks_intro.html#handlers-running-operations-on-change


1
Giải pháp này có cho phép sử dụng khối: và giải cứu: để xử lý lỗi bằng cách khởi chạy các lệnh không?
user1767316

3
Nhiều tác vụ có được thực hiện theo thứ tự được liệt kê không? Nếu một tác vụ phụ thuộc vào một tác vụ khác, tôi có nên sử dụng thông báo-lắng nghe bên trong trình xử lý không?
dùng26767

@ user26767 từ tài liệu được liên kết:Notify handlers are always run in the same order they are defined, not in the order listed in the notify-statement. This is also the case for handlers using listen.
swenzel

55

Trong tệp trình xử lý của bạn, hãy xâu chuỗi các bước khác nhau lại với nhau bằng cách sử dụng thông báo.

- name: Restart conditionally
  debug: msg=Step1
  changed_when: True
  notify: Restart conditionally step 2

- name: Restart conditionally step 2
  debug: msg=Step2
  changed_when: True
  notify: Restart conditionally step 3

- name: Restart conditionally step 3
  debug: msg=Step3

Sau đó, tham chiếu đến nó từ một nhiệm vụ với notify: Restart conditionally.

Lưu ý rằng bạn chỉ có thể thông báo cho các trình xử lý bên dưới trình xử lý hiện tại. Vì vậy, ví dụ, Restart conditionally step 2không thể thông báo Restart conditionally.

Nguồn: #ansible tại irc.freenode.net. Tôi không chắc liệu điều này có tiếp tục hoạt động trong tương lai hay không vì nó không được đề cập như một tính năng trong tài liệu chính thức.


Phương pháp này giúp đưa ra một thực tế mà dường như ít tài liệu: Các trình xử lý, một khi được thông báo, sẽ thực thi ngay cả khi một trong các trình xử lý đó không thành công. Sử dụng các notifynhãn khác nhau cho những nhãn mà bạn có thể không muốn chạy nếu trình xử lý trước đó bị lỗi là một cách tốt để "sửa chữa" điều này nếu bạn không muốn nó như vậy.
fbicknel

27

Chỉnh sửa: Nếu bạn có Ansible 2.2 trở lên, hãy sử dụng câu trả lời của mkadan. Câu trả lời dưới đây không hoạt động với các phiên bản mới hơn của Ansible. Cũng lưu ý rằng theo nhận xét của Enis Afgan bên dưới, do lỗi, câu trả lời này không hoạt động với các phiên bản Ansible từ 2.0.2 đến 2.1.2.


Kể từ Ansible 2.0, bạn có thể sử dụng hành động bao gồm trong trình xử lý của mình để chạy nhiều tác vụ.

Ví dụ: đặt các nhiệm vụ của bạn trong một tệp riêng restart_tasks.yml(nếu bạn sử dụng các vai trò, thì sẽ đi vào thư mục con nhiệm vụ, không phải trong thư mục con của trình xử lý):

- name: Restart conditionally step 1
  shell: check_is_started.sh
  register: result

- name: Restart conditionally step 2
  service: name=service state=restarted
  when: result

Trình xử lý của bạn sau đó sẽ chỉ đơn giản là:

- name: Restart conditionally
  include: restart_tasks.yml

Nguồn: chủ đề vấn đề trên github: https://github.com/ansible/ansible/issues/14270


5
Chỉ cần một lưu ý rằng các phiên bản Ansible giữa 2.0.2 và 2.1.2 có một lỗi nơi này không làm việc: github.com/ansible/ansible/issues/15915
Enis Afgan

1
Đối với độc giả tương lai - điều này không hiệu quả với tôi trên Ansible 2.9.2. Bản sửa lỗi đã được thay thế includebằng include_tasks.
Martin Melka

@MartinMelka cảm ơn, tôi đã thêm cảnh báo vào đầu câu trả lời của mình rằng nó không dành cho các phiên bản Ansible> = 2.2.
Alexander Klauer

Tuyệt vời, cảm ơn :) Khi thiết kế trình xử lý mới, câu trả lời khác sẽ tốt hơn. Nhưng khi mã khoảng không quảng cáo Ansible đã cũ và người ta chỉ cần thực hiện những thay đổi nhỏ (như tôi đã làm), thì mã của bạn vẫn có thể hữu ích với phần bổ sung nhỏ này.
Martin Melka
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.