Playbook: Cấu Trúc và Task

K
Kai··4 min read

Lệnh ad-hoc (Bài 2) tốt cho việc một lần. Nhưng sức mạnh thật của Ansible nằm ở playbook — file YAML mô tả trạng thái mong muốn của hệ thống, chạy lại được, đưa vào Git được. Bài này viết và chạy playbook đầu tiên thật trên EC2.

Playbook là gì

Playbook là một file YAML gồm một hay nhiều play. Mỗi play gắn một tập host với một danh sách task. Mỗi task gọi một module (Bài 1) với tham số cụ thể.

   Playbook (file .yml)
   └── Play: "áp lên nhóm web, với quyền root"
        ├── Task 1: dùng module dnf cài nginx
        ├── Task 2: dùng module service bật nginx
        └── Task 3: dùng module copy đặt index.html

Playbook đầu tiên

Tạo site.yml — cài và cấu hình một web server:

---
- name: Cài và cấu hình web server      # tên play
  hosts: web                            # áp lên nhóm "web" (Bài 3)
  become: true                          # chạy với quyền root (Bài 2)
  tasks:
    - name: Cài nginx
      ansible.builtin.dnf:
        name: nginx
        state: present

    - name: Đảm bảo nginx chạy và bật khi boot
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: true

    - name: Triển khai trang index
      ansible.builtin.copy:
        content: "<h1>Trien khai bang Ansible</h1>\n"
        dest: /usr/share/nginx/html/index.html

Đọc cấu trúc:

  • Play mở đầu bằng - name: (mô tả), hosts: (áp lên ai), become: (quyền), rồi tasks:.
  • Mỗi taskname: (mô tả, hiện ra khi chạy) và một module với tham số. Ví dụ task đầu gọi module ansible.builtin.dnf với name: nginx, state: present (nghĩa là "nginx phải được cài").
  • Để ý ta khai báo trạng thái (state: present, state: started), không phải lệnh — đây là tinh thần khai báo của Ansible.

Về ansible.builtin.dnf — đó là FQCN (Fully Qualified Collection Name): namespace.collection.module. ansible.builtin là collection lõi có sẵn. Viết tắt dnf cũng chạy, nhưng FQCN là best practice (rõ ràng, tránh trùng tên) — Bài 9 nói về collection.

Chạy playbook

ansible-playbook site.yml
TASK [Gathering Facts] *********************
ok: [lab]
TASK [Cài nginx] **************************
changed: [lab]
TASK [Đảm bảo nginx chạy và bật khi boot] **
changed: [lab]
TASK [Triển khai trang index] *************
changed: [lab]

PLAY RECAP ********************************
lab : ok=4  changed=3  unreachable=0  failed=0  skipped=0

Sau khi chạy, curl http://<ip>/ trả về <h1>Trien khai bang Ansible</h1> — web server đã được dựng hoàn toàn tự động.

Đọc kết quả: trạng thái task và PLAY RECAP

Mỗi task in một trạng thái cho từng host:

  • ok — đã đúng trạng thái mong muốn, không cần làm gì.
  • changed (vàng) — Ansible đã thay đổi gì đó để đạt trạng thái.
  • failed (đỏ) — task lỗi.
  • skipped — bị bỏ qua (do điều kiện — Bài 7).

PLAY RECAP ở cuối tổng kết mỗi host: ok=4 changed=3 failed=0. Hai con số cần nhìn ngay: failed (phải là 0) và changed (Ansible đã đổi bao nhiêu thứ).

Gathering Facts là gì

Để ý task đầu Gathering Facts mà ta không hề viết — Ansible tự chạy module setup (Bài 2) đầu mỗi play để thu thập thông tin host (OS, IP...) cho các task dùng (Bài 6). Có thể tắt bằng gather_facts: false nếu không cần (chạy nhanh hơn).

Idempotency: chạy lại an toàn

Chạy ansible-playbook site.yml lần thứ hai:

PLAY RECAP ********************************
lab : ok=4  changed=0  unreachable=0  failed=0

changed=0! Lần đầu Ansible đổi 3 thứ (cài nginx, bật service, đặt file); lần hai mọi thứ đã đúng nên nó không làm gì — chỉ kiểm tra. Đây là idempotency: chạy bao nhiêu lần cũng an toàn, chỉ sửa cái chưa đúng. Bài 5 đào sâu vì sao module làm được điều này.

Vài cờ ansible-playbook hữu ích

ansible-playbook site.yml --check        # dry-run: xem SẼ đổi gì, KHÔNG đổi thật
ansible-playbook site.yml --diff         # hiện khác biệt nội dung file thay đổi
ansible-playbook site.yml --limit lab    # chỉ chạy trên host/nhóm này
ansible-playbook site.yml --list-tasks   # liệt kê task mà không chạy
ansible-playbook site.yml -v             # verbose (thêm -vvv để xem cơ chế — Bài 1)

--check (check mode / dry-run) cực quan trọng trong thực tế: xem playbook sẽ thay đổi gì trước khi áp thật — tránh bất ngờ trên production. Kết hợp --diff để thấy nội dung file sẽ đổi ra sao. (Bài 13 nói kỹ check mode.)

YAML: vài lưu ý dễ vấp

Playbook là YAML, và YAML nhạy cảm với thụt lề (dùng dấu cách, không dùng tab) và cấu trúc. Lỗi hay gặp của người mới: thụt lề sai, quên dấu - trước phần tử danh sách, hoặc thiếu dấu hai chấm. Khi playbook báo lỗi cú pháp, kiểm tra thụt lề trước tiên. Lệnh ansible-playbook --syntax-check site.yml bắt lỗi cú pháp mà không chạy.

Tổng kết

Playbook là file YAML gồm các play; mỗi play gắn hosts với danh sách task, mỗi task gọi một module với tham số (dùng FQCN như ansible.builtin.dnf). Ta khai báo trạng thái (state: present/started), không phải lệnh. Chạy bằng ansible-playbook, đọc PLAY RECAP (ok/changed/failed). Ansible tự Gathering Facts đầu play. Và playbook idempotent — chạy lần hai cho changed=0. Dùng --check để dry-run trước khi áp production.

Idempotency vừa nhắc là tính chất nền tảng. Bài 5 mổ xẻ: module hoạt động bên trong thế nào để đạt được nó, và đó cũng là deep-dive chuẩn bị cho việc tự viết module sau này.