0

Lab 9 — Ansible Server Provisioning

Mục tiêu: Sau Lab này, người học có thể sử dụng Ansible để tự động dựng một server từ trạng thái gần như sạch thành một application server sẵn sàng để deploy.

Đây là Lab rất quan trọng vì từ đây Ansible bắt đầu được sử dụng đúng với vai trò Infrastructure as Code thay vì chỉ chạy command từ xa.


1. Bối cảnh

Ở Lab 8, chúng ta đã biết tổ chức automation bằng:

Roles

Ví dụ:

roles/
├── common/
├── docker/
├── nginx/
└── application/

Nhưng hiện tại chúng ta vẫn đang giả định server đã có sẵn khá nhiều thứ.

Trong thực tế, bạn có thể nhận một server mới:

New Ubuntu Server
        │
        ├── Chưa có Docker
        ├── Chưa có Docker Compose
        ├── Chưa có user deploy
        ├── Chưa có directory application
        ├── Chưa có package cần thiết
        ├── Chưa cấu hình SSH
        └── Chưa có cấu hình cơ bản

DevOps Engineer cần biến nó thành:

                    Ansible
                       │
                       ▼
                Fresh Server
                       │
        ┌──────────────┼──────────────┐
        ▼              ▼              ▼
     Common          Docker          SSH
        │              │              │
        └──────────────┼──────────────┘
                       ▼
                Ready Server
                       │
                       ▼
                Application Deploy

Đó chính là Server Provisioning.


2. Provisioning là gì?

Provisioning là quá trình chuẩn bị một server để nó có thể thực hiện một vai trò cụ thể.

Ví dụ:

Raw Server
    ↓
OS configuration
    ↓
Packages
    ↓
Users
    ↓
SSH
    ↓
Docker
    ↓
Docker Compose
    ↓
Directories
    ↓
System configuration
    ↓
Application-ready Server

Provisioning không nhất thiết là deploy application.

Có thể phân biệt:

Provisioning
    ↓
Chuẩn bị server

và:

Deployment
    ↓
Đưa application lên server

Ở Lab 9 chúng ta tập trung vào Provisioning.


3. Provisioning vs Deployment

Đây là distinction rất quan trọng.

Provisioning

Server
 ├── User
 ├── SSH
 ├── Packages
 ├── Docker
 ├── Directories
 └── System configuration

Deployment

Application
 ├── Docker image
 ├── Configuration
 ├── Database
 └── Service

Có thể hình dung:

              Server
                │
        ┌───────┴────────┐
        │                │
   Provisioning      Deployment
        │                │
        ▼                ▼
   Server Ready      App Running

4. Scenario của Lab

Chúng ta sẽ xây dựng một Todo Application Server.

Server ban đầu:

Ubuntu Server

Sau provisioning:

Ubuntu Server
│
├── Basic packages
│
├── deploy user
│
├── SSH configuration
│
├── Docker
│
├── Docker Compose
│
├── Application directories
│
└── System configuration

Chưa deploy application.


5. Kiến trúc

Project:

ansible-lab-09/
│
├── ansible.cfg
├── inventory/
│   └── hosts.ini
│
├── site.yml
│
├── group_vars/
│   └── all.yml
│
└── roles/
    ├── common/
    ├── users/
    ├── ssh/
    ├── docker/
    └── application_server/

Flow:

site.yml
   │
   ├── common
   │
   ├── users
   │
   ├── ssh
   │
   ├── docker
   │
   └── application_server

6. Chuẩn bị Server

Bạn cần một Ubuntu Server.

Có thể sử dụng:

  • VM
  • Multipass
  • VirtualBox
  • VMware
  • Cloud VM
  • AWS EC2
  • DigitalOcean
  • Azure
  • GCP

Trong Lab này giả sử:

Control Node
    │
    │ SSH
    ▼
Ubuntu Server
192.168.56.101

7. Kiểm tra SSH

Từ Control Node:

ssh ubuntu@192.168.56.101

Nếu SSH hoạt động:

ubuntu@server:~$

Thoát:

exit

8. Tạo Project

mkdir ansible-lab-09
cd ansible-lab-09

Tạo:

mkdir -p inventory group_vars roles

9. ansible.cfg

[defaults]
inventory = ./inventory/hosts.ini
roles_path = ./roles
host_key_checking = False

Trong production, không nên tùy tiện tắt:

host_key_checking = False

Ở lab dùng để tránh SSH host-key friction.

