Lab 14 — Final Project: Automated Server Provisioning
Mục tiêu: Xây dựng một hệ thống Ansible hoàn chỉnh có khả năng tự động provision và triển khai một server production từ đầu, áp dụng toàn bộ kiến thức từ Lab 1 → Lab 13.
Đây là Final Project, vì vậy không nên chỉ là một bài "copy command rồi chạy". Người học cần được đặt vào một tình huống gần với công việc DevOps thực tế.
1. Bối cảnh
Giả sử công ty có một application:
Todo Application
Application gồm:
Internet
│
▼
Nginx
│
▼
Todo API
│
▼
PostgreSQL
Công ty vừa tạo một Ubuntu server mới.
Server hiện tại:
Ubuntu Server
Fresh installation
Chưa có:
Docker
Docker Compose
Nginx
Application
Deploy User
Firewall
Application Configuration
Nhiệm vụ của bạn là:
Sử dụng Ansible để biến một server Ubuntu mới thành một application server production-ready.
Không SSH vào server để cài thủ công.
Không chạy:
apt install ...
docker install ...
vim /etc/...
thủ công.
Tất cả phải được quản lý bằng:
Ansible
2. Scenario
Bạn được giao ticket:
[DEVOPS-001]
Provision new production application server.
Requirements:
- Ubuntu 24.04
- Create deploy user
- Configure SSH
- Configure firewall
- Install required packages
- Install Docker
- Install Docker Compose
- Configure application
- Configure Nginx
- Deploy application
- Configure environment variables
- Configure secrets securely
- Configure log rotation
- Configure health check
- Support Dev / Staging / Production
- Deployment must be idempotent
Bạn cần biến requirements này thành một Ansible project.
3. Mục tiêu Final Project
Sau khi hoàn thành, người học phải có thể:
- Thiết kế một Ansible project hoàn chỉnh.
- Quản lý nhiều environment.
- Quản lý nhiều server.
- Sử dụng Inventory.
- Sử dụng Variables.
- Sử dụng Facts.
- Sử dụng Templates.
- Sử dụng Handlers.
- Xây dựng Roles.
- Sử dụng Ansible Vault.
- Provision server.
- Deploy Docker.
- Deploy application.
- Configure Nginx.
- Configure firewall.
- Kiểm tra health.
- Debug deployment.
- Đảm bảo idempotency.
- Thực hiện rolling deployment.
- Thiết kế production safety.
- Tổ chức code có thể maintain.
4. Kiến trúc mục tiêu
Kiến trúc cuối cùng:
Internet
│
▼
┌─────────────┐
│ Nginx │
│ Reverse │
│ Proxy │
└──────┬──────┘
│
▼
┌─────────────┐
│ Todo API │
│ Docker │
└──────┬──────┘
│
▼
┌─────────────┐
│ PostgreSQL │
│ Docker │
└─────────────┘
Ansible:
Ansible Controller
│
│ SSH
▼
┌─────────────────┐
│ Ubuntu Server │
│ │
│ deploy user │
│ Docker │
│ Nginx │
│ Firewall │
│ Todo API │
│ PostgreSQL │
└─────────────────┘
5. Multi-Environment
Project phải hỗ trợ:
DEV
│
└── dev-server
STAGING
│
└── staging-server
PRODUCTION
│
├── prod-server-01
└── prod-server-02
Mục tiêu:
Same Roles
Same Playbooks
Different Inventory
Different Configuration
Different Secrets
6. Project Structure
Cấu trúc đề xuất:
ansible-final-project/
│
├── ansible.cfg
├── site.yml
├── README.md
│
├── inventories/
│ │
│ ├── dev/
│ │ ├── hosts.ini
│ │ ├── group_vars/
│ │ │ ├── all.yml
│ │ │ └── vault.yml
│ │ └── host_vars/
│ │
│ ├── staging/
│ │ ├── hosts.ini
│ │ ├── group_vars/
│ │ │ ├── all.yml
│ │ │ └── vault.yml
│ │ └── host_vars/
│ │
│ └── production/
│ ├── hosts.ini
│ ├── group_vars/
│ │ ├── all.yml
│ │ └── vault.yml
│ └── host_vars/
│
├── group_vars/
│
├── roles/
│ │
│ ├── common/
│ ├── security/
│ ├── docker/
│ ├── nginx/
│ ├── application/
│ └── monitoring/
│
├── playbooks/
│ ├── provision.yml
│ ├── deploy.yml
│ └── verify.yml
│
├── templates/
│
└── scripts/
├── deploy-dev.sh
├── deploy-staging.sh
└── deploy-production.sh
7. Phase 1 — Chuẩn bị Infrastructure
Trong lab thực tế, có thể sử dụng:
VirtualBox
VMware
Multipass
Vagrant
AWS EC2
DigitalOcean
Cloud VM
Để người mới dễ thực hành, có thể sử dụng:
3 Ubuntu VM
Ví dụ:
Dev
192.168.56.11
Staging
192.168.56.12
Production
192.168.56.13
Nếu muốn nâng cấp:
Production
192.168.56.13
192.168.56.14
8. Phase 2 — Bootstrap SSH
Đầu tiên cần có một user có khả năng SSH vào server.
Ví dụ:
MacBook
│
│ SSH
▼
Ubuntu Server
Kiểm tra:
ssh ubuntu@192.168.56.11
Sau đó Ansible sẽ đảm nhiệm phần còn lại.
9. Phase 3 — Tạo Deploy User
Không nên deploy application bằng:
root
Tạo:
deploy
Role:
roles/common/
Task:
- name: Create deploy user
ansible.builtin.user:
name: deploy
shell: /bin/bash
groups: sudo
append: true
create_home: true
10. SSH Key
Copy public key:
- name: Configure SSH key
ansible.posix.authorized_key:
user: deploy
key: "{{ deploy_ssh_public_key }}"
Sau đó:
ssh deploy@server
11. Disable Password Authentication
Production không nên phụ thuộc vào:
SSH password
Template:
/etc/ssh/sshd_config
Ví dụ:
PasswordAuthentication no
PubkeyAuthentication yes
Sau khi thay đổi:
restart ssh
Đây là lúc kiến thức Handler từ Lab 7 được sử dụng.
12. Handler SSH
- name: Restart ssh
ansible.builtin.service:
name: ssh
state: restarted
Task:
notify: Restart ssh
Không restart SSH sau mọi task.
Chỉ restart khi configuration thực sự thay đổi.
13. Phase 4 — System Provisioning
Server cần được cập nhật:
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
Cài package:
- name: Install required packages
ansible.builtin.apt:
name:
- curl
- git
- unzip
- ca-certificates
- jq
- vim
state: present
14. Sử dụng Facts
Kiểm tra:
ansible_distribution
ansible_distribution_version
ansible_architecture
ansible_memtotal_mb
ansible_processor_vcpus
Ví dụ:
- name: Display server information
ansible.builtin.debug:
msg:
- "OS: {{ ansible_distribution }}"
- "Version: {{ ansible_distribution_version }}"
- "Architecture: {{ ansible_architecture }}"
- "CPU: {{ ansible_processor_vcpus }}"
15. Validate OS
Không phải server nào cũng được phép chạy.
- name: Validate operating system
ansible.builtin.assert:
that:
- ansible_distribution == "Ubuntu"
- ansible_distribution_major_version in ["22", "24"]
fail_msg: "Unsupported operating system"
16. Phase 5 — Firewall
Production server chỉ nên expose:
22
80
443
Ví dụ sử dụng UFW:
- name: Allow SSH
community.general.ufw:
rule: allow
port: "22"
- name: Allow HTTP
community.general.ufw:
rule: allow
port: "80"
- name: Allow HTTPS
community.general.ufw:
rule: allow
port: "443"
Sau đó:
- name: Enable firewall
community.general.ufw:
state: enabled
17. Security Rule
Không expose:
5432 PostgreSQL
8080 Todo API
ra Internet.
Mô hình đúng:
Internet
│
├── 80
└── 443
│
▼
Nginx
│
▼
API
│
▼
PostgreSQL
18. Phase 6 — Docker
Tạo Role:
roles/docker/
Nhiệm vụ:
Install Docker
Install Docker Compose
Enable Docker
Start Docker
Add deploy user to docker group
Ví dụ:
- name: Install Docker
ansible.builtin.apt:
name:
- docker.io
- docker-compose-plugin
state: present
19. Enable Docker
- name: Enable Docker
ansible.builtin.service:
name: docker
enabled: true
state: started
Thêm user:
- name: Add deploy user to docker group
ansible.builtin.user:
name: deploy
groups: docker
append: true
20. Phase 7 — Application
Application directory:
/opt/todo/
Cấu trúc:
/opt/todo/
├── docker-compose.yml
├── .env
└── config/
Ansible tạo:
- name: Create application directory
ansible.builtin.file:
path: /opt/todo
state: directory
owner: deploy
group: deploy
mode: "0755"
21. Docker Compose Template
Template:
roles/application/templates/docker-compose.yml.j2
Ví dụ:
services:
api:
image: "{{ app_image }}:{{ app_version }}"
restart: unless-stopped
ports:
- "{{ app_port }}:8080"
environment:
APP_ENVIRONMENT: "{{ app_environment }}"
DATABASE_HOST: "{{ database_host }}"
DATABASE_NAME: "{{ database_name }}"
DATABASE_USERNAME: "{{ database_username }}"
DATABASE_PASSWORD: "{{ database_password }}"
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_DB: "{{ database_name }}"
POSTGRES_USER: "{{ database_username }}"
POSTGRES_PASSWORD: "{{ database_password }}"
22. Environment Variables
Dev:
app_environment: dev
app_version: "1.0.0"
Staging:
app_environment: staging
app_version: "1.0.0"
Production:
app_environment: production
app_version: "1.0.0"
23. Secrets
Không viết:
database_password: "password123"
trong:
group_vars/all.yml
Thay vào đó:
vault.yml
và:
ansible-vault encrypt vault.yml
24. Phase 8 — Deploy Application
Sau khi template:
docker-compose.yml
được deploy:
- name: Start application
community.docker.docker_compose_v2:
project_src: /opt/todo
state: present
Nếu image thay đổi:
Todo API 1.0
↓
Todo API 1.1
Ansible sẽ deploy version mới.
25. Application Version
Đây là một variable rất quan trọng:
app_version: "1.0.0"
Không nên:
latest
trong Production.
Tốt hơn:
todo-api:1.0.0
todo-api:1.1.0
todo-api:1.2.0
Vì:
latest
không đảm bảo reproducibility.
26. Phase 9 — Nginx
Tạo:
roles/nginx/
Nginx đóng vai trò:
Reverse Proxy
Request:
https://todo.example.com
→ Nginx
→:
http://127.0.0.1:8080
27. Nginx Template
roles/nginx/templates/todo.conf.j2
Ví dụ:
server {
listen 80;
server_name {{ app_domain }};
location / {
proxy_pass http://127.0.0.1:{{ app_port }};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
28. Nginx Handler
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
Task:
notify: Restart nginx
29. Phase 10 — Health Check
Application cần có:
GET /health
Ansible kiểm tra:
- name: Check application health
ansible.builtin.uri:
url: "http://127.0.0.1:{{ app_port }}/health"
status_code: 200
register: health_check
retries: 10
delay: 5
until: health_check.status == 200
Điều này tránh tình trạng:
Docker container Running
≠
Application Healthy
30. Verify qua Nginx
Không chỉ kiểm tra:
localhost:8080
mà kiểm tra:
http://localhost
Ví dụ:
- name: Verify nginx endpoint
ansible.builtin.uri:
url: "http://127.0.0.1"
status_code: 200
31. Phase 11 — Logging
Application:
Docker logs
có thể kiểm tra:
docker compose logs
Ansible có thể verify container:
- name: Check running containers
community.docker.docker_container_info:
name: todo-api
Hoặc kiểm tra service:
docker compose ps
32. Phase 12 — Idempotency
Đây là một trong những tiêu chí bắt buộc.
Chạy:
ansible-playbook \
-i inventories/dev/hosts.ini \
site.yml
Lần đầu:
changed=15
Chạy lại:
ansible-playbook \
-i inventories/dev/hosts.ini \
site.yml
Mục tiêu:
changed=0
hoặc gần như không có thay đổi ngoài những task thực sự cần thiết.
33. Đây là tiêu chí quan trọng
Không chấp nhận:
changed=15
mỗi lần chạy.
Nếu mỗi lần chạy đều:
restart nginx
restart docker
restart application
thì automation chưa tốt.
34. Phase 13 — Production Safety
Production không được deploy trực tiếp một cách tùy tiện.
Trước tiên:
ansible-playbook \
-i inventories/production/hosts.ini \
site.yml \
--syntax-check
Sau đó:
ansible-playbook \
-i inventories/production/hosts.ini \
site.yml \
--check \
--diff
Sau khi review:
ansible-playbook \
-i inventories/production/hosts.ini \
site.yml
35. Production Deployment
Nếu production có:
prod01
prod02
không nên deploy đồng thời.
Sử dụng:
serial: 1
Workflow:
prod01
│
▼
Deploy
│
▼
Health Check
│
▼
PASS
│
▼
prod02
Nếu:
prod01
↓
Health Check
↓
FAIL
thì:
STOP
36. Phase 14 — Environment Configuration
Dev
app_environment: dev
app_version: "1.1.0"
app_domain: dev.todo.local
app_debug: true
Staging
app_environment: staging
app_version: "1.1.0"
app_domain: staging.todo.local
app_debug: false
Production
app_environment: production
app_version: "1.0.0"
app_domain: todo.example.com
app_debug: false
Role không thay đổi.
37. Production Validation
Thêm:
- name: Validate production configuration
ansible.builtin.assert:
that:
- app_debug == false
- app_version != "latest"
- database_password is defined
fail_msg: "Invalid production configuration"
when: app_environment == "production"
38. Phase 15 — Backup
Production cần backup database.
Có thể tạo:
roles/backup/
Ví dụ:
/opt/backups/
Ansible configure cron:
- name: Configure database backup
ansible.builtin.cron:
name: "Todo database backup"
minute: "0"
hour: "2"
job: "/opt/scripts/backup.sh"
Mục tiêu:
Every day at 02:00
↓
Database backup
39. Phase 16 — Monitoring Hook
Không cần xây dựng monitoring system hoàn chỉnh trong Final Project.
Nhưng nên chuẩn bị:
/health
/metrics
và verify:
- name: Verify health endpoint
...
Sau này có thể tích hợp:
Prometheus
Grafana
Loki
Alertmanager
vào Kubernetes/DevOps roadmap.
40. Final Project Workflow
Toàn bộ flow:
Fresh Ubuntu Server
│
▼
Bootstrap SSH
│
▼
Create User
│
▼
Secure SSH
│
▼
Install Packages
│
▼
Firewall
│
▼
Docker
│
▼
Application
│
▼
Nginx
│
▼
Health Check
│
▼
Verification
41. Playbook Architecture
Một cách tổ chức tốt:
# site.yml
- name: Provision servers
hosts: all
become: true
roles:
- common
- security
- docker
- name: Deploy application
hosts: application
become: true
roles:
- application
- nginx
- name: Verify deployment
hosts: application
become: true
roles:
- verify
42. Role Responsibilities
common
Package
User
Timezone
Hostname
System configuration
security
SSH
Firewall
Security hardening
docker
Docker
Docker Compose
Docker service
application
Application
Environment
Docker Compose
Deployment
nginx
Nginx
Reverse proxy
Configuration
verify
Health check
Service check
Deployment validation
43. Inventory Production
Ví dụ:
[application]
prod01 ansible_host=192.168.56.13
prod02 ansible_host=192.168.56.14
[production:children]
application
Sau đó:
ansible-inventory \
-i inventories/production/hosts.ini \
--graph
Kết quả:
@all
└── @production
└── @application
├── prod01
└── prod02
44. site.yml không chứa IP
Đây là nguyên tắc quan trọng.
Không:
hosts:
- 192.168.56.13
Mà:
hosts: application
Inventory chịu trách nhiệm:
Who?
Playbook chịu trách nhiệm:
What?
45. Tư duy thiết kế
Đây là một câu rất quan trọng cho người học:
Inventory quyết định "ở đâu", Variables quyết định "với cấu hình nào", Roles quyết định "làm gì".
Ví dụ:
Inventory
│
│ Where?
▼
Production
Variables
│
│ Configuration?
▼
4 replicas
4GB RAM
production domain
Roles
│
│ What?
▼
Install Docker
Configure Nginx
Deploy Application
46. Deployment Script
Ví dụ:
scripts/deploy-production.sh
#!/usr/bin/env bash
set -e
echo "================================="
echo " Production Deployment"
echo "================================="
read -p "Type PRODUCTION to continue: " confirm
if [ "$confirm" != "PRODUCTION" ]; then
echo "Deployment cancelled."
exit 1
fi
ansible-playbook \
-i inventories/production/hosts.ini \
site.yml \
--check \
--diff
read -p "Apply deployment? [y/N]: " deploy
if [ "$deploy" != "y" ]; then
echo "Deployment cancelled."
exit 0
fi
ansible-playbook \
-i inventories/production/hosts.ini \
site.yml \
--ask-vault-pass
Đây là một guardrail đơn giản.
47. Testing
Final Project phải có testing.
Syntax
ansible-playbook site.yml --syntax-check
Inventory
ansible-inventory \
-i inventories/dev/hosts.ini \
--graph
Connectivity
ansible \
all \
-i inventories/dev/hosts.ini \
-m ping
Dry Run
ansible-playbook \
-i inventories/dev/hosts.ini \
site.yml \
--check
Diff
ansible-playbook \
-i inventories/dev/hosts.ini \
site.yml \
--check \
--diff
48. Idempotency Test
Chạy:
ansible-playbook \
-i inventories/dev/hosts.ini \
site.yml
Sau đó chạy lại:
ansible-playbook \
-i inventories/dev/hosts.ini \
site.yml
Yêu cầu:
First run:
changed > 0
Second run:
changed ≈ 0
49. Failure Test
Cố tình thay đổi:
Docker image
Nginx config
Application port
Database password
Sau đó chạy lại Ansible.
Quan sát:
changed
và:
handlers
được trigger như thế nào.
50. Recovery Test
Cố tình stop application:
docker compose stop
Sau đó chạy:
ansible-playbook \
-i inventories/dev/hosts.ini \
site.yml
Ansible phải đưa server về trạng thái mong muốn:
Application
↓
Running
Đây chính là:
Desired State
51. Drift Test
SSH vào server:
ssh deploy@server
Thay đổi:
Nginx config
Application config
Service state
Sau đó:
ansible-playbook \
-i inventories/dev/hosts.ini \
site.yml
Ansible phải reconcile:
Actual State
↓
≠
↓
Desired State
↓
Ansible
↓
Desired State
52. Security Test
Kiểm tra:
sudo ufw status
Phải đảm bảo chỉ expose:
22
80
443
Kiểm tra SSH:
Password authentication
phải disabled nếu đó là yêu cầu của project.
53. Application Test
Kiểm tra:
curl http://server/health
Kết quả:
200 OK
Kiểm tra Docker:
docker compose ps
Expected:
todo-api
postgres
đang:
Running
54. Nginx Test
curl -I http://server
Expected:
HTTP/1.1 200 OK
55. Production Test
Production:
prod01
prod02
Deploy:
prod01
↓
Health check
↓
PASS
↓
prod02
↓
Health check
↓
PASS
Nếu:
prod01
↓
FAIL
thì:
prod02
↓
NOT DEPLOYED
56. Acceptance Criteria
Final Project chỉ được xem là hoàn thành khi đáp ứng:
Infrastructure
- [ ] Server có thể được provision bằng Ansible.
- [ ] Deploy user được tạo.
- [ ] SSH key được cấu hình.
- [ ] SSH password authentication được disable.
- [ ] Firewall được cấu hình.
- [ ] Docker được cài.
- [ ] Docker tự start sau reboot.
Application
- [ ] Application được deploy bằng Ansible.
- [ ] PostgreSQL được deploy.
- [ ] Nginx được deploy.
- [ ] Reverse proxy hoạt động.
- [ ]
/healthtrả về HTTP 200.
Automation
- [ ] Có Roles.
- [ ] Có Variables.
- [ ] Có Templates.
- [ ] Có Handlers.
- [ ] Có Vault.
- [ ] Có multi-environment.
- [ ] Playbook idempotent.
Production
- [ ] Có
--check. - [ ] Có
--diff. - [ ] Có validation.
- [ ] Có rolling deployment.
- [ ] Có health check.
- [ ] Có production guardrail.
57. Challenge nâng cao
Nếu muốn đánh giá người học ở trình độ Senior, hãy thêm các yêu cầu sau.
Challenge 1 — Rolling Deployment
Production:
4 servers
Deploy:
serial: 1
Health check sau mỗi server.
Challenge 2 — Automatic Rollback
Nếu health check fail:
New Version
↓
Health Check
↓
FAIL
↓
Rollback
↓
Previous Version
Ví dụ:
1.2.0
fail → rollback:
1.1.0
58. Challenge 3 — Artifact Promotion
Thiết kế:
Build:
todo-api:1.5.0
Sau đó:
DEV
↓
STAGING
↓
PRODUCTION
Không build lại application giữa các environment.
59. Challenge 4 — CI/CD
Đưa Ansible vào pipeline:
Git Push
│
▼
CI
│
├── ansible-lint
├── syntax-check
└── tests
│
▼
DEV
│
▼
STAGING
│
▼
Manual Approval
│
▼
PRODUCTION
60. Challenge 5 — Ansible Lint
Cài:
ansible-lint
Sau đó:
ansible-lint .
Mục tiêu:
0 errors
Đây là bước rất đáng thêm nếu muốn project mang tính production.
61. Challenge 6 — Molecule
Đối với Role:
common
docker
nginx
application
có thể viết test bằng:
Molecule
Mục tiêu:
Role
↓
Create Test Instance
↓
Apply Role
↓
Verify
↓
Destroy
Đây là bước nâng cao dành cho người học muốn tiến gần đến Senior/Platform Engineer.
62. Challenge 7 — Secrets Management
Thay vì chỉ:
Ansible Vault
hãy thiết kế architecture:
CI/CD
│
▼
Secret Manager
│
▼
Ansible
│
▼
Production
Ví dụ có thể nghiên cứu:
HashiCorp Vault
AWS Secrets Manager
GCP Secret Manager
Azure Key Vault
Mục tiêu không phải học tất cả trong Lab này, mà hiểu:
Production secret management không nên phụ thuộc vào việc copy password vào repository.
63. Challenge 8 — Monitoring
Sau deployment:
Application
│
├── /health
└── /metrics
│
▼
Prometheus
│
▼
Grafana
Có thể kết hợp với kiến thức Monitoring/Observability ở roadmap Kubernetes trước đó.
64. Challenge 9 — Centralized Logging
Application:
Docker
│
▼
Logs
│
▼
Loki / Fluent Bit
│
▼
Grafana
Mục tiêu:
Ansible
↓
Provision server
↓
Application
↓
Observability
65. Challenge 10 — Disaster Recovery
Xóa application:
docker compose down
hoặc giả lập server mới:
Fresh Ubuntu Server
Sau đó:
ansible-playbook site.yml
Mục tiêu:
Fresh Server
↓
Ansible
↓
Production-ready Server
Đây mới là bài test thực sự của Infrastructure as Code.
66. Final Architecture
Sau khi hoàn thành toàn bộ Challenge:
Git
│
▼
CI/CD Pipeline
│
┌─────────┴─────────┐
│ │
Ansible Lint Tests
│ │
└─────────┬─────────┘
▼
Ansible
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
DEV STAGING PRODUCTION
│ │ │
▼ ▼ ▼
Server Server Server(s)
│ │ │
└─────────────────┼─────────────────┘
│
Common Roles
│
┌───────────┬───────┼────────┬──────────┐
▼ ▼ ▼ ▼ ▼
Common Security Docker Nginx Application
│ │ │ │ │
└───────────┴───────┴────────┴──────────┘
│
▼
Health Check
│
▼
Monitoring
67. Final Deliverables
Người học phải nộp:
ansible-final-project/
bao gồm:
├── README.md
├── ansible.cfg
├── site.yml
│
├── inventories/
│ ├── dev/
│ ├── staging/
│ └── production/
│
├── roles/
│ ├── common/
│ ├── security/
│ ├── docker/
│ ├── nginx/
│ ├── application/
│ └── verify/
│
├── playbooks/
│ ├── provision.yml
│ ├── deploy.yml
│ └── verify.yml
│
└── scripts/
├── deploy-dev.sh
├── deploy-staging.sh
└── deploy-production.sh
Kèm theo:
Architecture Diagram
Deployment Guide
Troubleshooting Guide
Environment Documentation
Security Documentation
68. README phải giải thích được
Một Senior không chỉ viết code.
README cần trả lời:
Architecture
Hệ thống hoạt động như thế nào?
Installation
Làm sao chạy project?
Environment
Dev / Staging / Production khác nhau thế nào?
Deployment
Deploy như thế nào?
Rollback
Rollback như thế nào?
Secrets
Secret được quản lý như thế nào?
Troubleshooting
Nếu application không chạy thì debug thế nào?
69. Tiêu chí chấm điểm
Có thể sử dụng thang điểm:
| Hạng mục | Điểm |
|---|---|
| Inventory Architecture | 10 |
| Variables & Templates | 10 |
| Roles | 15 |
| Server Provisioning | 15 |
| Security | 10 |
| Application Deployment | 10 |
| Secrets / Vault | 10 |
| Idempotency | 10 |
| Multi-Environment | 5 |
| Documentation | 5 |
| Tổng | 100 |
70. Phân loại trình độ
Junior — 60–70 điểm
Có thể:
Provision server
Install Docker
Deploy application
nhưng còn phụ thuộc vào hướng dẫn.
Mid-level — 70–85 điểm
Có thể:
Roles
Variables
Templates
Vault
Multi-environment
Idempotency
và tự debug.
Senior — 85–100 điểm
Có thể:
Design architecture
↓
Security
↓
Multi-environment
↓
Production deployment
↓
Rolling deployment
↓
Health check
↓
Rollback
↓
CI/CD
↓
Observability
và quan trọng nhất:
Có khả năng giải thích tại sao architecture được thiết kế như vậy, chứ không chỉ biết viết Ansible YAML.
71. Bài kiểm tra cuối cùng
Đây là phần tôi khuyến nghị bắt buộc nếu mục tiêu của series là đào tạo người mới lên Senior.
Cho người học một:
Fresh Ubuntu Server
và chỉ cung cấp:
IP
SSH access
Application Git repository
Application requirements
Không cung cấp:
Playbook
Role
Inventory mẫu
Yêu cầu:
Trong vòng một khoảng thời gian quy định, hãy xây dựng toàn bộ automation để biến server mới thành Production Application Server.
Kết quả mong muốn:
Fresh Ubuntu
│
│ ansible-playbook
▼
┌──────────────────────┐
│ Production Server │
│ │
│ ✓ SSH Security │
│ ✓ Deploy User │
│ ✓ Firewall │
│ ✓ Docker │
│ ✓ Docker Compose │
│ ✓ PostgreSQL │
│ ✓ Todo API │
│ ✓ Nginx │
│ ✓ Secrets │
│ ✓ Health Check │
│ ✓ Logging │
│ ✓ Backup │
│ ✓ Idempotent │
└──────────────────────┘
Sau đó destroy server và dựng lại từ đầu.
Nếu người học có thể làm được việc này một cách có cấu trúc, giải thích được design decision, xử lý được failure và chứng minh được idempotency + reproducibility + security, thì họ đã vượt qua mục tiêu cốt lõi của series Ansible này.
72. Tổng kết toàn bộ Phase Ansible
Sau 14 Lab, roadmap hoàn chỉnh sẽ là:
LAB 01 Ansible Fundamentals
↓
LAB 02 Inventory & SSH
↓
LAB 03 Ad-Hoc Commands
↓
LAB 04 Playbook Fundamentals
↓
LAB 05 Variables & Facts
↓
LAB 06 Templates & Jinja2
↓
LAB 07 Handlers & Idempotency
↓
LAB 08 Roles
↓
LAB 09 Server Provisioning
↓
LAB 10 Application Deployment
↓
LAB 11 Secrets & Vault
↓
LAB 12 Troubleshooting
↓
LAB 13 Multi-Environment
↓
LAB 14 FINAL PROJECT
│
├── Provisioning
├── Security
├── Docker
├── Application
├── Nginx
├── Secrets
├── Dev/Staging/Prod
├── Idempotency
├── Health Check
├── Rolling Deployment
├── Rollback
└── Production Automation
Điểm quan trọng nhất của Lab 14: đừng biến nó thành một bài lab hướng dẫn từng câu lệnh. Hãy biến nó thành một project mở, trong đó các Lab 1–13 chính là kiến thức nền để người học tự giải quyết bài toán. Như vậy series mới thực sự có khả năng đưa một người mới từ "biết Ansible" → "có khả năng thiết kế và vận hành automation ở production".
All rights reserved