Lab 1 — Ansible Fundamentals
Mục tiêu: Hiểu Ansible là gì, tại sao DevOps Engineer cần Ansible, kiến trúc Control Node / Managed Node, Inventory, SSH và thực hiện automation đầu tiên.
1. Bối cảnh thực tế
Hãy tưởng tượng bạn đang quản lý một hệ thống có 3 server:
Internet
│
┌─────────┼─────────┐
│ │ │
▼ ▼ ▼
Server 1 Server 2 Server 3
Công việc yêu cầu:
- Cài Nginx
- Tạo user
deploy - Cài Git
- Start một service
- Kiểm tra trạng thái server
Cách đơn giản nhất là SSH vào từng server:
ssh user@server-1
ssh user@server-2
ssh user@server-3
Sau đó thực hiện từng command.
Với 3 server, cách này vẫn có thể chấp nhận được.
Nhưng hãy tưởng tượng hệ thống có:
10 servers
50 servers
100 servers
500 servers
Vấn đề bắt đầu xuất hiện:
- Phải thực hiện cùng một công việc nhiều lần.
- Dễ thao tác sai giữa các server.
- Khó đảm bảo các server có cùng cấu hình.
- Không có lịch sử automation rõ ràng.
- Khi server mới được tạo, phải cấu hình lại từ đầu.
- Khi cần thay đổi cấu hình, phải nhớ tất cả server cần thay đổi.
Đây chính là bài toán Configuration Management.
Và Ansible được sinh ra để giải quyết bài toán này.
2. Ansible là gì?
Ansible là một công cụ automation và configuration management, cho phép chúng ta tự động hóa các công việc quản trị hệ thống thông qua code.
Thay vì:
Human
│
├── SSH Server 1
├── SSH Server 2
├── SSH Server 3
└── SSH Server 4
chúng ta có thể mô tả:
"Đảm bảo tất cả web server đều có Nginx và Nginx đang chạy."
Sau đó Ansible thực hiện công việc đó trên các server.
Ansible
│
▼
┌──────────────┐
│ Control Node │
└───────┬──────┘
│
┌───────────┼───────────┐
│ │ │
SSH SSH SSH
│ │ │
▼ ▼ ▼
Server 1 Server 2 Server 3
Điểm quan trọng:
Ansible không phải là một script chứa hàng loạt command SSH.
Ansible mô tả trạng thái mong muốn của hệ thống và cố gắng đưa server về trạng thái đó.
Ví dụ:
state: present
có nghĩa là:
Package này phải tồn tại.
Không phải:
Hãy chạy command
apt install ....
Đây là một trong những tư duy quan trọng nhất khi học Ansible.
3. Tại sao DevOps Engineer cần Ansible?
Trong DevOps, infrastructure thường thay đổi liên tục.
Ví dụ:
Developer
│
▼
Application
│
▼
Docker
│
▼
Server
│
▼
Monitoring
Khi hệ thống phát triển, số lượng server và service cũng tăng lên.
Nếu configuration được thực hiện thủ công:
Manual
│
├── SSH
├── Install
├── Configure
├── Restart
└── Verify
thì rất khó đảm bảo tính nhất quán.
Ansible giúp chúng ta chuyển configuration thành code:
Infrastructure
│
▼
Infrastructure as Code
│
▼
Ansible
│
▼
Repeatable Automation
Lợi ích chính:
- Repeatability — có thể chạy lại.
- Consistency — các server được cấu hình nhất quán.
- Automation — giảm thao tác thủ công.
- Scalability — quản lý nhiều server.
- Version Control — lưu automation trong Git.
- Auditability — biết configuration được thay đổi như thế nào.
- Idempotency — chạy nhiều lần không tạo ra thay đổi không cần thiết.
4. Ansible Architecture
Kiến trúc cơ bản của Ansible rất đơn giản.
Developer
│
│
▼
┌─────────────────┐
│ Control Node │
│ │
│ Ansible │
└────────┬────────┘
│
SSH
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Server 1 │ │ Server 2 │ │ Server 3 │
│ Managed │ │ Managed │ │ Managed │
│ Node │ │ Node │ │ Node │
└──────────┘ └──────────┘ └──────────┘
Có 2 khái niệm quan trọng:
Control Node
Máy chạy Ansible.
Ví dụ:
MacBook
Ubuntu Server
CI/CD Server
Trên Control Node chúng ta cài:
ansible
Managed Node
Các server được Ansible quản lý.
Ví dụ:
web-01
web-02
db-01
Managed Node thường không cần cài Ansible.
Đây là một đặc điểm rất quan trọng của Ansible.
5. Ansible Agentless
Một trong những điểm nổi bật của Ansible là agentless.
Một số công cụ configuration management yêu cầu cài agent trên server.
Mô hình có agent:
Controller
│
│
▼
Agent
│
▼
Server
Ansible thường hoạt động theo mô hình:
Control Node
│
│ SSH
▼
Linux Server
Control Node kết nối tới Managed Node thông qua SSH.
Do đó Managed Node không cần chạy một Ansible daemon riêng.
Điều này giúp kiến trúc đơn giản hơn.
6. Các thành phần quan trọng của Ansible
Trong những Lab tiếp theo chúng ta sẽ học rất nhiều thành phần.
Ở Lab 1, chỉ cần nắm các khái niệm chính:
Ansible
│
├── Control Node
│
├── Managed Node
│
├── Inventory
│
├── Module
│
├── Task
│
├── Play
│
└── Playbook
6.1. Inventory
Inventory là nơi Ansible biết:
"Tôi cần quản lý những server nào?"
Ví dụ:
[webservers]
web-01
web-02
[dbservers]
db-01
Có thể hình dung:
Inventory
│
├── webservers
│ ├── web-01
│ └── web-02
│
└── dbservers
└── db-01
Inventory sẽ được tìm hiểu kỹ hơn ở Lab 2.
6.2. Module
Module là các đơn vị chức năng mà Ansible sử dụng để thực hiện công việc.
Ví dụ:
apt
copy
file
service
user
package
template
command
Ví dụ:
ansible.builtin.apt:
name: nginx
state: present
Có thể hiểu đơn giản:
Module = công cụ thực hiện một loại công việc
6.3. Task
Task mô tả một công việc.
Ví dụ:
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Đây là một Task.
6.4. Play
Play xác định:
Task nào sẽ chạy trên server nào?
Ví dụ:
- name: Configure web servers
hosts: webservers
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
6.5. Playbook
Playbook là file YAML chứa một hoặc nhiều Play.
Ví dụ:
- name: Configure web servers
hosts: webservers
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Thông thường Playbook có extension:
.yml
.yaml
Ví dụ:
site.yml
deploy.yml
server.yml
7. Chuẩn bị môi trường Lab
Trong series này, chúng ta sử dụng mô hình:
MacBook
Control Node
│
SSH
│
┌────────┴────────┐
▼ ▼
Ubuntu Server 1 Ubuntu Server 2
Managed Node Managed Node
Bạn có thể sử dụng:
- VM
- Cloud server
- Multipass
- VirtualBox
- VMware
- AWS EC2
- DigitalOcean
- Một Linux server có SSH
Để đơn giản, Lab chỉ cần 1 Managed Node.
MacBook
│
│ Ansible + SSH
▼
Ubuntu Server
8. Cài đặt Ansible trên Control Node
Kiểm tra Python:
python3 --version
Sau đó cài Ansible.
Trên macOS có thể sử dụng Homebrew:
brew install ansible
Kiểm tra:
ansible --version
Ví dụ:
ansible [core 2.x.x]
python version = 3.x.x
Nếu thấy thông tin version nghĩa là Ansible đã được cài thành công.
9. Kiểm tra SSH trước khi dùng Ansible
Trước khi chạy Ansible, hãy đảm bảo Control Node có thể SSH vào Managed Node.
Ví dụ:
ssh ubuntu@192.168.56.101
Nếu đăng nhập thành công:
ubuntu@server:~$
thì kết nối SSH đã hoạt động.
Thoát:
exit
Tip: Nếu SSH chưa hoạt động, đừng vội debug Ansible. Hãy đảm bảo SSH hoạt động bình thường trước.
Ansible sử dụng SSH làm nền tảng kết nối nên:
SSH không hoạt động
↓
Ansible cũng không hoạt động
10. Tạo Ansible Project đầu tiên
Tạo project:
mkdir ansible-lab
cd ansible-lab
Tạo inventory:
touch inventory.ini
Cấu trúc:
ansible-lab/
└── inventory.ini
Nội dung:
[webservers]
web-01 ansible_host=192.168.56.101
Trong đó:
web-01
là tên logical của server.
Còn:
ansible_host=192.168.56.101
là địa chỉ thật của server.
11. Kiểm tra Inventory
Chạy:
ansible-inventory -i inventory.ini --list
Hoặc:
ansible-inventory -i inventory.ini --graph
Kết quả có thể giống:
@all:
|--@ungrouped:
|--@webservers:
| |--web-01
Điều này cho thấy Ansible đã đọc được Inventory.
12. Chạy Ansible Command đầu tiên
Bây giờ chúng ta thử module:
ping
Chạy:
ansible webservers \
-i inventory.ini \
-m ansible.builtin.ping
Nếu thành công:
web-01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Đây là thời điểm quan trọng.
Chúng ta vừa thực hiện:
MacBook
│
│ Ansible
│
│ SSH
▼
Ubuntu Server
mà không cần SSH thủ công.
13. Hiểu câu lệnh vừa chạy
Command:
ansible webservers \
-i inventory.ini \
-m ansible.builtin.ping
gồm:
ansible
│
├── webservers
│ └── Target
│
├── -i inventory.ini
│ └── Inventory
│
└── -m ansible.builtin.ping
└── Module
webservers
Cho Ansible biết target là group:
[webservers]
-i
Chỉ định Inventory:
-i inventory.ini
-m
Chỉ định module:
-m ansible.builtin.ping
14. Thử một vài Ad-Hoc Command
Kiểm tra hostname:
ansible webservers \
-i inventory.ini \
-m ansible.builtin.command \
-a "hostname"
Kiểm tra OS:
ansible webservers \
-i inventory.ini \
-m ansible.builtin.command \
-a "cat /etc/os-release"
Kiểm tra uptime:
ansible webservers \
-i inventory.ini \
-m ansible.builtin.command \
-a "uptime"
Bạn vừa thực hiện một thao tác rất quan trọng:
One command
│
▼
Multiple remote servers
Nếu Inventory có:
[webservers]
web-01
web-02
web-03
thì cùng một command có thể được thực thi trên cả ba server.
Ad-Hoc Commands sẽ được học chi tiết trong Lab 3.
15. Playbook đầu tiên
Ad-Hoc Command rất hữu ích để kiểm tra nhanh.
Nhưng nếu muốn automation có thể:
- lưu trong Git
- review
- tái sử dụng
- chạy lại
- chia sẻ cho team
thì chúng ta cần Playbook.
Tạo:
touch site.yml
Nội dung:
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
Chạy:
ansible-playbook \
-i inventory.ini \
site.yml
Ansible sẽ:
Read Playbook
│
▼
Read Inventory
│
▼
Find webservers
│
▼
Connect via SSH
│
▼
Install nginx
│
▼
Return result
16. become: true là gì?
Trong Linux, cài package thường cần quyền root.
Ví dụ:
sudo apt install nginx
Trong Ansible:
become: true
cho phép Ansible thực hiện task với privilege escalation.
Có thể hiểu:
SSH user
│
│ sudo
▼
root privileges
Ví dụ:
- name: Configure web servers
hosts: webservers
become: true
17. Điều thú vị: chạy Playbook lần thứ hai
Hãy chạy:
ansible-playbook \
-i inventory.ini \
site.yml
lần thứ nhất có thể thấy:
changed=1
Chạy lại:
ansible-playbook \
-i inventory.ini \
site.yml
có thể thấy:
changed=0
Đây là một trong những concept quan trọng nhất của Ansible:
Idempotency
Ý tưởng:
Desired State
│
▼
Ansible Run
│
┌────────┴────────┐
│ │
Not correct Correct
│ │
▼ ▼
Change No change
Ví dụ:
state: present
không có nghĩa:
"Cài package mỗi lần."
Nó có nghĩa:
"Đảm bảo package tồn tại."
Nếu package đã tồn tại:
No change
Nếu chưa tồn tại:
Install
Đây là tư duy nền tảng mà chúng ta sẽ đào sâu trong Lab 7 — Handlers & Idempotency.
18. Kiểm tra Nginx
Trên server:
systemctl status nginx
Hoặc từ Control Node:
ansible webservers \
-i inventory.ini \
-m ansible.builtin.command \
-a "systemctl is-active nginx"
Kiểm tra HTTP:
curl http://192.168.56.101
Nếu nhận được HTML của Nginx:
Welcome to nginx!
thì Lab đã thành công.
19. Cấu trúc Project
Sau Lab 1, project có thể có:
ansible-lab/
│
├── inventory.ini
│
└── site.yml
Chúng ta chưa cần tạo một cấu trúc phức tạp.
Ở các Lab sau, project sẽ dần phát triển:
ansible-project/
├── inventories/
├── group_vars/
├── host_vars/
├── roles/
├── playbooks/
├── templates/
├── files/
└── ansible.cfg
Mục tiêu của series là từng bước xây dựng cấu trúc này thay vì đưa toàn bộ cho người mới ngay từ đầu.
20. Những lỗi thường gặp
20.1. UNREACHABLE
Ví dụ:
web-01 | UNREACHABLE!
Nguyên nhân thường gặp:
- Server không chạy.
- IP sai.
- SSH không hoạt động.
- Firewall chặn SSH.
- Username sai.
- SSH key sai.
Kiểm tra trước bằng:
ssh ubuntu@192.168.56.101
20.2. Permission denied
Ví dụ:
Permission denied (publickey)
Kiểm tra SSH:
ssh ubuntu@192.168.56.101
Nếu SSH cũng fail thì vấn đề chưa nằm ở Ansible.
20.3. sudo password required
Nếu gặp lỗi liên quan đến sudo:
Missing sudo password
có thể cần cấu hình privilege escalation phù hợp.
Trong môi trường Lab, có thể sử dụng:
ansible-playbook \
-i inventory.ini \
site.yml \
-K
-K yêu cầu Ansible hỏi sudo password.
Không nên tắt cơ chế bảo mật một cách tùy tiện chỉ để Playbook chạy được.
21. Best Practices
1. Kiểm tra SSH trước
ssh user@server
Sau đó mới debug Ansible.
2. Không hard-code secret
Không nên:
password=123456
Trong Inventory.
Sau này chúng ta sẽ học Ansible Vault.
3. Dùng module thay vì shell khi có thể
Không nên:
- name: Install nginx
ansible.builtin.shell: apt install nginx -y
Nếu đã có module:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
Module giúp automation dễ đọc, predictable và idempotent hơn.
4. Đặt tên Task rõ ràng
Không nên:
- name: Install
Nên:
- name: Install nginx
Khi Playbook có hàng trăm task, tên rõ ràng sẽ cực kỳ quan trọng.
5. Version Control
Ansible code nên được quản lý bằng Git:
Git
│
├── inventory
├── playbooks
├── roles
└── templates
Infrastructure cũng là code.
Vì vậy:
Infrastructure code cũng cần được review, versioning và audit giống application code.
22. 🧠 Senior Thinking
Đến đây người mới có thể nghĩ:
"Ansible giúp tôi chạy command trên nhiều server."
Đó là đúng, nhưng chưa đủ.
Một DevOps Engineer cần bắt đầu suy nghĩ:
Câu hỏi 1
Nếu tôi chạy Playbook 100 lần thì sao?
Run 1
Run 2
Run 3
...
Run 100
Hệ thống có bị thay đổi liên tục không?
→ Idempotency
Câu hỏi 2
Nếu server mới được tạo ngày hôm nay thì sao?
New Server
│
▼
Ansible
│
▼
Desired Configuration
Có thể đưa server mới về đúng trạng thái mà không cần cấu hình thủ công không?
→ Automation
Câu hỏi 3
Nếu có 100 server thì sao?
100 Servers
│
▼
Inventory
│
▼
Ansible
Có cần copy-paste command 100 lần không?
→ Scalability
Câu hỏi 4
Nếu Playbook nằm trong Git thì sao?
Developer
│
▼
Git
│
▼
Pull Request
│
▼
Review
│
▼
Ansible
Infrastructure có thể được review như code không?
→ Infrastructure as Code
23. Challenge
Sau khi hoàn thành Lab, hãy tự thực hiện bài tập sau mà không copy Playbook ở trên.
Bạn có một server:
web-01
Hãy viết Playbook có khả năng:
- Cài Nginx.
- Đảm bảo Nginx được enable khi server reboot.
- Đảm bảo Nginx đang chạy.
- Chạy lại Playbook không tạo thay đổi không cần thiết.
- Kiểm tra kết quả bằng command từ Control Node.
Sau đó thử:
Stop Nginx
│
▼
Run Playbook
│
▼
Nginx should be running
Tiếp theo:
Run Playbook
│
▼
No unnecessary changes
Nếu bạn làm được cả hai trường hợp, bạn đã bắt đầu hiểu được tư duy Desired State + Idempotency thay vì chỉ biết chạy command bằng Ansible.
24. Tổng kết
Sau Lab 1, bạn cần hiểu được:
Ansible
│
├── Control Node
│
├── Managed Node
│
├── SSH
│
├── Inventory
│
├── Module
│
├── Task
│
├── Play
│
├── Playbook
│
└── Idempotency
Và quan trọng hơn, bạn đã thực hiện được flow đầu tiên:
MacBook
Control Node
│
│ Ansible
│
│ SSH
▼
Ubuntu Server
│
▼
Nginx
Từ đây, chúng ta sẽ không chỉ học cách sử dụng Ansible.
Chúng ta sẽ từng bước xây dựng khả năng:
Run command
↓
Write Playbook
↓
Manage configuration
↓
Create reusable automation
↓
Provision server
↓
Deploy application
↓
Manage secrets
↓
Handle failures
↓
Manage environments
↓
Production Automation
Lab tiếp theo — Ansible Inventory & SSH sẽ đi sâu vào cách Ansible quản lý nhiều server, cách tổ chức Inventory, SSH key, group, host variables và cách thiết kế Inventory phù hợp với môi trường thực tế.
All rights reserved