Production nên quản lý host keys đúng cách.


10. Inventory

Tạo:

inventory/hosts.ini
[application_servers]
app-01 ansible_host=192.168.56.101

[all:vars]
ansible_user=ubuntu

Kiểm tra:

ansible-inventory --graph

Kết quả:

@all:
  |--@application_servers:
  |  |--app-01

11. Test kết nối

ansible all -m ansible.builtin.ping

Kỳ vọng:

app-01 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

12. Global Variables

Tạo:

group_vars/all.yml
---
timezone: Asia/Tokyo

deploy_user: deploy

application_name: todo

application_dir: /opt/todo

docker_packages:
  - docker-ce
  - docker-ce-cli
  - containerd.io
  - docker-buildx-plugin
  - docker-compose-plugin

Ở đây chúng ta bắt đầu sử dụng Variables từ Lab 5 kết hợp với Roles từ Lab 8.


13. Role common

Tạo:

ansible-galaxy role init roles/common

Cấu trúc:

roles/common/
├── defaults/
├── handlers/
├── tasks/
├── templates/
└── vars/

14. Common Packages

File:

roles/common/tasks/main.yml
---
- name: Update apt cache
  ansible.builtin.apt:
    update_cache: true
    cache_valid_time: 3600

- name: Install common packages
  ansible.builtin.apt:
    name:
      - curl
      - wget
      - git
      - vim
      - unzip
      - ca-certificates
      - gnupg
      - lsof
      - htop
    state: present

15. Tại sao dùng state: present?

Không dùng:

apt install curl

mà:

state: present

Ý nghĩa:

Đảm bảo package tồn tại.

Nếu package đã tồn tại:

changed = false

Nếu chưa tồn tại:

changed = true

Đây chính là Idempotency từ Lab 7.


16. Configure Timezone

Thêm:

- name: Set timezone
  community.general.timezone:
    name: "{{ timezone }}"

Nếu máy chưa có collection:

ansible-galaxy collection install community.general

Kiểm tra:

timedatectl

17. Role users

Tạo:

ansible-galaxy role init roles/users

File:

roles/users/tasks/main.yml
---
- name: Create deploy user
  ansible.builtin.user:
    name: "{{ deploy_user }}"
    shell: /bin/bash
    create_home: true
    state: present

Sau khi chạy:

id deploy

Kết quả:

uid=1001(deploy)

18. Add User vào Docker Group

Sau này chúng ta muốn:

docker ps

mà không cần:

sudo docker ps

Task:

- name: Add deploy user to docker group
  ansible.builtin.user:
    name: "{{ deploy_user }}"
    groups: docker
    append: true

Điểm cần nhớ:

Group membership có thể cần logout/login lại mới có hiệu lực đối với session hiện tại.


19. SSH Key

Giả sử public key của Control Node:

~/.ssh/id_ed25519.pub

Có thể sử dụng:

- name: Configure deploy user SSH key
  ansible.posix.authorized_key:
    user: "{{ deploy_user }}"
    state: present
    key: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/id_ed25519.pub') }}"

Cần collection:

ansible-galaxy collection install ansible.posix

20. Tại sao không copy private key?

Tuyệt đối không làm:

Control Node
    │
    │ private key
    ▼
Server

Private key phải nằm ở nơi cần dùng nó, thông thường là:

Control Node
~/.ssh/id_ed25519

Server chỉ cần:

~/.ssh/authorized_keys

Tư duy:

Private Key → NEVER upload to server
Public Key  → authorized_keys

21. Role ssh

Tạo:

ansible-galaxy role init roles/ssh

Mục tiêu:

SSH
├── Configure
├── Validate
└── Reload

22. SSH Configuration

Tạo:

roles/ssh/templates/sshd_config.j2

Ví dụ:

Port {{ ssh_port }}

PubkeyAuthentication yes

PasswordAuthentication {{ ssh_password_authentication }}

PermitRootLogin {{ ssh_permit_root_login }}

Variables:

ssh_port: 22
ssh_password_authentication: "no"
ssh_permit_root_login: "no"

23. Deploy SSH Configuration

---
- name: Deploy sshd configuration
  ansible.builtin.template:
    src: sshd_config.j2
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: "0600"
    validate: "/usr/sbin/sshd -t -f %s"
  notify: Restart ssh

Đây là pattern chúng ta đã học:

Template
   ↓
Validate
   ↓
Changed?
   ↓
Notify
   ↓
Restart SSH

24. SSH Handler

