Vấn đềBạn khởi chạy một Ansible playbook để thiết lập một web server mới. Mọi thứ đều ổn cho đến khi tác vụ cài đặt Nginx hoặc Redis gặp lỗi. Mặc dù bạn biết gói đó tồn tại, Ansible vẫn báo cáo rằng không tìm thấy kết quả phù hợp.
Lỗi này thường làm dừng quá trình triển khai của bạn với thông báo sau:
fatal: [server_ip]: FAILED! => {"changed": false, "msg": "No package matching 'nginx' is available"}
Đây là một trở ngại phổ biến trên các cloud instance mới khởi tạo, chẳng hạn như image AWS EC2 Ubuntu 22.04, nơi chỉ mục gói (package index) cục bộ thường trống hoặc đã cũ theo mặc định.
Tại sao Ansible không tìm thấy gói của bạnAnsible không quét trực tiếp trên internet để tìm phần mềm. Thay vào đó, nó dựa vào bộ nhớ đệm metadata (metadata cache) cục bộ được lưu trữ trên host từ xa. Nếu chỉ mục đó đã cũ vài ngày—hoặc chưa từng được cập nhật—trình quản lý gói sẽ không thấy phần mềm mà bạn yêu cầu.
Các nguyên nhân phổ biến bao gồm:
- Cache đã cũ: Server chưa chạy cập nhật gần đây và không biết về các phiên bản gói hiện tại.- Thiếu kho lưu trữ (Repositories): Bạn đang cố gắng cài đặt phần mềm như
nginxtrên RHEL mà chưa bật kho lưu trữ EPEL.- Sai lệch tên gọi: Gói phần mềm có tên làapache2trên Debian nhưng lại làhttpdtrên Red Hat.- Hạn chế mạng: Các quy tắc tường lửa hoặc thiếu thiết lập proxy đang chặn máy chủ kết nối tới các mirror.## Cách khắc phục nhanh: Làm mới Package CacheGiải pháp nhanh nhất là buộc Ansible cập nhật chỉ mục gói trước khi thử cài đặt. Theo mặc định, Ansible bỏ qua bước này để tiết kiệm khoảng 10–30 giây thời gian thực thi.
Dành cho Ubuntu/Debian (apt)Thêm update_cache: yes vào tác vụ của bạn. Điều này tương tự như việc chạy lệnh apt-get update thủ công.
- name: Install nginx and update cache
ansible.builtin.apt:
name: nginx
state: present
update_cache: yes # Cập nhật danh sách gói trước khi cài đặt
Dành cho CentOS/RHEL (yum/dnf)Mặc dù yum thường xử lý metadata tốt hơn apt, bạn vẫn có thể buộc làm mới để đảm bảo tác vụ lấy dữ liệu từ kho lưu trữ mới nhất:
- name: Install nginx and refresh yum metadata
ansible.builtin.yum:
name: nginx
state: present
update_cache: yes # Buộc làm mới metadata
Cách khắc phục lâu dài: Thêm kho lưu trữ (Repositories)Nếu việc làm mới cache không giải quyết được vấn đề, có khả năng gói đó không nằm trong các kho lưu trữ mặc định của hệ điều hành. Ví dụ, bản cài đặt CentOS 7 hoặc 8 stream tiêu chuẩn không bao gồm Nginx trong repo gốc.
Kích hoạt EPEL trên RHEL/CentOSTrước tiên, bạn phải cài đặt kho lưu trữ Extra Packages for Enterprise Linux (EPEL). Việc này sẽ thêm hàng ngàn gói mã nguồn mở tiêu chuẩn vào danh sách có sẵn của bạn.
- name: Install EPEL repository
ansible.builtin.yum:
name: epel-release
state: present
- name: Install nginx
ansible.builtin.yum:
name: nginx
state: present
update_cache: yes
Thêm PPA trên UbuntuNếu bạn cần một phiên bản cụ thể, chẳng hạn như Nginx Mainline hoặc Certbot, bạn có thể cần đến Personal Package Archive (PPA):
- name: Add Nginx stable PPA
ansible.builtin.apt_repository:
repo: 'ppa:nginx/stable'
state: present
update_cache: yes
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Xử lý tên gói trên nhiều nền tảngĐôi khi lỗi xảy ra do sự khác biệt đơn giản về tên gọi. Đừng viết cứng (hardcode) tên gói nếu bạn quản lý nhiều dòng hệ điều hành khác nhau. Hãy sử dụng biến để chọn đúng tên cho từng hệ thống một cách linh hoạt.
- name: Set package name based on OS
set_fact:
web_server_package: "{{ 'apache2' if ansible_os_family == 'Debian' else 'httpd' }}"
- name: Install web server
ansible.builtin.package:
name: "{{ web_server_package }}"
state: present
Xác minh thủ côngNếu playbook vẫn thất bại, hãy đăng nhập vào host từ xa để kiểm tra tình trạng gói theo cách thủ công. Việc này giúp xác nhận vấn đề nằm ở logic Ansible của bạn hay ở mạng của máy chủ.
Trên Debian/Ubuntu:```
Kiểm tra xem gói có được apt nhận diện không
apt-cache policy nginx
Nếu kết quả hiển thị `Candidate: (none)`, cấu hình kho lưu trữ của bạn vẫn đang gặp lỗi.
### Trên CentOS/RHEL:```
# Liệt kê các gói có sẵn khớp với nginx
yum list available | grep nginx

