0

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:

  1. Cài Nginx.
  2. Đảm bảo Nginx được enable khi server reboot.
  3. Đảm bảo Nginx đang chạy.
  4. Chạy lại Playbook không tạo thay đổi không cần thiết.
  5. 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

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í