Lab 12 — Ansible Troubleshooting
Mục tiêu: Sau Lab này, người học không chỉ biết viết Playbook mà còn có thể đọc lỗi, debug, tìm root cause và khắc phục deployment failure trong môi trường thực tế.
Đây là Lab rất quan trọng trong roadmap từ Beginner → Senior.
Ở các Lab trước, chúng ta chủ yếu học:
Viết Ansible
↓
Chạy Ansible
↓
Server được cấu hình
Nhưng production thực tế thường là:
Viết Playbook
↓
Run
↓
❌ FAILED
↓
Debug
↓
Find Root Cause
↓
Fix
↓
Run lại
↓
✅ SUCCESS
Senior DevOps/Infrastructure Engineer không phải người không gặp lỗi, mà là người có khả năng tìm lỗi nhanh và xác định đúng nguyên nhân.
1. Bối cảnh
Giả sử chúng ta có hệ thống:
Ansible Controller
│
│ SSH
▼
┌─────────────────┐
│ Production │
│ Server │
│ │
│ Docker │
│ PostgreSQL │
│ Todo API │
└─────────────────┘
Playbook:
ansible-playbook site.yml
Có thể gặp:
SSH connection failed
Permission denied
Package not found
Service failed
Template error
Variable undefined
Docker error
Port already in use
File permission denied
Handler không chạy
Task chạy nhưng application vẫn chết
Mục tiêu của Lab:
Học một quy trình troubleshooting có hệ thống, thay vì sửa lỗi bằng cách thử ngẫu nhiên.
2. Mục tiêu Lab
Sau Lab này, người học có thể:
- Đọc Ansible error.
- Phân biệt
UNREACHABLEvàFAILED. - Sử dụng
-v,-vv,-vvv,-vvvv. - Debug variables.
- Kiểm tra Inventory.
- Kiểm tra SSH.
- Kiểm tra privilege escalation.
- Debug
undefined variable. - Debug Jinja2 Template.
- Debug package installation.
- Debug service.
- Debug Docker.
- Debug Handler.
- Debug permissions.
- Debug networking.
- Debug application deployment.
- Sử dụng
check mode. - Sử dụng
diff mode. - Kiểm tra Playbook trước khi chạy.
- Debug từng host.
- Debug từng task.
- Xây dựng troubleshooting workflow.
- Biết cách tìm root cause thay vì chỉ xử lý symptom.
3. Nguyên tắc quan trọng nhất
Khi Playbook fail:
Đừng sửa ngay. Hãy đọc lỗi trước.
Ví dụ:
fatal: [server01]: FAILED!
Không có nghĩa:
Ansible bị lỗi
Mà có thể là:
Ansible
│
▼
Task
│
▼
Command
│
▼
Operating System
│
▼
Application
Lỗi có thể nằm ở bất kỳ layer nào.
4. Troubleshooting theo Layer
Một cách tư duy rất tốt:
Layer 1
Ansible Controller
│
▼
Layer 2
Inventory
│
▼
Layer 3
SSH
│
▼
Layer 4
Privilege
│
▼
Layer 5
OS / Package
│
▼
Layer 6
Service
│
▼
Layer 7
Docker
│
▼
Layer 8
Application
│
▼
Layer 9
Network
Không nên nhảy thẳng đến Layer 8 khi chưa biết Layer 3 có hoạt động hay không.
5. Bước 1 — Kiểm tra Syntax
Trước tiên:
ansible-playbook site.yml --syntax-check
Nếu đúng:
playbook: site.yml
Nếu sai YAML:
ERROR! We were unable to read either as JSON nor YAML
6. YAML Error
Ví dụ:
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
Indentation sai.
Chạy:
ansible-playbook site.yml --syntax-check
Có thể nhận:
mapping values are not allowed here
Cách xử lý
Không đoán.
Kiểm tra:
line number
column
task name
Sau đó kiểm tra indentation.
7. Bước 2 — Kiểm tra Inventory
Chạy:
ansible-inventory -i inventory/hosts.ini --graph
Ví dụ:
@all:
|--@application:
| |--server01
|--@database:
| |--server02
Nếu Inventory sai:
Playbook
↓
Wrong Host
↓
Everything fails
8. Xem toàn bộ Inventory
ansible-inventory \
-i inventory/hosts.ini \
--list
Output có thể rất dài.
Dùng:
ansible-inventory \
-i inventory/hosts.ini \
--list \
| jq
nếu máy có jq.
9. Test Connectivity
Đây là một trong những command quan trọng nhất:
ansible all \
-i inventory/hosts.ini \
-m ansible.builtin.ping
Expected:
server01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Nếu:
server01 | UNREACHABLE!
thì chưa cần debug Playbook.
Hãy debug SSH trước.
10. UNREACHABLE vs FAILED
Đây là distinction rất quan trọng.
UNREACHABLE
Ansible
│
X
│
Server
Ansible không kết nối được server.
Ví dụ:
SSH timeout
Connection refused
Permission denied
Host not found
FAILED
Ansible
│
▼
Server
│
▼
Task
│
X
Đã kết nối được nhưng task fail.
11. Debug SSH
Nếu:
ansible all -m ping
fail:
Permission denied (publickey)
thử SSH trực tiếp:
ssh deploy@server01
Nếu SSH cũng fail:
Vấn đề không nằm ở Ansible.
12. Kiểm tra SSH Verbose
ssh -vvv deploy@server01
Đây là command cực kỳ hữu ích.
Bạn có thể thấy:
Offering public key
Authenticating
Server refused key
Từ đó xác định:
SSH key
User
Permission
sshd
13. Kiểm tra Ansible SSH
Chạy:
ansible server01 \
-i inventory/hosts.ini \
-m ping \
-vvv
-vvv giúp nhìn thấy nhiều thông tin hơn.
14. Verbosity Levels
Normal
ansible-playbook site.yml
-v
ansible-playbook site.yml -v
-vv
ansible-playbook site.yml -vv
-vvv
ansible-playbook site.yml -vvv
-vvvv
ansible-playbook site.yml -vvvv
Thông thường:
Normal → -v → -vv → -vvv
là đủ.
-vvvv thường dùng khi cần debug sâu connection/SSH.
15. Bước 3 — Kiểm tra User
Trong Inventory:
[application]
server01 ansible_user=deploy
Nhưng server có thể không có:
deploy
Test:
ssh deploy@server01
Hoặc:
ansible server01 \
-m command \
-a "whoami"
Expected:
deploy
16. Debug become
Ví dụ task:
- name: Install Docker
become: true
ansible.builtin.apt:
name: docker.io
state: present
Nếu:
Missing sudo password
hoặc:
deploy is not in the sudoers file
thì vấn đề là privilege escalation.
17. Test sudo
SSH vào server:
ssh deploy@server01
Sau đó:
sudo whoami
Expected:
root
Nếu không:
sudo configuration
cần được kiểm tra.
18. Debug Variable
Một lỗi rất phổ biến:
'database_host' is undefined
Ví dụ:
- name: Show database host
ansible.builtin.debug:
var: database_host
Nếu variable tồn tại:
database_host: "postgres"
Nếu không:
VARIABLE IS NOT DEFINED
19. Debug nhiều Variables
Có thể:
- name: Debug application config
ansible.builtin.debug:
msg:
- "Environment: {{ app_environment }}"
- "Port: {{ application_port }}"
- "Host: {{ application_host }}"
Không làm điều này với secret.
Không:
- debug:
var: postgres_password
20. Debug Variable Type
Đôi khi variable tồn tại nhưng sai kiểu.
Ví dụ:
application_port: "8080"
thay vì:
application_port: 8080
Debug:
- name: Debug variable type
ansible.builtin.debug:
msg:
- "value={{ application_port }}"
- "type={{ application_port | type_debug }}"
Output:
value=8080
type=str
hoặc:
type=int
Đây là kỹ thuật rất hữu ích khi debug Jinja2.
21. Bước 4 — Kiểm tra Facts
Chạy:
ansible server01 \
-m ansible.builtin.setup
Có rất nhiều information:
ansible_hostname
ansible_distribution
ansible_os_family
ansible_memtotal_mb
ansible_processor_vcpus
ansible_default_ipv4
22. Debug OS
- name: Show OS
ansible.builtin.debug:
msg:
- "OS: {{ ansible_distribution }}"
- "Version: {{ ansible_distribution_version }}"
- "Architecture: {{ ansible_architecture }}"
Ví dụ:
OS: Ubuntu
Version: 24.04
Architecture: aarch64
23. Một lỗi thực tế
Bạn viết:
ansible.builtin.apt:
name: nginx
Nhưng target server là:
CentOS
Task fail.
Root cause:
Wrong package manager
Cần thiết kế:
Debian / Ubuntu
↓
apt
RHEL / CentOS
↓
dnf
24. Bước 5 — Debug Package
Ví dụ:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Nếu fail:
Unable to locate package nginx
Không nên ngay lập tức đổi package.
Kiểm tra:
apt update
hoặc:
apt-cache policy nginx
25. Debug bằng Ad-Hoc
Đây là lúc kiến thức Lab 3 — Ad-Hoc Commands trở nên rất hữu ích.
Ví dụ:
ansible server01 \
-m command \
-a "uname -a"
ansible server01 \
-m command \
-a "df -h"
ansible server01 \
-m command \
-a "free -m"
ansible server01 \
-m command \
-a "docker ps"
Ansible Ad-Hoc trở thành một công cụ troubleshooting.
26. Bước 6 — Debug Service
Ví dụ:
- name: Start nginx
ansible.builtin.service:
name: nginx
state: started
Task có thể báo:
Could not start service nginx
Không dừng ở đây.
SSH vào server:
systemctl status nginx
27. Đọc Systemd Logs
journalctl -u nginx
Hoặc:
journalctl -u nginx -n 100
Theo dõi realtime:
journalctl -u nginx -f
Đây mới có thể chứa root cause.
Ví dụ:
bind() failed: Address already in use
28. Port Already in Use
Nếu:
nginx failed to start
kiểm tra:
ss -lntp
hoặc:
sudo lsof -i :80
Có thể phát hiện:
docker-proxy
đang chiếm port 80.
Root cause:
Port conflict
không phải:
Ansible bug
29. Bước 7 — Debug Template
Một lỗi rất phổ biến:
template error
Ví dụ:
server {
listen {{ application_port }};
server_name {{ application_domain }};
}
nhưng:
application_domain
không tồn tại.
Ansible báo:
' application_domain ' is undefined
30. Validate Template
Có thể chạy:
ansible-playbook site.yml --check
Nếu template có lỗi, thường sẽ phát hiện trước khi thay đổi hệ thống.
31. Kiểm tra Rendered File
Có thể tạo task tạm thời:
- name: Show rendered config
ansible.builtin.command:
cmd: cat /etc/nginx/conf.d/todo.conf
Nhưng production không nên để những task debug này tồn tại lâu dài.
32. Sử dụng --diff
Chạy:
ansible-playbook site.yml --check --diff
Đây là command rất hữu ích.
Ansible có thể cho biết:
- old configuration
+ new configuration
Giúp xác định:
Ansible đang định thay đổi cái gì?
33. --check
ansible-playbook site.yml --check
Đây là check mode.
Ansible cố gắng mô phỏng thay đổi mà không thực hiện đầy đủ thay đổi.
Ví dụ:
Task
↓
Check
↓
Would change
Rất hữu ích trước production deployment.
34. Nhưng --check không phải hoàn hảo
Một số module hoặc command:
ansible.builtin.command
không thể mô phỏng đầy đủ.
Ngoài ra:
Application runtime
External API
Database state
có thể không được kiểm tra hoàn toàn.
Do đó:
--checklà một lớp kiểm tra, không phải guarantee deployment sẽ thành công.
35. Bước 8 — Debug Docker
Ví dụ:
- name: Start application
community.docker.docker_compose_v2:
project_src: /opt/todo
state: present
Task fail.
Không chỉ xem Ansible.
Kiểm tra:
docker compose ps
Sau đó:
docker compose logs
36. Debug từng Container
docker ps -a
Ví dụ:
todo-api Exited (1)
postgres Up
nginx Up
Sau đó:
docker logs todo-api
Root cause có thể:
DATABASE_URL invalid
Connection refused
Missing environment variable
Port conflict
Migration failed
37. Debug Environment
Kiểm tra:
docker inspect todo-api
Nhưng phải cẩn thận:
docker inspectcó thể hiển thị secret.
Không copy output có password vào ticket, Slack, GitHub hoặc log.
38. Debug Network
Nếu application không connect database:
Todo API
│
X
│
PostgreSQL
Kiểm tra:
docker network ls
Sau đó:
docker network inspect <network>
Kiểm tra:
Container
Network
IP
Aliases
39. Debug DNS trong Docker
Từ container:
docker exec todo-api getent hosts postgres
Nếu:
postgres
resolve được:
172.x.x.x postgres
thì DNS hoạt động.
Nếu không:
Network / service name
cần được kiểm tra.
40. Debug Database Connection
Ví dụ:
docker exec todo-api \
sh -c 'nc -zv postgres 5432'
Nếu thành công:
Connection succeeded
Nếu fail:
Connection refused
cần kiểm tra PostgreSQL.
41. Debug Application
Một Playbook có thể:
SUCCESS
nhưng application:
❌ 500 Internal Server Error
Đây là một distinction rất quan trọng.
Ansible SUCCESS
≠
Application HEALTHY
42. Health Check
Sau deployment:
- name: Check application health
ansible.builtin.uri:
url: "http://localhost:8080/health"
status_code: 200
Nếu:
200
→ deployment có vẻ healthy.
Nếu:
500
→ Ansible nên fail.
Đây là tư duy deployment verification.
43. Bước 9 — Debug Handler
Ví dụ:
- name: Update nginx config
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
Handler:
handlers:
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
Nếu config thay đổi:
Task changed
↓
notify
↓
handler
44. Nếu Handler không chạy
Kiểm tra:
1. Task có changed không?
Nếu:
ok
thì handler không chạy.
Nếu:
changed
thì handler được notify.
2. Tên Handler có đúng không?
notify: Restart nginx
phải match:
- name: Restart nginx
45. Handler chỉ chạy cuối Play
Thông thường:
Task 1
Task 2
Task 3
Task 4
↓
Handlers
Không phải:
Task 2
↓
Handler
↓
Task 3
Nếu cần handler chạy ngay:
- meta: flush_handlers
Nhưng không nên lạm dụng.
46. Bước 10 — Debug Permission
Một lỗi rất phổ biến:
Permission denied
Ví dụ:
ansible.builtin.template:
src: app.conf.j2
dest: /opt/todo/app.conf
Nếu user không có quyền:
Permission denied
Kiểm tra:
ls -ld /opt/todo
và:
ls -l /opt/todo
47. Kiểm tra User
whoami
id
groups
Ví dụ:
deploy
không thuộc:
docker
thì:
docker ps
có thể fail.
48. Docker Permission
Nếu:
permission denied while trying to connect to Docker daemon
kiểm tra:
groups
Có:
docker
không?
Nếu không:
sudo usermod -aG docker deploy
Sau đó user cần đăng nhập session mới để group membership có hiệu lực.
49. Bước 11 — Debug Disk
Deployment có thể fail vì:
No space left on device
Kiểm tra:
df -h
và:
df -i
Đây là một lỗi production rất thực tế.
50. Debug Memory
free -m
Hoặc:
docker stats
Có thể application chết vì:
OOMKilled
51. Debug CPU
top
hoặc:
htop
Docker:
docker stats
Nếu deployment rất chậm:
CPU
Memory
Disk I/O
Network
đều cần được xem xét.
52. Bước 12 — Debug bằng --limit
Nếu Inventory có:
server01
server02
server03
server04
không cần chạy toàn bộ.
ansible-playbook site.yml \
--limit server01
Chỉ debug:
server01
53. Debug một Group
ansible-playbook site.yml \
--limit application
Rất hữu ích trong production.
Ví dụ:
100 servers
không nên test bằng:
ansible-playbook site.yml
ngay lập tức.
54. Debug một Task
Dùng tags:
- name: Install Docker
tags:
- docker
Chạy:
ansible-playbook site.yml \
--tags docker
Chỉ test phần Docker.
55. Skip Task
ansible-playbook site.yml \
--skip-tags docker
Có thể dùng khi muốn cô lập vấn đề.
56. Step-by-Step Execution
Ansible hỗ trợ:
ansible-playbook site.yml --step
Ansible sẽ hỏi trước task.
Ví dụ:
Perform task: Install Docker? (N)o/(y)es/(c)ontinue
Rất hữu ích khi học và debug.
Không nên dùng thường xuyên trong automation production.
57. assert
Một kỹ thuật rất tốt để fail sớm:
- name: Validate configuration
ansible.builtin.assert:
that:
- application_port is defined
- application_domain is defined
- app_environment is defined
fail_msg: "Required application variables are missing"
Thay vì:
Deploy
↓
Template fail
↓
Debug khó
ta có:
Validate
↓
Fail immediately
↓
Clear error
58. Validate Port
- name: Validate application port
ansible.builtin.assert:
that:
- application_port | int > 0
- application_port | int < 65536
fail_msg: "Invalid application_port"
59. Validate Environment
- name: Validate environment
ansible.builtin.assert:
that:
- app_environment in ['dev', 'staging', 'production']
Nếu:
app_environment=prod
thì fail.
Điều này giúp tránh typo.
60. Debug với register
Ví dụ:
- name: Check Docker version
ansible.builtin.command:
cmd: docker --version
register: docker_version
changed_when: false
Sau đó:
- name: Show Docker version
ansible.builtin.debug:
var: docker_version.stdout
Output:
Docker version 28.x
61. Hiểu register
Command
│
▼
register
│
▼
Variable
│
├── stdout
├── stderr
├── rc
└── changed
Ví dụ:
docker_version.rc
docker_version.stdout
docker_version.stderr
62. failed_when
Có thể custom điều kiện fail:
- name: Check application
ansible.builtin.command:
cmd: curl -fs http://localhost:8080/health
register: health
failed_when: health.rc != 0
63. changed_when
Một command chỉ để kiểm tra:
- name: Check Docker version
ansible.builtin.command:
cmd: docker --version
changed_when: false
Nếu không:
changed
có thể làm Playbook report sai.
64. Debug Command Failure
Ví dụ:
- name: Run migration
ansible.builtin.command:
cmd: ./migration.sh
register: migration
Sau đó:
- name: Show migration output
ansible.builtin.debug:
msg:
- "RC: {{ migration.rc }}"
- "STDOUT: {{ migration.stdout }}"
- "STDERR: {{ migration.stderr }}"
Không dùng cách này nếu output có secret.
65. Root Cause vs Symptom
Đây là phần quan trọng nhất của Lab.
Ví dụ:
Ansible:
FAILED - nginx failed to start
Đây chỉ là:
Symptom
Tiếp tục:
systemctl status nginx
thấy:
Address already in use
Đây mới là:
Root Cause
Tiếp:
ss -lntp
thấy:
Docker container chiếm port 80
Root cause cuối:
Port 80 conflict between nginx and Docker
66. Troubleshooting Tree
Khi Playbook fail:
Playbook FAILED
│
┌────────┴────────┐
│ │
UNREACHABLE FAILED
│ │
▼ ▼
SSH Task
│ │
┌─────┴─────┐ ┌────┴────┐
│ │ │ │
User Key Variable Command
│ │ │ │
sudo network template service
67. Troubleshooting Workflow
Hãy hình thành thói quen:
1. Read Error
↓
2. Identify Layer
↓
3. Reproduce
↓
4. Isolate
↓
5. Inspect
↓
6. Find Root Cause
↓
7. Fix
↓
8. Re-run
↓
9. Verify
68. Không nên làm như thế này
Playbook fail
↓
Sửa random
↓
Run
↓
Fail
↓
Sửa random
↓
Run
↓
Fail
Đây là:
Trial-and-error troubleshooting
Không scale được.
69. Nên làm như thế này
Failure
↓
Read exact error
↓
Classify
↓
Reproduce outside Ansible
↓
Inspect system
↓
Root Cause
↓
Minimal Fix
↓
Verify
Ví dụ:
nginx failed
↓
systemctl status nginx
↓
Address already in use
↓
ss -lntp
↓
Docker owns :80
↓
Port conflict
↓
Change port architecture
70. Lab Challenge 1 — SSH Failure
Cố tình cấu hình sai:
server01 ansible_user=wronguser
Chạy:
ansible server01 -m ping
Kỳ vọng:
UNREACHABLE
Nhiệm vụ:
- Đọc lỗi.
- SSH trực tiếp.
- Kiểm tra user.
- Sửa Inventory.
- Test lại.
71. Lab Challenge 2 — Wrong SSH Key
Cấu hình sai:
ansible_ssh_private_key_file=wrong-key
Chạy:
ansible server01 -m ping
Debug:
ansible server01 -m ping -vvv
Sau đó:
ssh -vvv deploy@server01
Mục tiêu:
Phân biệt vấn đề Ansible và vấn đề SSH.
72. Lab Challenge 3 — Undefined Variable
Xóa:
application_port: 8080
Sau đó chạy:
ansible-playbook site.yml
Expected:
'application_port' is undefined
Fix bằng:
assert
để error rõ ràng hơn.
73. Lab Challenge 4 — Template Error
Cố tình viết:
server_name {{ application_domain }};
nhưng không khai báo:
application_domain
Chạy:
ansible-playbook site.yml
Debug:
ansible-playbook site.yml -vv
Sau đó bổ sung variable.
74. Lab Challenge 5 — Permission Error
Cố tình deploy:
/etc/myapp/config.yml
bằng user không có quyền.
Quan sát:
Permission denied
Sau đó xác định:
whoami
id
ls -ld /etc/myapp
và sửa bằng:
become: true
nếu phù hợp.
75. Lab Challenge 6 — Service Failure
Cố tình tạo nginx config sai.
Deploy:
ansible-playbook site.yml
Kỳ vọng:
nginx restart failed
Không sửa ngay.
Thực hiện:
systemctl status nginx
nginx -t
journalctl -u nginx -n 100
Tìm root cause.
76. Lab Challenge 7 — Docker Failure
Cố tình đổi:
DATABASE_HOST=wrong-host
Deploy application.
Sau đó:
docker compose ps
docker compose logs todo-api
Tìm:
Database connection failure
Sau đó kiểm tra:
docker network inspect
và sửa configuration.
77. Lab Challenge 8 — Port Conflict
Cho nginx sử dụng:
80
và Docker:
80
Deploy.
Kỳ vọng:
Address already in use
Tìm process:
ss -lntp
Xác định:
Who owns port 80?
Sau đó thiết kế lại port mapping.
78. Lab Challenge 9 — Disk Full
Giả lập:
disk gần đầy
Sau đó chạy deployment.
Kiểm tra:
df -h
df -i
Mục tiêu:
Phân biệt application failure với infrastructure capacity problem.
79. Lab Challenge 10 — Application Health Failure
Cho application start thành công nhưng:
GET /health
trả:
500
Ansible vẫn có thể báo:
changed
Nhiệm vụ:
Thêm:
ansible.builtin.uri
để deployment fail nếu application không healthy.
80. Lab Challenge 11 — Handler Failure
Tạo:
nginx.conf
sai.
Task:
template
notify:
Restart nginx
Theo dõi:
Task
↓
Changed
↓
Handler
↓
Restart
↓
Failed
Debug:
systemctl status nginx
journalctl -u nginx
81. Lab Challenge 12 — Production Incident
Đây là bài quan trọng nhất.
Giả sử:
02:00 AM
CI/CD chạy:
ansible-playbook production.yml
Output:
server01 SUCCESS
server02 SUCCESS
server03 FAILED
server04 SUCCESS
Application trên server03:
HTTP 500
Nhiệm vụ:
Tìm nguyên nhân.
Không được:
reinstall server
restart everything
delete Docker
Phải đi theo quy trình:
1. Identify affected server
2. Check Ansible error
3. SSH
4. Check service
5. Check logs
6. Check Docker
7. Check network
8. Check disk/memory
9. Identify root cause
10. Fix minimal component
11. Verify application
82. Production Incident Example
Giả sử Ansible báo:
TASK [Restart nginx]
fatal: [server03]: FAILED!
Đừng kết luận:
Ansible lỗi
Kiểm tra:
systemctl status nginx
Kết quả:
nginx.service failed
Tiếp:
nginx -t
Kết quả:
duplicate listen options for 0.0.0.0:80
Root cause:
Generated configuration duplicated listen directive
Không phải:
SSH
Ansible
systemd
83. Debug Checklist
Khi gặp lỗi, hãy đi theo checklist này:
[ ] 1. Read exact error
[ ] 2. Identify affected host
[ ] 3. Is it UNREACHABLE or FAILED?
[ ] 4. Test SSH
[ ] 5. Check user
[ ] 6. Check sudo/become
[ ] 7. Check variables
[ ] 8. Check facts
[ ] 9. Check template
[ ] 10. Check package
[ ] 11. Check service
[ ] 12. Check logs
[ ] 13. Check Docker
[ ] 14. Check network
[ ] 15. Check disk
[ ] 16. Check memory
[ ] 17. Check application
[ ] 18. Verify health
84. Bộ Command cần nhớ
Syntax
ansible-playbook site.yml --syntax-check
Inventory
ansible-inventory -i inventory/hosts.ini --graph
Connectivity
ansible all -m ping
Verbose
ansible-playbook site.yml -vvv
Check
ansible-playbook site.yml --check
Diff
ansible-playbook site.yml --check --diff
Limit
ansible-playbook site.yml --limit server01
Tags
ansible-playbook site.yml --tags docker
Facts
ansible server01 -m setup
85. Các command Linux cần kết hợp
Ansible troubleshooting không thể chỉ dùng Ansible.
Người học cần thành thạo:
ssh
systemctl
journalctl
ss
lsof
df
du
free
top
ps
docker
docker compose
curl
ping
getent
dig
Đây chính là lý do các Lab trước về Linux, SSH, Docker và Application Deployment rất quan trọng.
86. Tư duy Senior — Automation phải có khả năng tự kiểm tra
Playbook tốt không chỉ:
Install
Configure
Start
mà nên:
Validate
↓
Install
↓
Configure
↓
Restart
↓
Health Check
↓
Verify
Ví dụ:
- name: Validate nginx config
ansible.builtin.command:
cmd: nginx -t
changed_when: false
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
- name: Verify nginx
ansible.builtin.uri:
url: http://localhost
status_code: 200
87. Tư duy Senior — Fail Fast
Thay vì:
Deploy 20 tasks
↓
Task 20 fail
nên:
Validate configuration
↓
❌
Fail immediately
Ví dụ:
- name: Validate environment
ansible.builtin.assert:
that:
- app_environment is defined
- application_port is defined
88. Tư duy Senior — Minimize Blast Radius
Nếu production có:
100 servers
không nên:
ansible-playbook production.yml
và thay đổi cả 100 server ngay lập tức.
Có thể:
1 server
↓
verify
↓
5 servers
↓
verify
↓
20 servers
↓
verify
↓
100 servers
Đây là tư duy progressive rollout.
89. Tư duy Senior — Troubleshooting không phải chỉ là sửa lỗi
Một Senior sau khi fix phải hỏi:
Tại sao lỗi xảy ra?
và:
Tại sao hệ thống không phát hiện lỗi sớm hơn?
Ví dụ:
Nginx config sai
↓
Deployment failed
Junior:
Sửa config
Senior:
Sửa config
+
nginx -t trước restart
+
CI syntax validation
+
Ansible assert
+
health check
+
prevent regression
90. Sau Incident cần cải thiện Automation
Một incident tốt nên tạo ra:
Incident
↓
Root Cause Analysis
↓
Fix
↓
Automation Improvement
↓
Prevention
Ví dụ:
Database connection failed
Sau incident:
- name: Check database connectivity
...
được thêm vào deployment.
Lần sau:
Database unavailable
↓
Ansible detects
↓
Fail early
91. Bài tập tổng hợp cuối Lab
Xây dựng một Playbook:
production.yml
có pipeline:
START
│
▼
Validate Variables
│
▼
Check SSH
│
▼
Install Dependencies
│
▼
Deploy Configuration
│
▼
Validate Config
│
▼
Restart Service
│
▼
Health Check
│
┌─────┴─────┐
│ │
PASS FAIL
│ │
▼ ▼
SUCCESS Debug
Yêu cầu:
- Có
assert. - Có
register. - Có
changed_when. - Có
failed_whenkhi phù hợp. - Có
no_logcho secret. - Có health check.
- Có handler.
- Có template.
- Có Docker.
- Có troubleshooting documentation.
92. Deliverable
Sau Lab 12, người học cần có:
ansible-lab-12/
│
├── ansible.cfg
├── production.yml
│
├── inventory/
│ └── hosts.ini
│
├── group_vars/
│ ├── all.yml
│ └── vault.yml
│
├── roles/
│ └── application/
│ ├── defaults/
│ ├── handlers/
│ ├── tasks/
│ └── templates/
│
└── TROUBLESHOOTING.md
Trong TROUBLESHOOTING.md cần ghi lại ít nhất:
1. SSH failure
2. Permission failure
3. Variable failure
4. Template failure
5. Service failure
6. Docker failure
7. Network failure
8. Health check failure
9. Disk failure
10. Memory failure
Mỗi issue phải có:
Symptom
↓
Error
↓
Investigation
↓
Root Cause
↓
Fix
↓
Prevention
93. Kết quả đạt được
Sau Lab 12, người học không còn chỉ có tư duy:
Ansible = chạy Playbook
mà bắt đầu có tư duy:
Automation Engineer
│
┌───────────┴───────────┐
│ │
Deploy Troubleshoot
│ │
▼ ▼
Automation Root Cause
│ │
└───────────┬───────────┘
▼
Reliable System
Đây là một mốc rất quan trọng trong roadmap Beginner → Senior.
94. Liên kết với các Lab trước
Toàn bộ kiến thức đến đây bắt đầu kết nối thành một hệ thống:
Lab 1
Ansible Fundamentals
↓
Lab 2
Inventory & SSH
↓
Lab 3
Ad-Hoc
↓
Lab 4
Playbook
↓
Lab 5
Variables & Facts
↓
Lab 6
Jinja2
↓
Lab 7
Handlers & Idempotency
↓
Lab 8
Roles
↓
Lab 9
Server Provisioning
↓
Lab 10
Application Deployment
↓
Lab 11
Secrets & Vault
↓
Lab 12
Troubleshooting
Lab 12 là điểm chuyển rất rõ từ "học Ansible" sang "vận hành hệ thống bằng Ansible".
Và từ đây, Lab 13 — Ansible với nhiều Environment (Dev / Staging / Production) nên tập trung vào một vấn đề production quan trọng hơn nữa: làm sao dùng cùng một automation codebase nhưng triển khai an toàn cho nhiều môi trường, tránh việc cấu hình của Production bị lẫn với Dev/Staging.
All Rights Reserved