Trong Ansible, mặc định các task được chạy trên các host đã khai báo trong inventory. Tuy nhiên, đôi khi bạn muốn một task cụ thể chạy trên một host khác thay vì host hiện tại.
Đó là lúc bạn dùng delegate_to.
delegate_tokhông phải là một module riêng biệt.- Đây là một directive (chỉ thị), cho phép bạn “chỉ định” host cụ thể để thực thi task.
Xem thêm:
Ansible Local Action – Thực thi tác vụ trên Controller
Hướng dẫn sử dụng Block, Rescue và Always trong Ansible Playbook
Hướng dẫn sử dụng Error Handling trong Ansible Playbook
1. Ansible Delegate To là gì?
Trong Ansible, delegate_to là một directive (chỉ thị), cho phép bạn chỉ định một host cụ thể để chạy một task, thay vì chạy trên host mặc định trong inventory.
Nói đơn giản:
- Bình thường, mỗi task trong playbook sẽ chạy trên từng host trong danh sách
hosts. - Nhưng với
delegate_to, bạn có thể buộc task đó chạy ở một host khác (có thể làlocalhosthoặc một host trong inventory).
2. Khi nào dùng delegate_to?
Một số tình huống thực tế:
- Chạy lệnh backup database chỉ trên máy DB, không phải trên toàn bộ cluster.
- Ghi log hoặc thu thập thông tin từ nhiều host, nhưng lưu kết quả vào một host tập trung.
- Tạo chứng chỉ trên một máy duy nhất rồi phân phối cho các máy còn lại.
3. Cú pháp cơ bản
- name: Task chạy trên host khác
command: echo "Hello from {{ inventory_hostname }}"
delegate_to: target_host
delegate_to: target_host→ xác định rõ task sẽ chạy trên host nào.target_hostcó thể là:- Tên host trong inventory (
db,loadbalancer,web1, …). - Hoặc địa chỉ IP trực tiếp (
192.168.1.10). - Đặc biệt:
localhost→ chạy trên Ansible controller.
- Tên host trong inventory (
4. Ví dụ
Giả sử ta có 2 host trong inventory:
web1(ứng dụng).db1(database).
Mục tiêu:
- Tạo file log tạm trên tất cả host.
- Ghi hostname của mỗi host vào file log, nhưng file log chỉ được lưu tại một máy duy nhất (ví dụ
db1).
Playbook:
---
- name: Demo Delegate To
hosts: all
become: yes
vars:
log_path: /tmp/connection.log
tasks:
- name: Ensure log file exists
shell: "test -f {{ log_path }} || touch {{ log_path }}"
args:
warn: false
- name: Write host info into log file (delegated)
shell: "echo '{{ inventory_hostname }} - {{ ansible_hostname }}' >> {{ log_path }}"
delegate_to: db1
5. Giải thích từng bước
Task 1: Tạo file log
shell: "test -f {{ log_path }} || touch {{ log_path }}"
- Kiểm tra file
/tmp/connection.log. - Nếu chưa có thì tạo mới.
- Chạy trên từng host trong inventory.
Task 2: Ghi thông tin vào log (delegated)
delegate_to: db1
- Dù playbook chạy trên tất cả host, nhưng task này chỉ chạy tại
db1. - Mỗi lần lặp qua một host khác (
web1,db1, …), nội dung log vẫn được ghi vào cùng một file trêndb1. - Ví dụ kết quả file
/tmp/connection.logtrêndb1:
web1 - web1-hostname db1 - db1-hostname
6. So sánh delegate_to và local_action
| Tiêu chí | local_action |
delegate_to |
|---|---|---|
| Cú pháp | Viết ngắn gọn: local_action: <module> |
Viết đầy đủ: delegate_to: localhost |
| Ngữ nghĩa | Dễ hiểu, chuyên biệt: task này luôn chạy ở controller | Linh hoạt: task có thể chạy ở bất kỳ host nào (kể cả controller nếu chỉ định localhost) |
| Tính tương thích cũ | Xuất hiện từ Ansible rất sớm, nhiều ví dụ/lab cũ vẫn dùng | Bổ sung sau này, thống nhất hơn với triết lý “delegate cho host cụ thể” |
| Đọc code | Khi thấy local_action, người đọc biết ngay là chạy trên controller |
Khi thấy delegate_to, người đọc phải nhìn giá trị (localhost hay host khác) |
delegate_to là một công cụ cực kỳ hữu ích để linh hoạt điều khiển nơi task được chạy. Trong môi trường production, nó giúp giảm trùng lặp, tối ưu hóa tài nguyên và dễ dàng quản lý hạ tầng phức tạp.
Bài viết cùng chủ đề:
Hướng dẫn tạo Cron Job tự động dọn dẹp log bằng Ansible
Ansible Vault – Bài 11