Lab 4 — Ansible Playbook Fundamentals
Mục tiêu: Chuyển từ việc sử dụng Ansible để chạy các command đơn lẻ sang viết Playbook có cấu trúc, có thể tái sử dụng và version control. Sau Lab này, người học có thể tự viết Playbook để cài đặt package, tạo user, quản lý service và triển khai một cấu hình đơn giản.
1. Bối cảnh
Ở Lab 3, chúng ta đã sử dụng Ad-Hoc Command:
ansible webservers -m ansible.builtin.apt \
-a "name=nginx state=present" \
-b
Cách này rất tiện nếu chúng ta chỉ cần thực hiện một thao tác.
Nhưng hãy tưởng tượng yêu cầu trở thành:
1. Cài Nginx
2. Tạo user deploy
3. Tạo thư mục /opt/myapp
4. Copy configuration
5. Start Nginx
6. Enable Nginx
7. Kiểm tra service
Nếu sử dụng Ad-Hoc:
ansible ...
ansible ...
ansible ...
ansible ...
ansible ...
ansible ...
ansible ...
Rất nhanh chóng chúng ta sẽ gặp vấn đề:
- Khó nhớ đã chạy những gì.
- Khó review.
- Khó chia sẻ cho người khác.
- Khó version control.
- Khó chạy lại.
- Dễ chạy sai thứ tự.
- Khó audit.
Giải pháp là:
Playbook
│
┌───────────┼───────────┐
▼ ▼ ▼
Task 1 Task 2 Task 3
│ │ │
▼ ▼ ▼
Package User Service
2. Playbook là gì?
Playbook là file YAML mô tả các automation task mà Ansible cần thực hiện trên Managed Nodes.
Ví dụ đơn giản:
---
- name: Install Nginx
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Có thể đọc Playbook này như sau:
Trên nhóm
webservers, sử dụng quyền root và đảm bảo Nginx được cài đặt.
3. Ad-Hoc Command vs Playbook
Ad-Hoc
ansible webservers \
-b \
-m ansible.builtin.apt \
-a "name=nginx state=present"
Playbook
- name: Install Nginx
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Điểm khác biệt quan trọng:
Ad-Hoc
↓
Command
Playbook
↓
Code
↓
Automation
↓
Version Control
↓
Repeatable
4. Cấu trúc cơ bản của Playbook
Một Playbook thường có cấu trúc:
---
- name: Play name
hosts: target
become: true
vars:
...
tasks:
- name: Task 1
module:
...
- name: Task 2
module:
...
Có thể hình dung:
Playbook
│
├── Play
│ │
│ ├── hosts
│ ├── become
│ ├── vars
│ └── tasks
│ ├── Task
│ ├── Task
│ └── Task
│
└── Play
└── ...
Một Playbook có thể có một hoặc nhiều Play.
5. Tạo project
Tạo project mới:
mkdir ansible-lab-04
cd ansible-lab-04
Cấu trúc:
ansible-lab-04/
├── ansible.cfg
├── inventory.ini
└── playbook.yml
Ví dụ ansible.cfg:
[defaults]
inventory = ./inventory.ini
6. Inventory
Sử dụng Inventory:
[webservers]
web-01 ansible_host=192.168.56.101
web-02 ansible_host=192.168.56.102
[appservers]
app-01 ansible_host=192.168.56.103
[dbservers]
db-01 ansible_host=192.168.56.104
Kiểm tra:
ansible-inventory --graph
7. Play đầu tiên
Tạo:
playbook.yml
Nội dung:
---
- name: My first Ansible Playbook
hosts: webservers
tasks:
- name: Check server uptime
ansible.builtin.command:
cmd: uptime
Chạy:
ansible-playbook playbook.yml
Kết quả có thể giống:
PLAY [My first Ansible Playbook] ************************
TASK [Check server uptime] *******************************
changed: [web-01]
changed: [web-02]
PLAY RECAP ***********************************************
web-01 : ok=1 changed=1 unreachable=0 failed=0
web-02 : ok=1 changed=1 unreachable=0 failed=0
8. ansible-playbook là gì?
Đây là command dùng để chạy Playbook:
ansible-playbook playbook.yml
Khác với:
ansible
dùng cho Ad-Hoc Command.
Có thể nhớ:
ansible
↓
Ad-Hoc
ansible-playbook
↓
Playbook
9. name
Ví dụ:
- name: Install Nginx
và:
- name: Create deploy user
name không quyết định logic.
Nó giúp:
- Đọc Playbook dễ hơn.
- Hiểu task đang làm gì.
- Debug dễ hơn.
- Log rõ ràng hơn.
Không nên viết:
- name: Task 1
Nên viết:
- name: Install nginx
Tên task nên mô tả ý định của task.
10. hosts
Ví dụ:
- name: Configure web servers
hosts: webservers
Ansible sẽ tìm group:
[webservers]
trong Inventory.
Có thể sử dụng:
hosts: webservers
hoặc:
hosts: appservers
hoặc:
hosts: all
11. become
Nếu task cần quyền root:
become: true
Ví dụ:
- name: Install nginx
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Thay vì phải thêm:
-b
ở mỗi command, Playbook có thể khai báo một lần:
become: true
12. tasks
Task là đơn vị thực thi cơ bản trong Play.
Ví dụ:
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Start nginx
ansible.builtin.service:
name: nginx
state: started
Ở đây có hai task:
Task 1
Install nginx
↓
Task 2
Start nginx
Ansible thực hiện task theo thứ tự từ trên xuống dưới.
13. Module trong Playbook
Ở Lab 3 chúng ta viết:
-m ansible.builtin.apt
-a "name=nginx state=present"
Trong Playbook:
ansible.builtin.apt:
name: nginx
state: present
Có thể thấy Playbook dễ đọc hơn rất nhiều.
Ad-Hoc
ansible webservers \
-b \
-m ansible.builtin.apt \
-a "name=nginx state=present"
Playbook
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
14. Playbook đầu tiên — Install Nginx
Tạo:
---
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Chạy:
ansible-playbook playbook.yml
Nếu thành công:
TASK [Install nginx]
changed: [web-01]
changed: [web-02]
15. Chạy lại Playbook
Bây giờ:
ansible-playbook playbook.yml
Lần này có thể thấy:
TASK [Install nginx]
ok: [web-01]
ok: [web-02]
Không còn:
changed
Đây là một trong những điểm quan trọng nhất của Ansible.
First run
↓
Resource chưa tồn tại
↓
changed
Second run
↓
Desired state đã đạt
↓
ok
Đó chính là:
Idempotency
16. changed và ok
Ansible thường trả về các trạng thái:
ok
changed
failed
skipped
unreachable
ok
Task chạy thành công và không cần thay đổi.
ok: [web-01]
changed
Ansible đã thay đổi server.
changed: [web-01]
failed
Task thất bại.
failed: [web-01]
skipped
Task bị bỏ qua.
skipping: [web-01]
unreachable
Không thể kết nối đến server.
UNREACHABLE!
17. Playbook nhiều task
Bây giờ mở rộng:
---
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Start nginx
ansible.builtin.service:
name: nginx
state: started
- name: Enable nginx
ansible.builtin.service:
name: nginx
enabled: true
Có thể gộp state và enabled:
- name: Ensure nginx is running
ansible.builtin.service:
name: nginx
state: started
enabled: true
Đây là cách viết tốt hơn.
18. Tạo User
Thêm task:
- name: Create deploy user
ansible.builtin.user:
name: deploy
state: present
Full Playbook:
---
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Create deploy user
ansible.builtin.user:
name: deploy
state: present
- name: Ensure nginx is running
ansible.builtin.service:
name: nginx
state: started
enabled: true
19. Tạo Directory
Sử dụng file:
- name: Create application directory
ansible.builtin.file:
path: /opt/myapp
state: directory
owner: deploy
group: deploy
mode: "0755"
Ở đây chúng ta không nói:
"Hãy chạy
mkdir."
Mà nói:
"
/opt/myappphải tồn tại, thuộc userdeploy, groupdeployvà có permission0755."
Đây chính là tư duy declarative.
20. Copy File
Tạo file trên Control Node:
index.html
Nội dung:
<h1>Hello from Ansible</h1>
Playbook:
- name: Deploy index page
ansible.builtin.copy:
src: index.html
dest: /var/www/html/index.html
owner: root
group: root
mode: "0644"
Flow:
Control Node
│
│ copy
▼
Managed Node
│
▼
/var/www/html/index.html
21. Playbook hoàn chỉnh đầu tiên
Bây giờ:
---
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: Create deploy user
ansible.builtin.user:
name: deploy
state: present
- name: Create application directory
ansible.builtin.file:
path: /opt/myapp
state: directory
owner: deploy
group: deploy
mode: "0755"
- name: Deploy index page
ansible.builtin.copy:
src: index.html
dest: /var/www/html/index.html
owner: root
group: root
mode: "0644"
- name: Ensure nginx is running
ansible.builtin.service:
name: nginx
state: started
enabled: true
Chạy:
ansible-playbook playbook.yml
22. Tư duy quan trọng: Desired State
Đây là điểm người mới cần hiểu thật chắc.
Imperative:
mkdir /opt/myapp
chown deploy:deploy /opt/myapp
chmod 755 /opt/myapp
Bạn đang nói:
Làm những command này.
Declarative:
- name: Create application directory
ansible.builtin.file:
path: /opt/myapp
state: directory
owner: deploy
group: deploy
mode: "0755"
Bạn đang nói:
Tôi muốn hệ thống đạt trạng thái này.
Đây là một trong những nền tảng quan trọng của:
- Ansible
- Kubernetes
- Terraform
- Configuration Management
- Infrastructure as Code
23. YAML cơ bản
Ansible Playbook sử dụng YAML.
Ví dụ:
name: nginx
state: present
Tương đương concept:
name → nginx
state → present
YAML sử dụng indentation.
Đúng:
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Sai:
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Indentation rất quan trọng.
24. List trong YAML
Ví dụ:
packages:
- nginx
- curl
- git
Ansible có thể sử dụng:
name:
- nginx
- curl
- git
Ví dụ:
- name: Install packages
ansible.builtin.apt:
name:
- nginx
- curl
- git
state: present
25. Một Playbook có nhiều Play
Playbook không nhất thiết chỉ có một Play.
Ví dụ:
---
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Configure database servers
hosts: dbservers
become: true
tasks:
- name: Install PostgreSQL
ansible.builtin.apt:
name: postgresql
state: present
Flow:
Playbook
│
├── Play 1
│ └── webservers
│
└── Play 2
└── dbservers
26. gather_facts
Mặc định, Ansible thường thu thập Facts trước khi chạy tasks.
Ví dụ:
- name: Configure servers
hosts: webservers
tasks:
- name: ...
Ansible sẽ thực hiện bước:
Gathering Facts
↓
Tasks
Facts có thể chứa:
OS
CPU
RAM
Architecture
IP
Hostname
Kernel
Chúng ta sẽ khai thác sâu hơn ở Lab 5.
27. Tắt gather_facts
Nếu Playbook không cần Facts:
- name: Simple command
hosts: webservers
gather_facts: false
tasks:
- name: Check uptime
ansible.builtin.command:
cmd: uptime
Điều này có thể giúp giảm thời gian execution khi Playbook chỉ cần thực hiện những task đơn giản.
28. Kiểm tra Syntax
Trước khi chạy:
ansible-playbook --syntax-check playbook.yml
Nếu đúng:
playbook: playbook.yml
Đây nên trở thành thói quen.
Edit
↓
Syntax Check
↓
Run
29. --check
Có thể thử:
ansible-playbook playbook.yml --check
Ý tưởng:
Normal
↓
Apply changes
Check mode
↓
Predict changes
Không phải task/module nào cũng mô phỏng chính xác trong check mode, nên cần hiểu giới hạn của nó.
30. --diff
Đặc biệt hữu ích khi quản lý file:
ansible-playbook playbook.yml --diff
Ví dụ khi nội dung file thay đổi:
before
↓
after
Ansible có thể hiển thị diff nếu module hỗ trợ.
31. --limit
Không nên ngay lập tức chạy Playbook trên toàn bộ production.
Ví dụ:
ansible-playbook playbook.yml \
--limit web-01
Flow an toàn:
web-01
↓
Verify
↓
web-02
↓
Verify
↓
Remaining
Đặc biệt hữu ích khi deployment.
32. --list-hosts
Trước khi chạy:
ansible-playbook playbook.yml --list-hosts
Ansible sẽ cho biết Playbook sẽ target những host nào.
Đây là một bước kiểm tra rất hữu ích trước production change.
33. --list-tasks
Có thể xem danh sách task:
ansible-playbook playbook.yml --list-tasks
Ví dụ:
playbook: playbook.yml
play #1
TASK: Install nginx
TASK: Create deploy user
TASK: Create application directory
TASK: Deploy index page
TASK: Ensure nginx is running
34. Tags — giới thiệu
Playbook lớn có thể có rất nhiều task.
Ví dụ:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
tags:
- nginx
- packages
Task khác:
- name: Deploy configuration
ansible.builtin.copy:
...
tags:
- config
Sau đó:
ansible-playbook playbook.yml --tags nginx
Tags sẽ được học sâu hơn trong các bài nâng cao, nhưng người học nên biết concept từ bây giờ.
35. register — giới thiệu
Một task có thể lưu output:
- name: Check nginx version
ansible.builtin.command:
cmd: nginx -v
register: nginx_version
changed_when: false
Sau đó:
- name: Show nginx version
ansible.builtin.debug:
var: nginx_version
Flow:
Command
↓
register
↓
Variable
↓
Use later
register, when và variables sẽ được khai thác sâu hơn ở các Lab tiếp theo.
36. changed_when
Một vấn đề với:
- name: Check nginx version
ansible.builtin.command:
cmd: nginx -v
là command có thể được xem là changed.
Nhưng chúng ta chỉ đang kiểm tra.
Có thể viết:
- name: Check nginx version
ansible.builtin.command:
cmd: nginx -v
changed_when: false
Ý nghĩa:
Task này có thể chạy command, nhưng không được xem là thay đổi hệ thống.
Đây là một kỹ thuật quan trọng khi sử dụng command hoặc shell.
37. failed_when
Có thể định nghĩa điều kiện task được xem là failed.
Ví dụ:
- name: Check application health
ansible.builtin.command:
cmd: curl -f http://localhost/health
register: health_check
failed_when: health_check.rc != 0
Điều này cho phép automation hiểu được:
Command result
↓
Business condition
↓
Success / Failure
38. Tại sao không dùng shell cho mọi thứ?
Bạn có thể viết:
- name: Install nginx
ansible.builtin.shell:
cmd: apt install -y nginx
Nhưng đây không phải cách tốt.
Nên viết:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Lý do:
Module
├── Idempotency
├── Structured arguments
├── Better error handling
├── Better check mode support
└── Better intent
Trong khi shell:
Shell
├── Flexible
├── Powerful
└── Easier to misuse
Quy tắc:
Prefer Ansible modules over shell commands whenever a suitable module exists.
39. Debug Playbook
Khi cần xem giá trị:
- name: Show message
ansible.builtin.debug:
msg: "Hello from Ansible"
Hoặc:
- name: Show hostname
ansible.builtin.debug:
var: ansible_hostname
debug sẽ trở thành công cụ rất quan trọng khi chúng ta bắt đầu sử dụng:
- Variables
- Facts
- Templates
- Conditions
- Loops
40. Thực hành — Build Web Server
Bây giờ hãy xây dựng một Web Server đơn giản.
Yêu cầu
Playbook phải:
- Cài Nginx.
- Tạo user
deploy. - Tạo
/opt/myapp. - Tạo
/opt/myapp/index.html. - Deploy HTML vào Nginx.
- Start Nginx.
- Enable Nginx.
41. Chuẩn bị HTML
Tạo:
files/index.html
Nội dung:
<!DOCTYPE html>
<html>
<head>
<title>Ansible Lab 4</title>
</head>
<body>
<h1>Hello from Ansible!</h1>
<p>This server was configured automatically.</p>
</body>
</html>
Cấu trúc:
ansible-lab-04/
├── ansible.cfg
├── inventory.ini
├── playbook.yml
└── files/
└── index.html
42. Playbook thực hành
---
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: Create deploy user
ansible.builtin.user:
name: deploy
state: present
- name: Create application directory
ansible.builtin.file:
path: /opt/myapp
state: directory
owner: deploy
group: deploy
mode: "0755"
- name: Deploy web page
ansible.builtin.copy:
src: files/index.html
dest: /var/www/html/index.html
owner: root
group: root
mode: "0644"
- name: Ensure nginx is running
ansible.builtin.service:
name: nginx
state: started
enabled: true
43. Validate
Syntax:
ansible-playbook --syntax-check playbook.yml
Danh sách host:
ansible-playbook playbook.yml --list-hosts
Danh sách task:
ansible-playbook playbook.yml --list-tasks
Check mode:
ansible-playbook playbook.yml --check
Cuối cùng:
ansible-playbook playbook.yml
44. Verify
Kiểm tra Nginx:
ansible webservers \
-m ansible.builtin.service \
-a "name=nginx"
Kiểm tra user:
ansible webservers \
-m ansible.builtin.command \
-a "id deploy"
Kiểm tra file:
ansible webservers \
-m ansible.builtin.command \
-a "cat /var/www/html/index.html"
Nếu có thể truy cập Web Server:
curl http://<server-ip>
Kết quả:
Hello from Ansible!
45. Exercise 1 — Basic Playbook
Viết Playbook:
basic.yml
Yêu cầu:
Target: webservers
Task 1:
Install curl
Task 2:
Install git
Task 3:
Install nginx
Task 4:
Ensure nginx is running
Không được sử dụng shell.
46. Exercise 2 — User Management
Viết Playbook:
users.yml
Yêu cầu:
Create:
deploy
Create:
/opt/myapp
Owner:
deploy:deploy
Permission:
0755
Sau đó chạy Playbook hai lần.
Quan sát:
changed
và:
ok
47. Exercise 3 — Static Website
Viết Playbook deploy một website HTML.
Yêu cầu:
Install nginx
↓
Copy index.html
↓
Start nginx
↓
Enable nginx
Verify:
curl http://<server-ip>
48. Exercise 4 — Multi Server
Inventory:
[webservers]
web-01
web-02
[appservers]
app-01
Viết Playbook:
webservers
↓
Install nginx
appservers
↓
Install curl
Không được viết hai Playbook riêng.
Sử dụng:
2 Plays
trong cùng một Playbook.
49. Exercise 5 — Safe Deployment
Viết Playbook deploy Nginx.
Trước khi chạy toàn bộ:
ansible-playbook deploy.yml \
--limit web-01
Verify.
Sau đó:
ansible-playbook deploy.yml \
--limit web-02
Verify.
Cuối cùng mới:
ansible-playbook deploy.yml
Mục tiêu của exercise này không chỉ là syntax.
Bạn đang thực hành:
Controlled production change.
50. Exercise 6 — Debugging
Tạo một Playbook cố tình sai:
- name: Test failure
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Start invalid service
ansible.builtin.service:
name: nginx-invalid
state: started
Chạy:
ansible-playbook test.yml
Quan sát:
TASK
↓
FAILED
↓
PLAY RECAP
Xác định:
- Task nào fail?
- Host nào fail?
- Error message là gì?
- Task trước đó có được thực hiện không?
51. Exercise 7 — Production Challenge
Bạn được giao ticket:
"Provision một Web Server mới."
Yêu cầu:
Server
↓
Install nginx
↓
Create deploy user
↓
Create /opt/myapp
↓
Deploy website
↓
Start nginx
↓
Enable nginx
↓
Verify
Constraint:
❌ Không SSH thủ công
❌ Không dùng shell để install/configure nginx
❌ Không chạy từng command bằng tay
✅ Chỉ sử dụng Playbook
Sau khi chạy lần đầu, chạy lại Playbook.
Mục tiêu:
First run
changed > 0
Second run
changed = 0
52. Những lỗi người mới thường gặp
Lỗi 1 — Sai indentation
tasks:
- name: Install nginx
ansible.builtin.apt:
Mặc dù YAML có thể chấp nhận một số dạng indentation, hãy thống nhất style:
tasks:
- name: Install nginx
ansible.builtin.apt:
Lỗi 2 — Quên become
- name: Install nginx
ansible.builtin.apt:
Có thể gặp:
Permission denied
Nếu cần root:
become: true
Lỗi 3 — Sai module
Ví dụ dùng:
ansible.builtin.apt:
trên hệ điều hành không sử dụng APT.
Cần xác định OS trước.
Lỗi 4 — Dùng shell cho mọi thứ
Không nên:
shell: apt install nginx
nếu có:
ansible.builtin.apt:
Lỗi 5 — Không kiểm tra target
Không nên chạy ngay:
ansible-playbook production.yml
Hãy kiểm tra:
ansible-playbook production.yml --list-hosts
53. Workflow tốt khi viết Playbook
Một workflow thực tế:
Requirement
↓
Identify target
↓
Choose Ansible module
↓
Write Playbook
↓
Syntax check
↓
--list-hosts
↓
--check
↓
Run on one host
↓
Verify
↓
Run broader scope
Có thể rút gọn thành:
Write
↓
Validate
↓
Test
↓
Verify
↓
Deploy
Đây là workflow nên hình thành ngay từ khi mới học.
54. Tư duy Senior #1 — Playbook là Code
Đừng xem:
playbook.yml
chỉ là file configuration.
Hãy xem nó là:
Infrastructure Code
Vì vậy Playbook nên:
- Dễ đọc.
- Dễ review.
- Có naming rõ ràng.
- Có version control.
- Có testing.
- Có documentation phù hợp.
- Không chứa secret trực tiếp.
55. Tư duy Senior #2 — Mô tả Intent
Không nên nghĩ:
"Tôi cần chạy command này."
Hãy nghĩ:
"Server cần đạt trạng thái nào?"
Ví dụ:
state: present
thay vì:
apt install nginx
hoặc:
state: started
thay vì:
systemctl start nginx
Đây chính là bước chuyển từ:
Imperative
sang:
Declarative
56. Tư duy Senior #3 — Idempotency
Một Playbook tốt phải có thể chạy nhiều lần.
Ví dụ:
Run #1
↓
Create resource
Run #2
↓
No unnecessary change
Run #3
↓
No unnecessary change
Mục tiêu:
Desired State
↓
=
Actual State
Không nên viết automation mà mỗi lần chạy đều:
restart
recreate
overwrite
change
mà không cần thiết.
57. Tư duy Senior #4 — Không phải mọi task đều cần changed
Ví dụ:
- name: Check nginx version
ansible.builtin.command:
cmd: nginx -v
changed_when: false
Task này:
Read-only
nên không nên báo:
changed
Hãy phân biệt:
Read operation
vs
Write operation
Đây là một chi tiết nhỏ nhưng rất quan trọng khi xây dựng automation lớn.
58. Tư duy Senior #5 — Giảm Blast Radius
Nếu có:
100 production servers
không nên mặc định:
Change 100 servers
Có thể:
1 server
↓
Verify
↓
5 servers
↓
Verify
↓
25 servers
↓
Verify
↓
100 servers
Đây chính là tư duy:
Progressive rollout
Sau này chúng ta sẽ dùng các cơ chế như:
serialstrategymax_fail_percentage
để kiểm soát deployment.
59. Tư duy Senior #6 — Playbook phải có khả năng đọc hiểu
Không nên:
- name: Do thing
Nên:
- name: Ensure nginx is installed
Không nên:
- name: Execute command
Nên:
- name: Check nginx service status
Một năm sau, chính bạn hoặc đồng đội sẽ phải đọc lại code này.
60. Tư duy Senior #7 — Automation không có nghĩa là chạy càng nhiều càng tốt
Một automation tốt không phải:
1000 lines
mà là:
Clear
+
Predictable
+
Idempotent
+
Reusable
+
Safe
Mục tiêu cuối cùng không phải:
"Ansible chạy được."
Mà là:
"Infrastructure có thể được quản lý một cách đáng tin cậy bằng code."
61. Kiến thức cần ghi nhớ
Sau Lab 4, người học cần nắm chắc:
Playbook
│
├── Play
│ ├── hosts
│ ├── become
│ ├── vars
│ └── tasks
│
└── Tasks
└── Modules
Và workflow:
Inventory
↓
Playbook
↓
Module
↓
Desired State
↓
Managed Node
62. Cheat Sheet
Chạy Playbook
ansible-playbook playbook.yml
Syntax check
ansible-playbook playbook.yml --syntax-check
Check mode
ansible-playbook playbook.yml --check
Diff
ansible-playbook playbook.yml --diff
Xem host
ansible-playbook playbook.yml --list-hosts
Xem task
ansible-playbook playbook.yml --list-tasks
Giới hạn host
ansible-playbook playbook.yml --limit web-01
Tags
ansible-playbook playbook.yml --tags nginx
63. Checklist hoàn thành Lab 4
- [ ] Hiểu Playbook là gì.
- [ ] Hiểu sự khác nhau giữa Ad-Hoc và Playbook.
- [ ] Hiểu Play.
- [ ] Hiểu Task.
- [ ] Biết sử dụng
hosts. - [ ] Biết sử dụng
become. - [ ] Biết sử dụng module trong Playbook.
- [ ] Viết được Playbook nhiều task.
- [ ] Viết được nhiều Play trong một Playbook.
- [ ] Hiểu
okvàchanged. - [ ] Hiểu Idempotency.
- [ ] Biết
--syntax-check. - [ ] Biết
--check. - [ ] Biết
--diff. - [ ] Biết
--limit. - [ ] Biết
--list-hosts. - [ ] Biết
--list-tasks. - [ ] Biết sử dụng
debug. - [ ] Biết cơ bản về
register. - [ ] Biết cơ bản về
changed_when. - [ ] Biết khi nào nên dùng module thay vì
shell. - [ ] Có thể viết một Playbook provision Web Server đơn giản.
64. Tổng kết Lab 4
Ở các Lab trước, chúng ta có:
Lab 1
Ansible Fundamentals
↓
Lab 2
Inventory & SSH
↓
Lab 3
Ad-Hoc Commands
Đến Lab 4:
Ad-Hoc
│
│ "Run this command"
▼
Playbook
│
│ "Make the server look like this"
▼
Desired State
Đây là bước ngoặt quan trọng nhất của giai đoạn Ansible Fundamentals.
Từ đây, người học không chỉ biết:
ansible <host> -m <module>
mà bắt đầu biết:
Infrastructure
↓
Code
↓
Playbook
↓
Repeatable Automation
Và ở Lab 5 — Ansible Variables & Facts, chúng ta sẽ giải quyết một vấn đề mới:
Playbook hiện tại đang hard-code rất nhiều giá trị.
Ví dụ:
name: nginx
path: /opt/myapp
user: deploy
Nhưng thực tế:
Development
↓
user = dev
Staging
↓
user = staging
Production
↓
user = deploy
Hay:
Ubuntu
↓
apt
RHEL
↓
dnf
Lúc này chúng ta cần Variables + Facts để Playbook có thể tự thích nghi với từng server và từng environment.
Lab 4
Playbook
↓
Hard-coded Automation
Lab 5
Variables + Facts
↓
Dynamic Automation
Đây sẽ là nền tảng để bước sang Templates, Handlers, Roles và cuối cùng là Production-grade Ansible Automation.
All rights reserved