Làm ngay trong 5 phút
Nếu bạn đang quản lý 3+ server Linux và mỗi lần update đều phải SSH vào từng cái để gõ lệnh — tôi hiểu cảm giác đó. Ansible giải quyết vấn đề này theo cách đơn giản nhất có thể: SSH vào từng máy, chạy lệnh, xong. Không cần cài thêm agent, không cần daemon chạy nền, không cần mở thêm port nào cả.
Cài Ansible trên control node (CentOS Stream 9)
# Bật EPEL repository
sudo dnf install epel-release -y
# Cài Ansible
sudo dnf install ansible -y
# Kiểm tra version
ansible --version
Tạo file inventory đầu tiên
File inventory là danh sách các máy chủ bạn muốn quản lý. Tạo file hosts.ini trong thư mục project:
[webservers]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11
[dbservers]
db1 ansible_host=192.168.1.20
[all:vars]
ansible_user=admin
ansible_ssh_private_key_file=~/.ssh/id_rsa
Chạy lệnh đầu tiên
# Ping tất cả server để kiểm tra kết nối
ansible all -i hosts.ini -m ping
# Xem uptime của nhóm webservers
ansible webservers -i hosts.ini -m command -a "uptime"
# Xem dung lượng đĩa trên tất cả máy
ansible all -i hosts.ini -m command -a "df -h /"
Nếu thấy "ping": "pong" trả về từ các máy — bạn đã kết nối thành công và sẵn sàng tự động hóa.
Ansible hoạt động như thế nào?
Nhiều người nghe đến “automation tool” là tưởng ngay đến việc phải cài thêm service trên từng máy chủ. Ansible khác: nó dùng SSH — thứ bạn đang dùng mỗi ngày để kết nối server — làm đường truyền duy nhất.
Kiến trúc gồm 2 phần:
- Control Node: Máy bạn cài Ansible (laptop hoặc một jump server). Chỉ cần đúng 1 máy này.
- Managed Nodes: Các máy chủ cần quản lý. Chỉ cần có SSH và Python 3 — có sẵn trên hầu hết distro Linux hiện đại.
Khi chạy lệnh Ansible, nó thực hiện theo trình tự:
- Đọc file inventory để biết cần kết nối vào máy nào
- SSH vào từng managed node (song song nếu dùng
-f) - Upload module Python tạm thời vào
/tmp - Thực thi module, thu kết quả, xóa file tạm ngay lập tức
Toàn bộ quy trình diễn ra qua SSH — không còn gì tồn tại trên managed node sau khi chạy xong. Đây là lý do Ansible được gọi là agentless.
Viết Playbook thực tế
Ad-hoc command phù hợp cho tác vụ nhanh một lần. Khi cần làm nhiều bước theo thứ tự, bạn cần Playbook — file YAML mô tả “cần làm gì, trên máy nào, theo thứ tự nào”.
Ví dụ: Playbook cài đặt Nginx trên webservers
---
- name: Cài đặt và cấu hình Nginx
hosts: webservers
become: yes # chạy với sudo
vars:
nginx_port: 80
tasks:
- name: Cài nginx
dnf:
name: nginx
state: present
- name: Khởi động nginx và enable khi boot
systemd:
name: nginx
state: started
enabled: yes
- name: Mở port 80 trên firewall
firewalld:
port: "{{ nginx_port }}/tcp"
permanent: yes
state: enabled
immediate: yes
- name: Tạo trang index.html
copy:
content: "<h1>Server {{ inventory_hostname }} — Deployed by Ansible</h1>"
dest: /var/www/html/index.html
owner: nginx
group: nginx
mode: '0644'
handlers:
- name: Reload nginx
systemd:
name: nginx
state: reloaded
# Chạy playbook
ansible-playbook -i hosts.ini deploy_nginx.yml
# Dry-run: kiểm tra thay đổi mà chưa apply thật
ansible-playbook -i hosts.ini deploy_nginx.yml --check --diff
Tham số --check --diff cực kỳ hữu ích khi bạn chưa chắc playbook sẽ thay đổi gì — nó hiển thị chi tiết sẽ thay đổi file nào, dòng nào, mà không thực sự động tay vào hệ thống.
Câu chuyện thực tế: Migration 5 server trong 1 tuần
Khi CentOS 8 EOL, mình phải migrate gấp 5 server sang Rocky Linux trong 1 tuần. Lúc đầu tính làm thủ công — SSH từng máy, theo checklist Excel. Đến server thứ 3 thì sai sót bắt đầu xuất hiện: máy này quên bật SELinux lại sau test, máy kia cài nhầm version PHP, máy khác thiếu bước cấu hình timezone JST…
Đó là lúc mình dừng lại và viết Ansible playbook cho toàn bộ quá trình migration. Mất khoảng 2 tiếng để viết và test — nhưng 2 server còn lại chạy playbook trong 8 phút mỗi cái, hoàn toàn đồng nhất, không sai sót.
Playbook đó sau đó được dùng lại nhiều lần khi provision server mới — không cần nhớ lại từng bước, không cần checklist, chỉ cần ansible-playbook provision.yml.
Bài học: Viết playbook ngay cả khi chỉ có 2–3 server. Chi phí viết lần đầu thấp hơn nhiều so với chi phí debug khi làm tay mà sai ở bước thứ 4.
Tổ chức code với Roles
Khi playbook dài quá 50 task, nên tách ra thành Roles — cấu trúc thư mục chuẩn giúp tái sử dụng và chia sẻ giữa các project.
# Khởi tạo role mới
ansible-galaxy init roles/nginx
Cấu trúc thư mục sau khi tạo:
roles/nginx/
├── tasks/
│ └── main.yml # Các task chính
├── handlers/
│ └── main.yml # Handlers (restart/reload service)
├── templates/
│ └── nginx.conf.j2 # Template Jinja2 với biến động
├── vars/
│ └── main.yml # Biến cố định
└── defaults/
└── main.yml # Biến mặc định (có thể override)
Dùng role trong playbook gọn hơn nhiều:
---
- name: Setup web server stack
hosts: webservers
become: yes
roles:
- common # timezone, hostname, sysctl
- nginx
- php-fpm
- firewall
Tips thực tế
1. Bảo vệ thông tin nhạy cảm bằng Ansible Vault
# Mã hóa file chứa password/API key
ansible-vault encrypt secrets.yml
# Xem nội dung file đã mã hóa
ansible-vault view secrets.yml
# Chạy playbook với vault
ansible-playbook site.yml --ask-vault-pass
# Hoặc dùng password file (phù hợp cho CI/CD)
ansible-playbook site.yml --vault-password-file ~/.vault_pass
2. Tăng tốc khi có nhiều server
# Mặc định Ansible chạy 5 host song song
# Tăng lên 20 nếu infrastructure đủ lớn
ansible-playbook -i hosts.ini site.yml -f 20
# Hoặc set trong ansible.cfg
[defaults]
forks = 20
3. Kiểm tra chất lượng playbook trước khi dùng production
# Cài ansible-lint
pip install ansible-lint
# Lint toàn bộ project
ansible-lint
# Syntax check nhanh
ansible-playbook deploy.yml --syntax-check
4. Tạo file ansible.cfg trong project để không cần chỉ định -i mỗi lần
[defaults]
inventory = hosts.ini
remote_user = admin
private_key_file = ~/.ssh/id_rsa
host_key_checking = False
forks = 10
[privilege_escalation]
become = True
become_method = sudo
Với file ansible.cfg này, lệnh chạy chỉ còn:
ansible-playbook deploy_nginx.yml
Ansible không yêu cầu bạn phải là DevOps senior mới dùng được. Bắt đầu từ một file inventory đơn giản và vài ad-hoc command để làm quen — sau vài ngày bạn sẽ thấy mình không muốn SSH thủ công vào từng máy nữa. Đó là dấu hiệu tốt.

