Tự Động Hóa VPS Với Ansible 2026 - IaC, Playbook, Quản Lý Nhiều Server Cùng Lúc

📅 22/06/2026 · ⏱ 14 phút đọc · 🏷 DevOps · Dev · Linux

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:

💡 Sự thật thú vị: Ansible được Red Hat mua lại năm 2015 và hiện là công cụ automation số 1 thế giới. Được dùng bởi NASA, Netflix, Twitter, và hàng triệu DevOps engineer. Học Ansible là 1 trong những khoản đầu tư ROI cao nhất cho sysadmin.

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
🔑 Yêu cầu: Control node cần Python 3.8+. Managed node cần Python và SSH access. Không cần cài gì trên managed node ngoài Python (có sẵn trên mọi Linux). Đây là điểm mạnh nhất của Ansible so với Puppet/Chef/Saltstack.

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
⚡ Thời gian thực tế: Chạy playbook LAMP trên 10 VPS mới cài Ubuntu mất 3-5 phút. Làm thủ công: ít nhất 30 phút/server x 10 = 5 tiếng. Tiết kiệm 98% thời gian.

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
🔒 Best practice: Không commit .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íAnsibleTerraformPuppetBash Script
Ngôn ngữYAMLHCLDSL (Ruby-like)Bash
Kiến trúcAgentless, push qua SSHState file, plan/applyAgent-server, pullKhông
Idempotent✅ Có✅ Có✅ Có❌ Thường không
Quản lý stateKhông lưu stateState file (local/S3)PuppetDBKhông
Phù hợpConfig management + deployProvision infrastructureEnterprise config mgmtScript đơn giản
Đường cong họcThấp (YAML dễ đọc)Trung bìnhCaoThấp (nhưng dễ lỗi)
PhíMiễn phí (OSS)Miễn phí (OSS)Miễn phí (OSS)Miễn phí
🎯 Khi nào dùng Ansible vs Terraform: Dùng cả hai nếu bạn làm DevOps nghiêm túc. Terraform provision VPS (tạo/xóa server), Ansible configure VPS (cài package, config, deploy app). Chúng bổ sung cho nhau, không cạnh tranh. Nếu chỉ chọn 1: Ansible cho người mới bắt đầu vì đơn giản hơn.

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

ModuleCông DụngVí Dụ
apt / yumQuản lý packagesCài, gỡ, update packages
copyCopy file lên serverDeploy config file
templateCopy file với Jinja2 templateConfig động theo biến
fileQuản lý file/thư mục/quyềnTạo folder, set permission
serviceQuản lý service/systemdStart/stop/enable service
shell / commandChạy lệnh shellChạy script tùy chỉnh
lineinfileSửa 1 dòng trong fileThêm/sửa config trong file
cronQuản lý cron jobsTạo scheduled task
gitClone/update Git repoDeploy code từ GitHub
docker_containerQuản lý Docker containersDeploy Docker app

10. Tips & Best Practices

🚀 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