hoatranlab.io.vn Zalo: 0917516878 Hotline: 0917516878 [email protected]
HoaTranLab Logo HoaTranLab
Linux Bible 11th Edition • Chapter 30

Automating Apps and Infrastructure with Ansible

Tự động hóa IT infrastructure với Ansible: inventory files, playbooks YAML, modules (dnf/service/copy/user), ad-hoc commands và roles.

Mục tiêu học tập

Kiến trúc Ansible

Hiểu mô hình Control Node / Managed Nodes, cách Ansible giao tiếp qua SSH mà không cần agent trên managed nodes.

Inventory Files

Tạo inventory files để nhóm và quản lý các hosts, sử dụng static inventory và hiểu cách phân nhóm hosts.

Playbooks YAML

Viết Ansible playbooks định dạng YAML để tự động hóa: cài đặt packages, cấu hình services, quản lý files và users.

Ansible Modules

Sử dụng các modules phổ biến: dnf/yum (packages), service, copy, template, user, file, command, shell.

Ad-hoc Commands

Chạy lệnh ansible ad-hoc trực tiếp (-m module) để thực hiện tasks ngay lập tức mà không cần playbook.

Roles

Tổ chức playbooks thành roles có thể tái sử dụng, hiểu cấu trúc thư mục role và cách sử dụng Ansible Galaxy.

Lý thuyết: Ansible Automation

1. Kiến trúc Ansible

Control Node

Máy chạy Ansible. Cài ansible package. Chạy playbooks từ đây. SSH ra managed nodes.

→ SSH →

Managed Nodes

Các hosts được Ansible quản lý. Không cần cài Ansible agent. Chỉ cần SSH + Python.

Ưu điểm Agentless: Không cần cài software đặc biệt trên managed nodes. Ansible push code qua SSH, thực thi Python modules tạm thời rồi xóa. Đơn giản, bảo mật.

2. Cài đặt Ansible và SSH Keys

Terminal - Control Node: Cài Ansible + setup SSH keys

# Cài Ansible trên control node (Fedora/RHEL)

$ sudo dnf install ansible -y

$ ansible --version

ansible [core 2.17.3]

python version = 3.12.5

# Thêm hosts vào /etc/hosts

$ sudo tee -a /etc/hosts <<'EOF'

192.168.122.154 host01

192.168.122.94 host02

192.168.122.189 host03

EOF

# Tạo SSH key pair

$ ssh-keygen -t ed25519

Generating public/private ed25519 key pair.

Enter file: /home/joe/.ssh/id_ed25519: [Enter]

Enter passphrase: [Enter]

# Copy SSH key đến các managed nodes

$ for i in 1 2 3; do ssh-copy-id joe@host0$i; done

Number of key(s) added: 1

Now try logging into the machine, with: "ssh 'joe@host01'"

3. Inventory Files

inventory.ini

# Inventory file - nhóm hosts theo mục đích

[webservers]

host01

host02

[dbservers]

host03

[production:children]

webservers

dbservers

[webservers:vars]

http_port=80

ansible_user=joe

Terminal - Kiểm tra inventory

$ ansible -i inventory.ini all --list-hosts

hosts (3):

host01

host02

host03

$ ansible -i inventory.ini webservers --list-hosts

hosts (2):

host01

host02

4. Ad-hoc Commands

Terminal - Ansible Ad-hoc Commands

# Ping tất cả hosts

$ ansible -i inventory.ini all -m ping

host01 | SUCCESS => {"changed": false, "ping": "pong"}

host02 | SUCCESS => {"changed": false, "ping": "pong"}

host03 | SUCCESS => {"changed": false, "ping": "pong"}

# Chạy command trên group webservers

$ ansible -i inventory.ini webservers -m command -a "uptime"

host01 | SUCCESS | rc=0 >>

09:15:32 up 2 days, 3:42, 1 user, load average: 0.01, 0.02, 0.00

# Cài package với module dnf (cần become root)

$ ansible -i inventory.ini webservers -m dnf \

-a "name=nginx state=present" --become

host01 | CHANGED => {"changed": true, "msg": "Installed: nginx-1.24.0"}

