Tự Động Hóa VPS Với Ansible 2026 - IaC, Playbook, Quản Lý Nhiều Server Cùng Lúc
1. Tại Sao Cần Tự Động Hóa VPS?
Bạn có 1 VPS — mọi thứ đơn giản. Bạn có 5 VPS — bắt đầu thấy phiền khi phải SSH vào từng máy, gõ cùng một lệnh 5 lần. Bạn có 20 VPS? Ác mộng quản trị. Cập nhật security patch, cài package mới, sửa config nginx, thêm user — mỗi thao tác nhân với 20 là 20 lần cơ hội gõ sai lệnh và làm sập production.
Ansible giải quyết vấn đề này bằng Infrastructure as Code (IaC): bạn viết cấu hình server trong file YAML, Ansible tự động áp dụng lên tất cả server cùng lúc. Đồng bộ, nhất quán, không sai sót con người.
Lợi ích khi dùng Ansible cho VPS:
- Nhất quán tuyệt đối: 50 server đều có cấu hình giống hệt nhau — không còn tình trạng "server A thiếu package này, server B sai config kia"
- Tốc độ: Cài LAMP stack trên 10 VPS trong 5 phút thay vì 2 tiếng SSH thủ công
- Version control: Playbook lưu trong Git → ai cũng biết server đang chạy config gì, thay đổi khi nào, ai đổi
- Idempotent: Chạy playbook 1 lần hay 10 lần — kết quả cuối cùng như nhau. Ansible chỉ thay đổi những gì cần thay đổi, không làm lại những thứ đã đúng
- Agentless: Chỉ cần SSH và Python trên server đích — không cài agent, không mở port mới
2. Cài Đặt Ansible & Cấu Hình Cơ Bản
2.1. Cài Ansible Trên Máy Control
Ansible chạy từ control node (máy của bạn hoặc 1 VPS riêng) và kết nối đến các managed node (VPS cần quản lý) qua SSH:
# Ubuntu/Debian
sudo apt update && sudo apt install -y ansible
# macOS
brew install ansible
# Kiểm tra version
ansible --version
2.2. Inventory File — Danh Sách Server
Inventory là file định nghĩa danh sách server bạn muốn quản lý:
# inventory.ini
[webservers]
web1 ansible_host=192.168.1.10 ansible_user=root
web2 ansible_host=192.168.1.11 ansible_user=root
web3 ansible_host=192.168.1.12 ansible_user=root
[dbservers]
db1 ansible_host=10.0.0.50 ansible_user=ubuntu
db2 ansible_host=10.0.0.51 ansible_user=ubuntu
[production:children]
webservers
dbservers
[all:vars]
ansible_python_interpreter=/usr/bin/python3
2.3. Kiểm Tra Kết Nối
# Ping tất cả server
ansible all -i inventory.ini -m ping
# Kết quả:
# web1 | SUCCESS => {"changed": false, "ping": "pong"}
# web2 | SUCCESS => {"changed": false, "ping": "pong"}
# Chạy lệnh trên tất cả webserver
ansible webservers -i inventory.ini -m shell -a "uptime"
# Kiểm tra OS version
ansible all -i inventory.ini -m shell -a "cat /etc/os-release"
3. Ansible Playbook — Trái Tim Của Automation
Playbook là file YAML mô tả trạng thái mong muốn của server. Bạn không viết "làm A rồi làm B", bạn viết "server phải có package X, file Y, service Z đang chạy". Ansible tự động tính toán cần làm gì để đạt trạng thái đó.
3.1. Playbook Đầu Tiên: Cập Nhật Hệ Thống
# update-system.yml
---
- name: Cập nhật và bảo mật tất cả VPS
hosts: all
become: yes
tasks:
- name: Update apt cache
apt:
update_cache: yes
cache_valid_time: 3600
- name: Upgrade tất cả packages
apt:
upgrade: dist
autoremove: yes
- name: Cài packages cần thiết
apt:
name:
- htop
- vim
- curl
- git
- ufw
- fail2ban
- unattended-upgrades
state: present
- name: Cấu hình timezone
timezone:
name: Asia/Ho_Chi_Minh
- name: Enable unattended security updates
copy:
dest: /etc/apt/apt.conf.d/20auto-upgrades
content: |
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";
3.2. Triển Khai LAMP Stack Trong 1 Playbook
# lamp-stack.yml - Cài Apache + MySQL + PHP trên nhiều VPS
---
- name: Triển khai LAMP Stack
hosts: webservers
become: yes
vars:
php_version: "8.2"
mysql_root_password: "{{ vault_mysql_root_password }}"
domain: "example.com"
tasks:
- name: Cài Apache
apt:
name: apache2
state: latest
- name: Cài MySQL
apt:
name:
- mysql-server
- mysql-client
- python3-pymysql
state: latest
- name: Khởi động MySQL
service:
name: mysql
state: started
enabled: yes
- name: Set MySQL root password
mysql_user:
name: root
password: "{{ mysql_root_password }}"
host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
check_implicit_admin: yes
- name: Cài PHP và extensions
apt:
name:
- "php{{ php_version }}"
- "php{{ php_version }}-mysql"
- "php{{ php_version }}-curl"
- "php{{ php_version }}-gd"
- "php{{ php_version }}-mbstring"
- "php{{ php_version }}-xml"
- "php{{ php_version }}-zip"
- "php{{ php_version }}-fpm"
state: latest
- name: Enable Apache modules
apache2_module:
name: "{{ item }}"
state: present
loop:
- rewrite
- ssl
- headers
- name: Tạo VirtualHost
template:
src: vhost.conf.j2
dest: "/etc/apache2/sites-available/{{ domain }}.conf"
- name: Enable site
command: a2ensite {{ domain }}.conf
args:
creates: "/etc/apache2/sites-enabled/{{ domain }}.conf"
notify: restart apache
handlers:
- name: restart apache
service:
name: apache2
state: restarted
4. Ansible Roles — Tái Sử Dụng & Tổ Chức Code
Role là cách tổ chức playbook thành các module độc lập, có thể tái sử dụng giữa các dự án. Mỗi role đảm nhiệm 1 chức năng: cài nginx, cấu hình firewall, deploy ứng dụng...
# Tạo cấu trúc role
mkdir -p roles/nginx/{tasks,handlers,templates,files,vars,defaults,meta}
# Cây thư mục role
roles/nginx/
├── tasks/main.yml # Tasks chính
├── handlers/main.yml # Handlers (restart, reload...)
├── templates/nginx.conf.j2 # Template config
├── vars/main.yml # Biến nội bộ role
├── defaults/main.yml # Biến mặc định (có thể override)
└── meta/main.yml # Metadata role
Ví dụ role cài Nginx + SSL tự động:
# roles/nginx/tasks/main.yml
---
- name: Cài Nginx
apt:
name: nginx
state: latest
- name: Cài Certbot
apt:
name:
- certbot
- python3-certbot-nginx
state: latest
- name: Copy Nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/sites-available/{{ domain }}
notify: reload nginx
- name: Enable site
file:
src: /etc/nginx/sites-available/{{ domain }}
dest: /etc/nginx/sites-enabled/{{ domain }}
state: link
notify: reload nginx
- name: Tạo SSL certificate
command: certbot --nginx -d {{ domain }} --non-interactive --agree-tos -m {{ admin_email }}
args:
creates: /etc/letsencrypt/live/{{ domain }}/fullchain.pem
Sử dụng role trong playbook chính:
# site.yml
---
- name: Deploy web servers
hosts: webservers
become: yes
roles:
- common # Cài packages cơ bản, firewall
- nginx # Cài Nginx + SSL
- php # Cài PHP-FPM
- nodejs # Cài Node.js + PM2
- deploy # Deploy application code
5. Ansible Vault — Bảo Mật Secrets
Không ai muốn commit password database hay API key lên GitHub. Ansible Vault mã hóa các biến nhạy cảm trong playbook:
# Tạo file secrets được mã hóa
ansible-vault create group_vars/all/secrets.yml
# Nhập password vault → nhập nội dung secrets
# Nội dung secrets.yml (đã mã hóa):
mysql_root_password: "SuperSecret123!"
api_key: "sk-abc123def456"
jwt_secret: "random-64-char-string"
# Sử dụng trong playbook
- name: Create database
mysql_db:
name: myapp
login_user: root
login_password: "{{ mysql_root_password }}"
# Chạy playbook với vault password
ansible-playbook site.yml --ask-vault-pass
# Hoặc dùng file password
ansible-playbook site.yml --vault-password-file .vault_pass
.vault_pass lên Git. Thêm vào .gitignore. Trong CI/CD, lưu vault password trong secrets của GitHub Actions/GitLab CI.
6. Ansible + CI/CD — Tự Động Deploy
Kết hợp Ansible với GitHub Actions để tự động deploy mỗi khi push code:
# .github/workflows/deploy.yml
name: Deploy to VPS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Ansible
run: sudo apt update && sudo apt install -y ansible
- name: Run Ansible playbook
env:
ANSIBLE_HOST_KEY_CHECKING: "false"
VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}
run: |
echo "$VAULT_PASSWORD" > .vault_pass
ansible-playbook -i inventory.ini deploy.yml --vault-password-file .vault_pass
7. So Sánh Ansible Với Các Công Cụ Tự Động Hóa Khác
| Tiêu Chí | Ansible | Terraform | Puppet | Bash Script |
|---|---|---|---|---|
| Ngôn ngữ | YAML | HCL | DSL (Ruby-like) | Bash |
| Kiến trúc | Agentless, push qua SSH | State file, plan/apply | Agent-server, pull | Không |
| Idempotent | ✅ Có | ✅ Có | ✅ Có | ❌ Thường không |
| Quản lý state | Không lưu state | State file (local/S3) | PuppetDB | Không |
| Phù hợp | Config management + deploy | Provision infrastructure | Enterprise config mgmt | Script đơn giản |
| Đường cong học | Thấp (YAML dễ đọc) | Trung bình | Cao | Thấp (nhưng dễ lỗi) |
| Phí | Miễn phí (OSS) | Miễn phí (OSS) | Miễn phí (OSS) | Miễn phí |
8. Các Use Case Thực Tế
8.1. Setup Server Mới Trong 3 Phút
Mỗi khi thuê VPS mới, thay vì SSH vào cài từng package, chỉ cần thêm IP vào inventory và chạy ansible-playbook setup-new-server.yml. 3 phút sau: firewall đã bật, fail2ban đã active, swap đã tạo, user deploy đã có, SSH key đã cài.
8.2. Cập Nhật Bảo Mật Hàng Loạt
Phát hiện lỗ hổng CVE nghiêm trọng? 1 dòng lệnh cập nhật tất cả 50 server: ansible all -m apt -a "name=openssl state=latest" -b. Không cần thức đêm SSH từng máy.
8.3. Rolling Update Zero-Downtime
Deploy ứng dụng mới với chiến lược rolling update: cập nhật từng server một, kiểm tra health check, chuyển traffic — tất cả tự động qua Ansible playbook với serial: 1.
8.4. Disaster Recovery
Toàn bộ cấu hình server được lưu trong Git. Nếu server chết, thuê VPS mới, chạy lại playbook — mọi thứ y hệt như cũ trong vài phút.
8.5. MMO Multi-VPS Management
Chạy tool MMO trên 20-30 VPS? Dùng Ansible để đồng bộ script, cập nhật proxy list, kiểm tra trạng thái tool, restart hàng loạt chỉ bằng 1 lệnh.
9. 10 Ansible Modules Quan Trọng Nhất
| Module | Công Dụng | Ví Dụ |
|---|---|---|
apt / yum | Quản lý packages | Cài, gỡ, update packages |
copy | Copy file lên server | Deploy config file |
template | Copy file với Jinja2 template | Config động theo biến |
file | Quản lý file/thư mục/quyền | Tạo folder, set permission |
service | Quản lý service/systemd | Start/stop/enable service |
shell / command | Chạy lệnh shell | Chạy script tùy chỉnh |
lineinfile | Sửa 1 dòng trong file | Thêm/sửa config trong file |
cron | Quản lý cron jobs | Tạo scheduled task |
git | Clone/update Git repo | Deploy code từ GitHub |
docker_container | Quản lý Docker containers | Deploy Docker app |
10. Tips & Best Practices
- Luôn test với
--check --difftrước: Xem playbook sẽ thay đổi gì trước khi chạy thật - Dùng
ansible-lint: Tự động kiểm tra lỗi syntax và best practice trong playbook - Tags để chạy 1 phần playbook:
ansible-playbook site.yml --tags "nginx"chỉ chạy task liên quan đến nginx - Limit host:
ansible-playbook site.yml --limit "web1"chỉ chạy trên web1 - Dùng
gather_facts: no: Tắt fact gathering nếu không cần, tiết kiệm 2-3s/server - Parallel execution: Mặc định Ansible chạy 5 server song song. Tăng với
-f 20
🚀 Sẵn Sàng Tự Động Hóa Hệ Thống VPS Của Bạn?
Cần VPS để làm control node hoặc thêm managed node? Thuê VPS giá rẻ tại TrumVPS — từ 47K/tháng, hỗ trợ cài sẵn Ansible
Thuê VPS Ngay