roles/ssh/handlers/main.yml
---
- name: Restart ssh
  ansible.builtin.service:
    name: ssh
    state: restarted

Cực kỳ quan trọng: SSH là service quản lý kết nối của chính Ansible.

Nếu cấu hình sai:

Ansible
   ↓
Modify SSH
   ↓
SSH broken
   ↓
Connection lost

Vì vậy luôn phải:

validate sshd_config

trước khi reload/restart.


25. Role docker

Tạo:

ansible-galaxy role init roles/docker

Docker trên Ubuntu nên được cài từ repository phù hợp thay vì chỉ chạy:

apt install docker.io

Đối với lab, chúng ta có thể sử dụng Docker's official repository.


26. Docker Repository

Task:

---
- name: Install Docker prerequisites
  ansible.builtin.apt:
    name:
      - ca-certificates
      - curl
    state: present

- name: Create Docker keyring directory
  ansible.builtin.file:
    path: /etc/apt/keyrings
    state: directory
    mode: "0755"

Sau đó cấu hình Docker repository và GPG key.

Một điểm quan trọng:

Repository configuration cũng phải được quản lý bằng Ansible, không nên yêu cầu người học SSH vào server rồi tự chạy từng command.


27. Install Docker

Ví dụ task:

- name: Install Docker packages
  ansible.builtin.apt:
    name:
      - docker-ce
      - docker-ce-cli
      - containerd.io
      - docker-buildx-plugin
      - docker-compose-plugin
    state: present
    update_cache: true

28. Enable Docker

- name: Ensure Docker is enabled and running
  ansible.builtin.service:
    name: docker
    state: started
    enabled: true

Kỳ vọng:

Docker
├── installed
├── enabled
└── running

29. Kiểm tra Docker

docker --version

và:

docker compose version

Sau đó:

systemctl status docker

30. Role application_server

Role này chuẩn bị filesystem cho application.

Tạo:

ansible-galaxy role init roles/application_server

31. Tạo Application Directory

---
- name: Create application directory
  ansible.builtin.file:
    path: "{{ application_dir }}"
    state: directory
    owner: "{{ deploy_user }}"
    group: "{{ deploy_user }}"
    mode: "0755"

Ví dụ:

/opt/todo

32. Tạo Subdirectories

Có thể tạo:

- name: Create application subdirectories
  ansible.builtin.file:
    path: "{{ application_dir }}/{{ item }}"
    state: directory
    owner: "{{ deploy_user }}"
    group: "{{ deploy_user }}"
    mode: "0755"
  loop:
    - config
    - data
    - logs
    - backups

Kết quả:

/opt/todo/
├── config/
├── data/
├── logs/
└── backups/

Đây là một ví dụ tốt về automation thay vì chạy:

mkdir
mkdir
mkdir
mkdir

33. Tạo Application Environment File

Template:

roles/application_server/templates/app.env.j2
APP_NAME={{ application_name }}
APP_ENV={{ app_environment }}
APP_PORT={{ app_port }}

Variables:

application_name: todo
app_environment: production
app_port: 8080

Task:

- name: Deploy application environment
  ansible.builtin.template:
    src: app.env.j2
    dest: "{{ application_dir }}/config/app.env"
    owner: "{{ deploy_user }}"
    group: "{{ deploy_user }}"
    mode: "0640"

34. Lưu ý về Secrets

File:

app.env

có thể chứa:

DATABASE_PASSWORD
JWT_SECRET
API_KEY

Không nên để secret trực tiếp:

database_password: "123456"

Trong Lab này chỉ tạo structure.

Secret management sẽ được xử lý kỹ ở:

Lab 11 — Ansible Secrets & Vault


35. Main Playbook

Tạo:

site.yml
---
- name: Provision application servers
  hosts: application_servers
  become: true

  roles:
    - common
    - users
    - docker
    - ssh
    - application_server

Bây giờ Playbook chỉ mô tả:

Server cần có:
    Common
    Users
    Docker
    SSH
    Application structure

Không cần biết từng Task bên trong.


36. Thứ tự Role rất quan trọng

Chúng ta có:

common
   ↓
users
   ↓
docker
   ↓
ssh
   ↓
application_server

Tại sao?

common

Cài package cơ bản.

users

Tạo deploy.

docker

Cài Docker.

ssh

Configure access.

application_server

Sử dụng deploy user và filesystem.

Đây chính là dependency ordering.


37. Chạy Provisioning

ansible-playbook site.yml

Ansible sẽ:

