- Tác giả

- Name
- Nguyễn Đức Xinh
- Ngày xuất bản
- Ngày xuất bản
Error Handling và Debugging trong Ansible: Hướng dẫn xử lý lỗi và troubleshooting hiệu quả
Giới thiệu
Khi làm việc với Ansible, bạn sẽ không tránh khỏi việc gặp lỗi - từ lỗi cú pháp đơn giản đến lỗi logic phức tạp. Khả năng xử lý lỗi hiệu quả và debug nhanh chóng là kỹ năng quan trọng giúp bạn trở thành một Ansible engineer chuyên nghiệp.
Trong bài này, chúng ta sẽ học cách:
- Xử lý lỗi một cách chủ động trong playbook
- Sử dụng các công cụ debug có sẵn
- Áp dụng các kỹ thuật troubleshooting hiệu quả
1. Hiểu về Error Handling trong Ansible
1.1 Hành vi mặc định khi có lỗi
Mặc định, khi một task fail, Ansible sẽ:
- Dừng thực thi playbook trên host đó
- Tiếp tục chạy trên các host khác (nếu có)
- Báo lỗi và exit với status code khác 0
---
- name: Demo lỗi mặc định
hosts: webservers
tasks:
- name: Task này sẽ fail
command: /bin/false
- name: Task này sẽ không chạy
debug:
msg: "Bạn sẽ không thấy message này"
1.2 Ignore Errors - Bỏ qua lỗi
Sử dụng ignore_errors: yes khi bạn biết task có thể fail nhưng muốn tiếp tục:
- name: Kiểm tra service có tồn tại không
command: systemctl status httpd
register: service_status
ignore_errors: yes
- name: Cài đặt nếu chưa có
yum:
name: httpd
state: present
when: service_status.rc != 0
Lưu ý: Chỉ dùng ignore_errors khi bạn thực sự hiểu tại sao lỗi xảy ra và nó không ảnh hưởng đến logic playbook.
2. Kiểm soát Error với Failed_when
2.1 Định nghĩa điều kiện fail tùy chỉnh
failed_when cho phép bạn quyết định khi nào task được coi là fail:
- name: Kiểm tra disk space
shell: df -h / | tail -1 | awk '{print $5}' | sed 's/%//'
register: disk_usage
failed_when: disk_usage.stdout|int > 80
- name: Chạy script và kiểm tra output
script: /tmp/check_health.sh
register: health_check
failed_when: "'ERROR' in health_check.stdout"
2.2 Ví dụ thực tế: Kiểm tra web service
- name: Kiểm tra web service response
uri:
url: "http://{{ inventory_hostname }}/health"
return_content: yes
register: health_response
failed_when:
- health_response.status != 200
- "'healthy' not in health_response.content"
3. Changed_when - Kiểm soát trạng thái Changed
Đôi khi task chạy thành công nhưng không thực sự thay đổi gì. Sử dụng changed_when để báo cáo chính xác:
- name: Kiểm tra config file syntax
command: nginx -t
register: nginx_test
changed_when: false # Command này chỉ test, không thay đổi gì
- name: Lấy thông tin hệ thống
shell: uname -a
register: system_info
changed_when: false
4. Block và Rescue - Xử lý lỗi có cấu trúc
4.1 Cấu trúc Block-Rescue-Always
Tương tự try-catch trong lập trình, Ansible có block-rescue-always:
- name: Demo Block Rescue
hosts: webservers
tasks:
- block:
- name: Cài đặt package
yum:
name: nginx
state: present
- name: Start service
service:
name: nginx
state: started
rescue:
- name: Thông báo lỗi
debug:
msg: "Có lỗi xảy ra khi cài đặt nginx!"
- name: Gửi email cảnh báo
mail:
subject: "Ansible Error on {{ inventory_hostname }}"
body: "Failed to install nginx"
to: admin@example.com
always:
- name: Ghi log
lineinfile:
path: /var/log/ansible_deploy.log
line: "Deployment attempted at {{ ansible_date_time.iso8601 }}"
create: yes
4.2 Ví dụ thực tế: Deploy an toàn
- name: Deploy ứng dụng với rollback
hosts: appservers
tasks:
- block:
- name: Backup version hiện tại
command: cp -r /var/www/app /var/www/app.backup
- name: Deploy version mới
git:
repo: 'https://github.com/example/app.git'
dest: /var/www/app
version: main
- name: Restart application
service:
name: myapp
state: restarted
rescue:
- name: Rollback về version cũ
command: mv /var/www/app.backup /var/www/app
- name: Restart với version cũ
service:
name: myapp
state: restarted
- name: Notify team
debug:
msg: "Deploy failed! Đã rollback về version trước."
5. Debug Module - Công cụ debug chính
5.1 Debug cơ bản
- name: Debug đơn giản
debug:
msg: "Giá trị của biến: {{ my_variable }}"
- name: Debug với verbosity level
debug:
msg: "Thông tin chi tiết này chỉ hiện khi chạy với -v"
verbosity: 1
5.2 Debug variables và facts
- name: Hiển thị tất cả facts của host
debug:
var: ansible_facts
- name: Debug một variable cụ thể
debug:
var: hostvars[inventory_hostname]
- name: Debug với format đẹp hơn
debug:
msg: |
Hostname: {{ ansible_hostname }}
IP Address: {{ ansible_default_ipv4.address }}
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
6. Kỹ thuật Debugging nâng cao
6.1 Assert - Kiểm tra điều kiện
- name: Kiểm tra điều kiện trước khi tiếp tục
assert:
that:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version|int >= 7
- ansible_memtotal_mb >= 2048
fail_msg: "Server không đáp ứng yêu cầu tối thiểu"
success_msg: "Server đạt yêu cầu, tiếp tục deploy"
6.2 Register và Debug kết hợp
- name: Chạy command và debug output
shell: ps aux | grep nginx | wc -l
register: nginx_processes
- name: Hiển thị kết quả đầy đủ
debug:
var: nginx_processes
- name: Chỉ hiển thị stdout
debug:
msg: "Số process nginx: {{ nginx_processes.stdout }}"
6.3 Sử dụng --step và --start-at-task
# Chạy từng task một, xác nhận trước khi tiếp tục
ansible-playbook playbook.yml --step
# Bắt đầu từ một task cụ thể
ansible-playbook playbook.yml --start-at-task="Install nginx"
# Chạy với check mode (dry-run)
ansible-playbook playbook.yml --check
# Tăng verbosity level
ansible-playbook playbook.yml -vvv
7. Best Practices
7.1 Checklist debug hiệu quả
- Bắt đầu với syntax check:
ansible-playbook playbook.yml --syntax-check
- Sử dụng check mode trước:
ansible-playbook playbook.yml --check --diff
- Tăng verbosity khi cần:
-v # Thông tin cơ bản
-vv # Chi tiết hơn
-vvv # Rất chi tiết
-vvvv # Connection debugging
7.2 Cấu trúc error handling tốt
- name: Production deployment với error handling đầy đủ
hosts: production
tasks:
- name: Pre-deployment checks
block:
- name: Kiểm tra disk space
assert:
that: ansible_facts.devices.sda.partitions.sda1.size_available|int > 1000000000
fail_msg: "Không đủ disk space"
- name: Kiểm tra memory
assert:
that: ansible_memfree_mb > 500
fail_msg: "Không đủ RAM"
rescue:
- name: Cleanup và thử lại
command: "{{ cleanup_script }}"
when: cleanup_script is defined
- name: Main deployment
block:
- name: Deploy application
include_tasks: deploy.yml
rescue:
- name: Rollback
include_tasks: rollback.yml
- name: Send alert
include_tasks: alert.yml
always:
- name: Log deployment
include_tasks: logging.yml
Tổng kết
Trong bài này, chúng ta đã học:
- ✅ Error Handling:
ignore_errors,failed_when,changed_when - ✅ Block-Rescue-Always: Cấu trúc xử lý lỗi có tổ chức
- ✅ Debug Module: Công cụ debug chính trong Ansible
- ✅ Assert: Kiểm tra điều kiện trước khi thực thi
- ✅ CLI Options:
--check,--step,-vvvcho debugging
Bài tập thực hành
Hãy tạo một playbook để:
- Cài đặt nginx
- Kiểm tra service đã chạy chưa
- Nếu fail, thử cài đặt apache thay thế
- Log tất cả các bước vào file
- Gửi thông báo khi hoàn thành hoặc fail
Tip: Sử dụng block-rescue và register để theo dõi từng bước!