host02 | CHANGED => {"changed": true, "msg": "Installed: nginx-1.24.0"}

# Xem help cho module copy

$ ansible-doc copy

> ANSIBLE.BUILTIN.COPY (/usr/lib/python3/dist-packages/ansible/...)

The copy module copies a file from local or remote machine...

5. Ansible Playbooks

webserver-playbook.yml

---

- name

: Deploy Nginx Web Server

hosts

: webservers

become

: yes

vars

:

web_port: 80

web_root: /var/www/html

tasks

:

- name: Install nginx

dnf:

name: nginx

state: latest

- name: Start and enable nginx

service:

name: nginx

state: started

enabled: yes

- name: Copy index.html to web root

copy:

src: files/index.html

dest: "{{ web_root }}/index.html"

owner: root

mode: '0644'

- name: Open firewall for HTTP

firewalld:

service: http

permanent: yes

state: enabled

immediate: yes

- name: Create web developer user

user:

name: webdev

groups: wheel

shell: /bin/bash

create_home: yes

state: present

Terminal - Chạy playbook

# Dry run (check mode) - không thay đổi thực tế

$ ansible-playbook -i inventory.ini webserver-playbook.yml --check

# Chạy playbook thực sự

$ ansible-playbook -i inventory.ini webserver-playbook.yml

PLAY [Deploy Nginx Web Server] ***********************

TASK [Gathering Facts] ******* ok: [host01] ok: [host02]

TASK [Install nginx] ********* changed: [host01] changed: [host02]

TASK [Start and enable nginx] changed: [host01] changed: [host02]

TASK [Copy index.html] ******* changed: [host01] changed: [host02]

TASK [Open firewall for HTTP] changed: [host01] changed: [host02]

TASK [Create web developer user] changed: [host01] changed: [host02]

PLAY RECAP ********************************************

host01 : ok=6 changed=5 unreachable=0 failed=0

host02 : ok=6 changed=5 unreachable=0 failed=0

6. Ansible Roles

Roles cho phép tổ chức playbooks thành các đơn vị tái sử dụng. Mỗi role có cấu trúc thư mục chuẩn:

Terminal - Tạo role structure

$ ansible-galaxy init roles/nginx

- Role roles/nginx was created successfully

$ tree roles/nginx/

roles/nginx/

├── defaults/ # Default variables

│ └── main.yml

├── files/ # Static files to copy

├── handlers/ # Handler definitions

│ └── main.yml

├── tasks/ # Task definitions

│ └── main.yml

├── templates/ # Jinja2 templates

└── vars/ # Role variables

└── main.yml

Lab Thực Hành

Triển khai web server tự động với Ansible: cài Nginx, cấu hình firewall, tạo users và deploy web content lên 3 managed nodes từ một control node.

1

Cài Ansible trên Control Node

Terminal - ansible (control node)

$ sudo dnf install ansible -y

$ ansible --version | head -2

ansible [core 2.17.3]

2

Setup SSH Keys đến managed nodes

Terminal

$ ssh-keygen -t ed25519 -f ~/.ssh/ansible_key

$ for i in 1 2 3; do

ssh-copy-id -i ~/.ssh/ansible_key.pub joe@host0$i

done

$ ssh -i ~/.ssh/ansible_key joe@host01 "hostname"

host01

3

Tạo Inventory File

hosts.ini

[webservers]

host01 ansible_user=joe

host02 ansible_user=joe

host03 ansible_user=joe

[webservers:vars]

ansible_ssh_private_key_file=~/.ssh/ansible_key

Terminal - Verify

$ ansible -i hosts.ini all -m ping

host01 | SUCCESS => {"ping": "pong"}

host02 | SUCCESS => {"ping": "pong"}

host03 | SUCCESS => {"ping": "pong"}

4

Viết Playbook triển khai Nginx

deploy-web.yml

---

- name

: Deploy Nginx on webservers

hosts

: webservers

become

: yes

tasks

:

- name: Install nginx

dnf: name=nginx state=latest

- name: Enable and start nginx

service: name=nginx state=started enabled=yes