app-01
 │
 ├── common
 │
 ├── users
 │
 ├── docker
 │
 ├── ssh
 │
 └── application_server

38. Kiểm tra kết quả

SSH:

ssh deploy@192.168.56.101

Kiểm tra user:

whoami

Kỳ vọng:

deploy

39. Kiểm tra Docker

docker ps

Nếu user vừa được thêm vào group:

groups

Nếu chưa thấy:

docker

logout/login lại.


40. Kiểm tra Directory

ls -la /opt/todo

Kỳ vọng:

config
data
logs
backups

41. Kiểm tra SSH

sshd -t

Nếu không có output:

Configuration OK

Kiểm tra service:

systemctl status ssh

42. Test Idempotency

Đây là phần bắt buộc.

Chạy:

ansible-playbook site.yml

Lần đầu:

changed > 0

Sau đó chạy:

ansible-playbook site.yml

Lần hai:

changed = 0

Nếu lần thứ hai vẫn:

changed > 0

thì phải tìm nguyên nhân.


43. Debug Idempotency

Ví dụ:

TASK [Create directory]
changed

mỗi lần.

Có thể do:

permissions
owner
group
path

không ổn định.

Hoặc:

ansible.builtin.command

được sử dụng không đúng.

Hoặc template luôn tạo ra output khác nhau.


44. Check Mode

Trước khi provisioning production:

ansible-playbook site.yml --check

Ansible sẽ cố gắng mô phỏng thay đổi.

Kết hợp:

ansible-playbook site.yml --check --diff

để xem configuration difference.


45. Tags

Khi project lớn, có thể thêm Tags.

Ví dụ:

- name: Install Docker
  ansible.builtin.apt:
    name: docker-ce
    state: present
  tags:
    - docker

Sau đó:

ansible-playbook site.yml --tags docker

Chỉ chạy phần Docker.


46. Tags theo Role

Có thể:

roles:
  - role: common
    tags:
      - common

  - role: docker
    tags:
      - docker

  - role: ssh
    tags:
      - ssh

Sau đó:

ansible-playbook site.yml --tags docker

47. --limit

Giả sử Inventory:

app-01
app-02
app-03

Muốn chỉ provision:

app-02

dùng:

ansible-playbook site.yml --limit app-02

Đây là kỹ năng rất quan trọng khi làm Production.


48. --limit trong Production

Không nên:

ansible-playbook site.yml

ngay lập tức trên:

100 servers

nếu chưa test.

Có thể:

1 server
 ↓
3 servers
 ↓
10 servers
 ↓
100 servers

Ví dụ:

ansible-playbook site.yml --limit app-01

Sau khi kiểm tra:

ansible-playbook site.yml --limit app-01,app-02

49. Serial Deployment

Ở level cao hơn, có thể sử dụng:

serial: 1

Ví dụ:

---
- name: Provision application servers
  hosts: application_servers
  become: true
  serial: 1

  roles:
    - common
    - docker
    - ssh

Ansible sẽ xử lý:

app-01
   ↓
app-02
   ↓
app-03

thay vì:

app-01
app-02
app-03
   ↓
cùng lúc

Đây là tư duy rollout an toàn.


50. Provisioning và Failure

Giả sử:

app-01 → SUCCESS
app-02 → SUCCESS
app-03 → FAILED

Không nên chạy lại một cách mù quáng.

Trước tiên:

ansible-playbook site.yml --limit app-03

Debug:

Why did app-03 fail?

Sau khi fix:

ansible-playbook site.yml --limit app-03

Đây là workflow thực tế.


51. become

Provisioning thường cần quyền root.

Ví dụ:

hosts: application_servers
become: true

Ansible sẽ thực hiện:

deploy user
      ↓
sudo
      ↓
root

Các thao tác như:

apt install
/etc
systemd
user creation
SSH config

thường cần quyền cao.


52. Không nên SSH bằng root

Mô hình không tốt:

Internet
   │
   │ SSH
   ▼
root

Tốt hơn:

Developer / CI
       │
       │ SSH Key
       ▼
deploy user
       │
       │ sudo
       ▼
root

Đây là một nguyên tắc security quan trọng.


53. Tại sao cần deploy user?

Không nên để:

application
    ↓
root

Thay vào đó:

application
    ↓
deploy

với:

sudo

chỉ khi cần.

Điều này giảm blast radius nếu application bị compromise.


54. Provisioning hoàn chỉnh

Bây giờ chúng ta có:

                    Ansible
                       │
                       ▼
                  New Server
                       │
             ┌─────────┴─────────┐
             ▼                   ▼
          Common               Users
             │                   │
             ▼                   ▼
          Packages            deploy
             │                   │
             └─────────┬─────────┘
                       ▼
                     Docker
                       │
                       ▼
                      SSH
                       │
                       ▼
              Application Server

Đây là kết quả chính của Lab.


55. Exercise 1 — Provision Basic Server

Tạo Role:

common

Cài:

curl
git
vim
htop
unzip

Yêu cầu:

Run 1 → changed
Run 2 → changed = 0

56. Exercise 2 — Deploy User

Tạo:

deploy

Yêu cầu:

username: deploy
shell: /bin/bash
home: /home/deploy

Thêm vào:

sudo

và:

docker

group.


57. Exercise 3 — SSH Key

Copy public key của Control Node vào:

/home/deploy/.ssh/authorized_keys

Test:

ssh deploy@server

Không sử dụng password.


58. Exercise 4 — Docker

Provision:

Docker Engine
Docker Compose plugin

Kiểm tra:

docker --version
docker compose version

Sau đó:

docker run --rm hello-world

59. Exercise 5 — Application Filesystem

Tạo:

/opt/todo/
├── config/
├── data/
├── logs/
└── backups/

Owner:

deploy:deploy

Permissions:

0755

60. Exercise 6 — Environment Configuration

Template:

app.env.j2

Variables:

app_name: todo
app_environment: production
app_port: 8080

Kết quả:

/opt/todo/config/app.env

61. Exercise 7 — Full Provisioning

Chạy:

ansible-playbook site.yml

Sau đó verify:

✓ Packages
✓ User
✓ SSH
✓ Docker
✓ Docker Compose
✓ Directories
✓ Application configuration

62. Exercise 8 — Destroy and Rebuild

Đây là bài tập rất quan trọng.

Xóa VM hoặc tạo một VM Ubuntu mới.

Server:

Fresh Ubuntu

Không tự SSH vào server để cài Docker.

Chỉ chạy:

ansible-playbook site.yml

Sau đó kiểm tra:

Docker
User
SSH
Directories
Packages

Nếu toàn bộ hoạt động:

Bạn đã thực sự xây dựng được một provisioning automation.


63. Exercise 9 — New Server Challenge

Tạo:

app-02

Không sửa Role.

Chỉ thêm Inventory:

[application_servers]
app-01 ansible_host=192.168.56.101
app-02 ansible_host=192.168.56.102

Chạy:

ansible-playbook site.yml

Mục tiêu:

app-01 → Ready
app-02 → Ready

Đây chính là sức mạnh của Infrastructure as Code.


64. Exercise 10 — Production Simulation

Giả sử bạn có:

app-01
app-02
app-03

Provision theo thứ tự:

app-01
   ↓
verify
   ↓
app-02
   ↓
verify
   ↓
app-03

Sử dụng:

serial: 1

và:

--limit

65. Tư duy Senior #1 — Server phải Disposable

Một tư duy rất quan trọng:

Đừng coi server là thứ phải được cấu hình thủ công và giữ nguyên mãi mãi.

Thay vào đó:

Server chết
   ↓
Tạo server mới
   ↓
Ansible
   ↓
Ready

Mô hình:

Infrastructure
     ↓
Code
     ↓
Rebuild

Đây là một trong những nền tảng của Cloud và DevOps.


66. Tư duy Senior #2 — Không SSH thủ công để sửa Production

Không nên:

SSH
 ↓
vim /etc/...
 ↓
systemctl restart

sau đó quên mất mình đã thay đổi gì.

Tốt hơn:

Git
 ↓
Ansible
 ↓
Server

Thay đổi được:

Version controlled
Reviewable
Repeatable
Auditable

67. Tư duy Senior #3 — Infrastructure cũng là Code

Ví dụ:

deploy_user: deploy
timezone: Asia/Tokyo
docker_enabled: true

được lưu trong Git.

Do đó:

Infrastructure
      ↓
Code
      ↓
Git
      ↓
Review
      ↓
Deploy

Infrastructure bắt đầu có lifecycle giống application code.


68. Tư duy Senior #4 — Provisioning phải Idempotent

Một provisioning script tốt:

Run 1
 ↓
Build server

Run 2:

Run 2
 ↓
Nothing unnecessary

Không nên:

Run 2
 ↓
Reinstall Docker
 ↓