- name: Deploy index.html

copy:

content: "<h1>Deployed by Ansible</h1>"

dest: /usr/share/nginx/html/index.html

- name: Open HTTP port

firewalld: service=http permanent=yes state=enabled immediate=yes

5

Chạy Playbook

Terminal

$ ansible-playbook -i hosts.ini deploy-web.yml --ask-become-pass

BECOME password: ****

PLAY [Deploy Nginx on webservers] ********************

TASK [Install nginx] *** changed: [host01] changed: [host02] changed: [host03]

TASK [Enable and start nginx] changed: [host01] changed: [host02] changed: [host03]

TASK [Deploy index.html] changed: [host01] changed: [host02] changed: [host03]

PLAY RECAP: host01/02/03 ok=4 changed=3 unreachable=0 failed=0

6

Xác nhận kết quả

Terminal

$ for h in host01 host02 host03; do

echo "=== $h ==="

curl -s http://$h/

done

=== host01 ===

<h1>Deployed by Ansible</h1>

=== host02 ===

<h1>Deployed by Ansible</h1>

=== host03 ===

<h1>Deployed by Ansible</h1>

Câu hỏi ôn tập

1

Ansible "agentless" có nghĩa là gì?

Ansible không cần cài software/agent trên managed nodes. Control node kết nối qua SSH, upload Python modules tạm thời lên managed node, thực thi rồi xóa. Managed nodes chỉ cần: SSH service running, Python interpreter. Điều này đơn giản hóa quản lý và tăng bảo mật.
2

Inventory file trong Ansible dùng để làm gì?

Inventory file liệt kê tất cả managed hosts và tổ chức chúng thành groups. Cho phép: (1) target specific groups trong playbooks (hosts: webservers); (2) assign variables per-host hoặc per-group; (3) tạo group hierarchy ([prod:children]). Default inventory: /etc/ansible/hosts.
3

Sự khác biệt giữa ad-hoc command và playbook?

Ad-hoc: lệnh một lần trực tiếp: ansible hosts -m module -a args. Nhanh, không cần file. Dùng cho tasks đơn giản như ping, kiểm tra. Playbook: file YAML định nghĩa nhiều tasks theo thứ tự. Reusable, versionable, idempotent. Dùng cho automation phức tạp, deployment workflows.
4

become: yes trong playbook có nghĩa là gì?

become: yes cho phép Ansible escalate privileges lên root (qua sudo) khi thực thi tasks. Tương đương chạy lệnh với sudo. Dùng khi tasks cần root: install packages, cấu hình system services, chỉnh sửa system files. Kết hợp với --ask-become-pass để nhập sudo password.
5

Idempotency trong Ansible có nghĩa là gì?

Idempotency: chạy playbook nhiều lần cho kết quả giống nhau. Nếu nginx đã được install (state: present), Ansible không install lại. Output hiển thị ok thay vì changed. Cho phép chạy playbooks an toàn bất kỳ lúc nào mà không lo gây ra side effects.
6

Module dnf và module service trong Ansible làm gì?

dnf module: quản lý packages trên Fedora/RHEL. state: present/absent/latest. Ví dụ: dnf: name=nginx state=latest. service module: quản lý systemd services. state: started/stopped/restarted, enabled: yes/no. Ví dụ: service: name=nginx state=started enabled=yes.
7

Lệnh ansible --check (dry run) dùng để làm gì?

--check chạy playbook ở chế độ "what-if" — Ansible kiểm tra những gì sẽ thay đổi nhưng không thực sự thực hiện. Useful để: preview changes trước khi apply, validate playbook syntax, CI/CD testing. Một số modules không hỗ trợ check mode và sẽ bị skip.
8

Ansible Role khác gì so với một Playbook thông thường?

Role là cách tổ chức playbook content thành cấu trúc thư mục chuẩn (tasks/, handlers/, vars/, defaults/, files/, templates/). Ưu điểm: (1) Reusable — dùng trong nhiều playbooks; (2) Shareable — qua Ansible Galaxy; (3) Maintainable — code tách biệt theo chức năng; (4) Testable độc lập với Molecule.