Recreate user
 ↓
Restart everything

69. Tư duy Senior #5 — Fail Fast

Ví dụ SSH configuration.

Không nên:

Deploy bad config
 ↓
Restart SSH
 ↓
Connection lost

Nên:

Generate
 ↓
Validate
 ↓
Deploy
 ↓
Restart

Tương tự:

Nginx
sshd
Docker
Application config

Validation là một phần của provisioning production-grade.


70. Tư duy Senior #6 — Không Hard-code Environment

Không nên:

server_name: production.example.com

trong Role.

Nên:

Role
 ↓
Variable
 ↓
Environment

Ví dụ:

Dev
server_name: todo.dev.example.com

Staging
server_name: todo.staging.example.com

Production
server_name: todo.example.com

Role vẫn giữ nguyên.

Chúng ta sẽ phát triển ý tưởng này ở:

Lab 13 — Ansible với nhiều Environment


71. Tư duy Senior #7 — Provisioning phải có thể Review

Một engineer khác nên có thể nhìn vào:

site.yml

và hiểu:

common
docker
ssh
application_server

Nếu muốn biết chi tiết:

roles/docker/
roles/ssh/

Điều này tốt hơn một Playbook 1.500 dòng.


72. Kiến trúc sau Lab 9

Đến đây project đã tiến hóa:

Lab 1
Fundamentals
     ↓
Lab 4
Playbook
     ↓
Lab 5
Variables
     ↓
Lab 6
Templates
     ↓
Lab 7
Handlers + Idempotency
     ↓
Lab 8
Roles
     ↓
Lab 9
Server Provisioning

Tư duy:

Run Commands
     ↓
Write Playbooks
     ↓
Manage Desired State
     ↓
Create Reusable Roles
     ↓
Provision Entire Servers

Đây là bước chuyển từ:

Ansible user

sang:

Infrastructure Automation Engineer


73. Checklist hoàn thành Lab 9

Người học cần có khả năng:

  • [ ] Hiểu Server Provisioning.
  • [ ] Phân biệt Provisioning và Deployment.
  • [ ] Tạo server từ trạng thái sạch.
  • [ ] Cài package bằng Ansible.
  • [ ] Tạo user.
  • [ ] Quản lý group.
  • [ ] Quản lý SSH public key.
  • [ ] Cấu hình SSH.
  • [ ] Validate SSH configuration.
  • [ ] Cài Docker.
  • [ ] Cài Docker Compose plugin.
  • [ ] Enable và start Docker.
  • [ ] Tạo application directories.
  • [ ] Quản lý ownership/permissions.
  • [ ] Sử dụng Jinja2 trong provisioning.
  • [ ] Sử dụng Roles để tổ chức provisioning.
  • [ ] Sử dụng become.
  • [ ] Sử dụng --check.
  • [ ] Sử dụng --diff.
  • [ ] Sử dụng --limit.
  • [ ] Hiểu serial.
  • [ ] Kiểm tra Idempotency.
  • [ ] Rebuild một server mới chỉ bằng Ansible.
  • [ ] Hiểu tại sao không nên cấu hình Production thủ công bằng SSH.

74. Final Project — Build a Production-Ready Server

Đây là bài quan trọng nhất của Lab.

Bạn cần xây dựng:

                   Ansible Control Node
                           │
                           │ SSH
                           ▼
                    Ubuntu Server
                           │
          ┌────────────────┼────────────────┐
          │                │                │
          ▼                ▼                ▼
       Common           Users             SSH
          │                │                │
          └────────────────┼────────────────┘
                           ▼
                         Docker
                           │
                           ▼
                  Application Server
                           │
              ┌────────────┼────────────┐
              ▼            ▼            ▼
           config         data         logs

Server cuối cùng phải đạt:

✓ Base packages installed
✓ deploy user created
✓ SSH key authentication
✓ Root SSH disabled
✓ Password SSH disabled
✓ Docker installed
✓ Docker Compose installed
✓ Docker enabled
✓ Docker running
✓ /opt/todo created
✓ Correct ownership
✓ Application config generated
✓ All tasks idempotent

Và quan trọng nhất:

ansible-playbook site.yml

có thể biến:

Fresh Ubuntu Server

thành:

Application-ready Server

mà không cần SSH vào server và chạy thủ công bất kỳ command cài đặt nào.

Đây chính là tiêu chuẩn mà người học nên đạt được sau Lab 9 trước khi bước sang Lab 10 — Ansible Application Deployment.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí