Lab 5 — Ansible Variables & Facts
Mục tiêu: Sau Lab này, người học hiểu cách Ansible lưu trữ và sử dụng dữ liệu động thông qua Variables và Facts. Người học sẽ biết cách viết Playbook không còn hard-code, biết cách truy cập thông tin của server, sử dụng
register,debug,whenvà bắt đầu xây dựng Playbook có khả năng thích nghi với nhiều server/environment.
1. Bối cảnh
Ở Lab 4, chúng ta đã viết được Playbook:
---
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Create deploy user
ansible.builtin.user:
name: deploy
state: present
- name: Create application directory
ansible.builtin.file:
path: /opt/myapp
state: directory
owner: deploy
group: deploy
mode: "0755"
Playbook này hoạt động.
Nhưng có một vấn đề:
name: deploy
path: /opt/myapp
mode: 0755
Tất cả đều được hard-code.
Giả sử chúng ta có:
Development
user = dev
app = todo-dev
Staging
user = staging
app = todo-staging
Production
user = deploy
app = todo
Nếu viết hard-code:
deploy-dev.yml
deploy-staging.yml
deploy-production.yml
thì chúng ta đang tạo ra rất nhiều code trùng lặp.
Thay vào đó:
Playbook
│
▼
Variables
/ | \
▼ ▼ ▼
Dev Staging Prod
Đây là lý do Variables rất quan trọng.
2. Variable là gì?
Variable đơn giản là một giá trị có thể thay đổi.
Ví dụ:
app_name: todo
app_user: deploy
app_port: 8080
Sau đó sử dụng:
- name: Create application directory
ansible.builtin.file:
path: "/opt/{{ app_name }}"
state: directory
owner: "{{ app_user }}"
Thay vì:
path: /opt/todo
owner: deploy
Ta có:
Variable
↓
{{ app_name }}
↓
todo
3. Jinja2 expression
Ansible sử dụng Jinja2 để xử lý expression.
Cú pháp cơ bản:
{{ variable }}
Ví dụ:
app_name: todo
Sử dụng:
msg: "Application: {{ app_name }}"
Kết quả:
Application: todo
Có thể hình dung:
{{ app_name }}
↓
Template Engine
↓
todo
Phần Jinja2 nâng cao sẽ được học sâu hơn ở Lab 6 — Templates với Jinja2. Trong Lab này chúng ta chỉ sử dụng Jinja2 ở mức cần thiết cho Variables.
4. Tạo project
Tạo project:
mkdir ansible-lab-05
cd ansible-lab-05
Cấu trúc:
ansible-lab-05/
├── ansible.cfg
├── inventory.ini
└── playbook.yml
ansible.cfg:
[defaults]
inventory = ./inventory.ini
5. Inventory
Sử dụng:
[webservers]
web-01 ansible_host=192.168.56.101
web-02 ansible_host=192.168.56.102
Kiểm tra:
ansible-inventory --graph
6. Variable đầu tiên
Tạo:
---
- name: Variable demo
hosts: webservers
vars:
app_name: todo
app_user: deploy
app_port: 8080
tasks:
- name: Show application information
ansible.builtin.debug:
msg: "App={{ app_name }}, User={{ app_user }}, Port={{ app_port }}"
Chạy:
ansible-playbook playbook.yml
Kết quả:
App=todo, User=deploy, Port=8080
7. vars
Variables có thể được khai báo trực tiếp trong Play:
vars:
app_name: todo
app_user: deploy
Phạm vi:
Play
│
├── vars
│ ├── app_name
│ └── app_user
│
└── tasks
Các task trong Play có thể sử dụng những variable này.
8. Sử dụng Variable trong Task
Ví dụ:
---
- name: Configure application
hosts: webservers
become: true
vars:
app_name: todo
app_user: deploy
tasks:
- name: Create application user
ansible.builtin.user:
name: "{{ app_user }}"
state: present
- name: Create application directory
ansible.builtin.file:
path: "/opt/{{ app_name }}"
state: directory
owner: "{{ app_user }}"
group: "{{ app_user }}"
mode: "0755"
Bây giờ thay đổi:
app_name: payment
app_user: payment
thì Playbook sẽ tự động tạo:
/opt/payment
và:
payment user
Không cần sửa từng task.
9. Tại sao Variables quan trọng?
Không có variable:
- name: Create deploy user
ansible.builtin.user:
name: deploy
- name: Create directory
ansible.builtin.file:
path: /opt/todo
owner: deploy
Có variable:
vars:
app_name: todo
app_user: deploy
Sau đó:
- name: Create application user
ansible.builtin.user:
name: "{{ app_user }}"
- name: Create application directory
ansible.builtin.file:
path: "/opt/{{ app_name }}"
owner: "{{ app_user }}"
So sánh:
Hard-coded
↓
Khó thay đổi
Khó reuse
Khó scale
Variables
↓
Dễ thay đổi
Dễ reuse
Dễ scale
10. Variable kiểu String
app_name: todo
environment: production
app_user: deploy
Sử dụng:
msg: "Deploy {{ app_name }} to {{ environment }}"
Kết quả:
Deploy todo to production
11. Variable kiểu Number
app_port: 8080
worker_count: 4
Có thể:
msg: "Application port: {{ app_port }}"
Lưu ý:
Trong YAML, kiểu dữ liệu có thể ảnh hưởng đến cách Ansible xử lý giá trị.
Ví dụ:
app_port: 8080
là number.
Trong một số context, đặc biệt khi cần truyền giá trị chuỗi, có thể chủ động sử dụng:
app_port: "8080"
12. Boolean
nginx_enabled: true
debug_enabled: false
Sử dụng với module:
- name: Ensure nginx is enabled
ansible.builtin.service:
name: nginx
enabled: "{{ nginx_enabled }}"
13. List
Variable có thể là danh sách:
packages:
- nginx
- curl
- git
Có thể sử dụng:
- name: Install required packages
ansible.builtin.apt:
name: "{{ packages }}"
state: present
Kết quả:
nginx
curl
git
sẽ được cài đặt.
14. Dictionary
Variable cũng có thể chứa nhiều key:
app:
name: todo
user: deploy
port: 8080
Truy cập:
{{ app.name }}
{{ app.user }}
{{ app.port }}
Ví dụ:
- name: Show app information
ansible.builtin.debug:
msg: "{{ app.name }} runs on port {{ app.port }}"
Kết quả:
todo runs on port 8080
15. Nested Variables
Có thể tạo cấu trúc:
application:
name: todo
version: "1.0.0"
server:
host: 0.0.0.0
port: 8080
Truy cập:
{{ application.name }}
{{ application.version }}
{{ application.server.port }}
Đây là cấu trúc rất thường gặp trong Ansible thực tế.
16. Variable trong debug
Module rất hữu ích để debug:
ansible.builtin.debug:
Ví dụ:
- name: Show application name
ansible.builtin.debug:
var: app_name
Hoặc:
- name: Show application configuration
ansible.builtin.debug:
var: application
17. msg vs var
msg
- name: Show message
ansible.builtin.debug:
msg: "Application is {{ app_name }}"
Dùng khi muốn tạo message tùy chỉnh.
var
- name: Show variable
ansible.builtin.debug:
var: app_name
Dùng khi muốn xem trực tiếp giá trị variable.
18. Facts là gì?
Đây là phần quan trọng thứ hai của Lab.
Khi Ansible kết nối tới server, nó có thể tự động thu thập thông tin về server.
Ví dụ:
OS
Hostname
IP
CPU
Memory
Architecture
Kernel
Python
Interfaces
Disks
Những thông tin này gọi là:
Ansible Facts
Flow:
Control Node
│
│ SSH
▼
Managed Node
│
│ Gather information
▼
Ansible Facts
19. gather_facts
Mặc định:
- name: Configure server
hosts: webservers
Ansible thường sẽ thực hiện:
Gathering Facts
↓
Tasks
Bạn có thể thấy:
TASK [Gathering Facts]
ok: [web-01]
ok: [web-02]
20. Xem Facts
Tạo Playbook:
---
- name: Explore Ansible Facts
hosts: webservers
tasks:
- name: Show all facts
ansible.builtin.debug:
var: ansible_facts
Chạy:
ansible-playbook playbook.yml
Bạn sẽ nhận được rất nhiều dữ liệu.
Không nên cố đọc toàn bộ output.
Thay vào đó, lấy từng thông tin cần thiết.
21. Hostname
Một Fact thường được sử dụng:
ansible_hostname
Ví dụ:
- name: Show hostname
ansible.builtin.debug:
var: ansible_hostname
Có thể sử dụng:
msg: "Server hostname: {{ ansible_hostname }}"
22. Operating System
Có thể sử dụng:
ansible_facts.distribution
Ví dụ:
- name: Show operating system
ansible.builtin.debug:
msg: "OS: {{ ansible_facts.distribution }}"
Ví dụ kết quả:
OS: Ubuntu
hoặc:
OS: Debian
hoặc:
OS: Rocky
23. OS Version
ansible_facts.distribution_version
Ví dụ:
- name: Show OS version
ansible.builtin.debug:
msg: "{{ ansible_facts.distribution }} {{ ansible_facts.distribution_version }}"
Kết quả:
Ubuntu 24.04
24. Architecture
ansible_facts.architecture
Ví dụ:
- name: Show architecture
ansible.builtin.debug:
var: ansible_facts.architecture
Có thể nhận:
x86_64
hoặc:
aarch64
Điều này đặc biệt hữu ích khi làm việc với:
- ARM server
- AWS Graviton
- Raspberry Pi
- Apple Silicon VM
- Multi-architecture deployment
25. CPU
Ví dụ:
ansible_facts.processor_vcpus
- name: Show CPU count
ansible.builtin.debug:
msg: "vCPU: {{ ansible_facts.processor_vcpus }}"
26. Memory
Ví dụ:
ansible_facts.memtotal_mb
- name: Show memory
ansible.builtin.debug:
msg: "Memory: {{ ansible_facts.memtotal_mb }} MB"
27. Default IPv4
Có thể truy cập:
ansible_facts.default_ipv4.address
Ví dụ:
- name: Show server IP
ansible.builtin.debug:
msg: "IP: {{ ansible_facts.default_ipv4.address }}"
28. Facts vs Variables
Đây là điểm cần phân biệt rõ.
Variable
Do chúng ta hoặc inventory cung cấp:
app_name: todo
Fact
Ansible tự thu thập từ server:
ansible_facts.distribution
ansible_facts.architecture
ansible_facts.memtotal_mb
Có thể hình dung:
Variables
│
└── Configuration / Input
Facts
│
└── Information about server
29. Fact có thể dùng để quyết định
Ví dụ:
- name: Install nginx on Debian family
ansible.builtin.apt:
name: nginx
state: present
when: ansible_facts.os_family == "Debian"
Nếu:
OS = Ubuntu
thì task chạy.
Nếu:
OS = Rocky Linux
thì task bị skip.
30. when
when dùng để thực hiện task có điều kiện.
Ví dụ:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
when: ansible_facts.os_family == "Debian"
Không đặt {{ }} trong when cho biểu thức điều kiện:
Đúng:
when: ansible_facts.os_family == "Debian"
Không cần:
when: "{{ ansible_facts.os_family == 'Debian' }}"
31. Ubuntu và RHEL
Một ví dụ thực tế:
---
- name: Install web server
hosts: all
become: true
tasks:
- name: Install nginx on Debian family
ansible.builtin.apt:
name: nginx
state: present
when: ansible_facts.os_family == "Debian"
- name: Install nginx on RedHat family
ansible.builtin.dnf:
name: nginx
state: present
when: ansible_facts.os_family == "RedHat"
Flow:
Server
│
Gather Facts
│
┌────────┴────────┐
▼ ▼
Debian RedHat
│ │
▼ ▼
apt dnf
Đây là lúc Facts bắt đầu tạo ra giá trị thực tế.
32. register
Ngoài Facts, một nguồn dữ liệu quan trọng khác là kết quả của task.
Ví dụ:
- name: Check nginx version
ansible.builtin.command:
cmd: nginx -v
register: nginx_result
changed_when: false
Kết quả task được lưu vào:
nginx_result
Sau đó:
- name: Show result
ansible.builtin.debug:
var: nginx_result
33. Register hoạt động thế nào?
Task
│
│ execute
▼
Command / Module
│
│ result
▼
register
│
▼
Variable
│
├── stdout
├── stderr
├── rc
└── changed
Ví dụ:
nginx_result.stdout
nginx_result.rc
34. stdout
Ví dụ:
- name: Check hostname
ansible.builtin.command:
cmd: hostname
register: hostname_result
changed_when: false
Có thể:
- name: Show hostname
ansible.builtin.debug:
msg: "{{ hostname_result.stdout }}"
35. rc
rc thường là return code.
Ví dụ:
0
thường biểu thị command thành công.
Có thể:
- name: Check command result
ansible.builtin.debug:
msg: "Return code: {{ hostname_result.rc }}"
36. Register + when
Đây là pattern rất quan trọng.
Ví dụ:
- name: Check nginx configuration
ansible.builtin.command:
cmd: nginx -t
register: nginx_test
changed_when: false
Sau đó có thể dựa trên kết quả:
- name: Show nginx test result
ansible.builtin.debug:
msg: "Nginx configuration is valid"
when: nginx_test.rc == 0
Flow:
Execute
↓
Register result
↓
Check condition
↓
Take action
37. Variable precedence — giới thiệu
Một trong những phần khó nhất của Ansible là:
Một variable có thể được khai báo ở nhiều nơi.
Ví dụ:
defaults
vars
inventory
group_vars
host_vars
extra vars
Không phải tất cả đều có độ ưu tiên giống nhau.
Ở Lab này chưa cần học thuộc toàn bộ precedence.
Điều cần hiểu:
Variable source
↓
Precedence
↓
Final value
Chúng ta sẽ xây dựng cấu trúc Variable bài bản ở Lab 13 khi bắt đầu quản lý nhiều Environment.
38. Inventory Variables
Variable có thể đặt trực tiếp trong Inventory.
Ví dụ:
[webservers]
web-01 ansible_host=192.168.56.101 app_port=8080
web-02 ansible_host=192.168.56.102 app_port=9090
Sau đó:
- name: Show application port
ansible.builtin.debug:
msg: "{{ app_port }}"
Kết quả:
web-01 → 8080
web-02 → 9090
Điều này cho phép từng server có cấu hình riêng.
39. group_vars
Khi project lớn hơn, không nên nhét tất cả vào Inventory.
Có thể tạo:
group_vars/
└── webservers.yml
Ví dụ:
app_name: todo
app_user: deploy
app_port: 8080
Cấu trúc:
ansible-lab-05/
├── inventory.ini
├── playbook.yml
└── group_vars/
└── webservers.yml
Ansible sẽ tự động load variables cho group webservers.
40. host_vars
Nếu một server cần cấu hình riêng:
host_vars/
├── web-01.yml
└── web-02.yml
Ví dụ:
# host_vars/web-01.yml
app_port: 8080
và:
# host_vars/web-02.yml
app_port: 9090
Flow:
webservers
│
├── web-01
│ └── app_port=8080
│
└── web-02
└── app_port=9090
41. Đây là cấu trúc rất quan trọng
Một project thực tế có thể:
ansible/
├── ansible.cfg
├── inventory.ini
├── group_vars/
│ └── webservers.yml
├── host_vars/
│ ├── web-01.yml
│ └── web-02.yml
└── playbook.yml
Tư duy:
Playbook
│
├── Common logic
│
└── Variables
├── Group
└── Host
Như vậy logic và dữ liệu bắt đầu được tách ra.
42. Thực hành — Dynamic Web Server
Bây giờ chúng ta xây dựng một Playbook thực tế hơn.
Mục tiêu:
Install nginx
Create application user
Create application directory
Deploy website
Start nginx
Nhưng tất cả configuration phải sử dụng Variables.
43. Tạo group_vars
Tạo:
group_vars/webservers.yml
Nội dung:
app_name: todo
app_user: deploy
app_directory: "/opt/{{ app_name }}"
web_root: /var/www/html
44. Playbook
---
- name: Configure web servers
hosts: webservers
become: true
tasks:
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
- name: Create application user
ansible.builtin.user:
name: "{{ app_user }}"
state: present
- name: Create application directory
ansible.builtin.file:
path: "{{ app_directory }}"
state: directory
owner: "{{ app_user }}"
group: "{{ app_user }}"
mode: "0755"
- name: Ensure nginx is running
ansible.builtin.service:
name: nginx
state: started
enabled: true
Điểm quan trọng:
Playbook không biết:
deploy
todo
/opt/todo
Nó chỉ biết:
app_user
app_name
app_directory
45. Thay đổi Environment
Chỉ cần:
app_name: payment
app_user: payment
app_directory: "/opt/{{ app_name }}"
Playbook sẽ tạo:
user:
payment
directory:
/opt/payment
Không cần sửa Playbook.
Đây chính là lợi ích lớn của Variables.
46. Thực hành Facts
Tạo:
facts.yml
---
- name: Explore server facts
hosts: webservers
tasks:
- name: Show hostname
ansible.builtin.debug:
msg: "Hostname: {{ ansible_hostname }}"
- name: Show OS
ansible.builtin.debug:
msg: "OS: {{ ansible_facts.distribution }}"
- name: Show OS version
ansible.builtin.debug:
msg: "Version: {{ ansible_facts.distribution_version }}"
- name: Show architecture
ansible.builtin.debug:
msg: "Architecture: {{ ansible_facts.architecture }}"
- name: Show memory
ansible.builtin.debug:
msg: "Memory: {{ ansible_facts.memtotal_mb }} MB"
- name: Show IP
ansible.builtin.debug:
msg: "IP: {{ ansible_facts.default_ipv4.address }}"
Chạy:
ansible-playbook facts.yml
47. Exercise 1 — Variables
Tạo Playbook:
variables.yml
Khai báo:
app_name: todo
app_version: "1.0.0"
app_port: 8080
app_user: deploy
In ra:
Application:
Version:
Port:
User:
Không được hard-code các giá trị trong debug.
48. Exercise 2 — List
Tạo:
packages:
- curl
- git
- nginx
Viết task cài toàn bộ package.
Gợi ý:
ansible.builtin.apt:
name: "{{ packages }}"
state: present
49. Exercise 3 — Dictionary
Tạo:
app:
name: todo
user: deploy
port: 8080
directory: /opt/todo
In:
Name
User
Port
Directory
sử dụng:
app.name
app.user
app.port
app.directory
50. Exercise 4 — Facts
Viết Playbook hiển thị:
Hostname
OS
OS Version
Architecture
CPU
Memory
IP
Yêu cầu:
Không được hard-code bất kỳ thông tin server nào.
Tất cả phải lấy từ Facts.
51. Exercise 5 — OS Detection
Viết Playbook:
Debian family
↓
Install nginx with apt
RedHat family
↓
Install nginx with dnf
Sử dụng:
when:
và:
ansible_facts.os_family
52. Exercise 6 — Register
Viết task:
Check nginx version
↓
register
↓
Print stdout
Ví dụ:
- name: Check nginx version
ansible.builtin.command:
cmd: nginx -v
register: nginx_version
changed_when: false
Sau đó hiển thị:
nginx_version.stderr
Lưu ý: nginx -v trên nhiều phiên bản Nginx ghi version vào stderr, không phải stdout.
53. Exercise 7 — Register + Condition
Viết Playbook:
Check nginx
↓
Register result
↓
Nếu thành công
↓
Print "Nginx check passed"
Nếu thất bại
↓
Playbook fail
Gợi ý:
failed_when: nginx_test.rc != 0
54. Exercise 8 — Group Variables
Tạo:
group_vars/
└── webservers.yml
Khai báo:
app_name: todo
app_user: deploy
app_port: 8080
Playbook phải sử dụng Variables từ group_vars.
Sau đó thay đổi:
app_name: payment
và chạy lại.
Kiểm tra xem Playbook có tự động thay đổi theo không.
55. Exercise 9 — Host Variables
Có:
web-01
web-02
Cấu hình:
web-01
app_port = 8080
web-02
app_port = 9090
Sử dụng:
host_vars/
để cấu hình.
Sau đó viết Playbook in:
hostname → port
Kết quả:
web-01 → 8080
web-02 → 9090
56. Exercise 10 — Senior Challenge
Xây dựng Playbook:
server-provision.yml
Yêu cầu:
Input
Variables:
app_name
app_user
app_port
packages
Facts
Tự phát hiện:
OS
Architecture
Memory
Hostname
IP
Logic
Server
│
Gather Facts
│
┌────────┴────────┐
▼ ▼
Debian RedHat
│ │
▼ ▼
apt dnf
│ │
└────────┬────────┘
▼
Install packages
│
▼
Create app user
│
▼
Create app directory
Playbook phải chạy được trên cả Debian-family và RedHat-family server.
57. Một vấn đề rất quan trọng: Variable không phải Secret
Không nên:
db_password: "MySuperSecretPassword"
trong:
playbook.yml
hoặc:
group_vars/webservers.yml
nếu file được commit vào Git.
Secret sẽ được học kỹ hơn ở:
Lab 11 — Ansible Secrets & Vault
Ở Lab này chỉ cần nhớ:
Variable
≠
Secret
58. Một lỗi nguy hiểm với debug
Không nên debug secret:
- name: Show password
ansible.builtin.debug:
var: db_password
Vì secret có thể xuất hiện trong log.
Khi làm việc với secret, cần sử dụng:
no_log: true
và cơ chế quản lý secret phù hợp như Ansible Vault.
59. Tư duy Senior #1 — Tách Logic và Data
Đây là một trong những nguyên tắc quan trọng nhất của Lab này.
Không nên:
Playbook
├── Logic
├── Configuration
├── Environment
└── Host-specific values
Tốt hơn:
Playbook
│
└── Logic
Variables
│
├── Environment config
├── Group config
└── Host config
Ví dụ:
Playbook
│
└── "Create application"
Variables
│
└── "Application name = todo"
60. Tư duy Senior #2 — Facts giúp Playbook thích nghi
Không nên:
apt:
một cách mù quáng nếu Playbook phải hỗ trợ nhiều OS.
Có thể:
Facts
↓
OS Detection
↓
Correct module
Ví dụ:
when: ansible_facts.os_family == "Debian"
và:
when: ansible_facts.os_family == "RedHat"
Đây là bước đầu tiên để xây dựng cross-platform automation.
61. Tư duy Senior #3 — Không lạm dụng Facts
Facts rất hữu ích nhưng không phải lúc nào cũng cần.
Nếu Playbook chỉ cần:
Install nginx
thì không nhất thiết phải thu thập hàng trăm thông tin về server.
Có thể:
gather_facts: false
khi thực sự không cần.
Tư duy tốt là:
Gather only what you need, when appropriate.
62. Tư duy Senior #4 — Variable naming
Nên:
app_name
app_user
app_port
app_directory
Không nên:
name
user
port
dir
Vì Playbook lớn sẽ có rất nhiều loại:
user
port
name
path
Tên rõ ràng giúp tránh collision và tăng khả năng đọc.
63. Tư duy Senior #5 — Đừng tạo Variable chỉ để tạo Variable
Không nên biến mọi thứ thành:
nginx_service_name: nginx
nếu giá trị đó không bao giờ thay đổi và không có lý do để cấu hình.
Variable nên tồn tại khi:
- Có khả năng thay đổi.
- Phụ thuộc environment.
- Phụ thuộc host.
- Được sử dụng nhiều lần.
- Cần override.
- Có ý nghĩa cấu hình.
64. Tư duy Senior #6 — register là runtime data
Phân biệt:
Variable
↓
Configuration/Input
và:
register
↓
Runtime result
Ví dụ:
app_port: 8080
là configuration.
Trong khi:
register: nginx_result
là kết quả của một task vừa chạy.
65. Tư duy Senior #7 — Condition phải dựa trên dữ liệu đáng tin cậy
Ví dụ:
when: ansible_facts.os_family == "Debian"
tốt hơn việc kiểm tra:
cat /etc/os-release
bằng shell rồi parse text thủ công.
Tận dụng dữ liệu Ansible đã cung cấp trước khi tự viết logic bằng shell.
66. Debugging Workflow
Khi Variable không hoạt động:
Variable không đúng
↓
debug
↓
Kiểm tra giá trị
↓
Kiểm tra source
↓
Kiểm tra precedence
↓
Kiểm tra type
Ví dụ:
- name: Debug application configuration
ansible.builtin.debug:
var: app
Đây là kỹ năng cực kỳ quan trọng khi Playbook trở nên lớn.
67. Workflow sau Lab 5
Từ Lab 4:
Playbook
↓
Hard-coded values
Sau Lab 5:
Playbook
│
├── Variables
│ ↓
│ Configuration
│
├── Facts
│ ↓
│ Server information
│
└── Register
↓
Runtime result
Và bắt đầu có:
Condition
↓
when
↓
Dynamic automation
68. Cheat Sheet
Variable
vars:
app_name: todo
Sử dụng Variable
"{{ app_name }}"
List
packages:
- nginx
- curl
Dictionary
app:
name: todo
port: 8080
Truy cập:
"{{ app.name }}"
Fact
ansible_facts.distribution
OS Family
ansible_facts.os_family
Hostname
ansible_hostname
Architecture
ansible_facts.architecture
Memory
ansible_facts.memtotal_mb
IP
ansible_facts.default_ipv4.address
Register
register: result
Output
result.stdout
Return code
result.rc
Condition
when: ansible_facts.os_family == "Debian"
Debug
ansible.builtin.debug:
var: app
69. Checklist hoàn thành Lab 5
Người học nên có thể:
- [ ] Giải thích Variable là gì.
- [ ] Khai báo Variable bằng
vars. - [ ] Sử dụng
{{ variable }}. - [ ] Sử dụng String.
- [ ] Sử dụng Number.
- [ ] Sử dụng Boolean.
- [ ] Sử dụng List.
- [ ] Sử dụng Dictionary.
- [ ] Hiểu nested variables.
- [ ] Hiểu Ansible Facts.
- [ ] Hiểu
gather_facts. - [ ] Lấy hostname.
- [ ] Lấy OS.
- [ ] Lấy OS version.
- [ ] Lấy architecture.
- [ ] Lấy memory.
- [ ] Lấy IP.
- [ ] Sử dụng Facts trong
when. - [ ] Hiểu
register. - [ ] Lấy
stdout. - [ ] Lấy
rc. - [ ] Sử dụng
register + when. - [ ] Biết
group_vars. - [ ] Biết
host_vars. - [ ] Hiểu cơ bản về variable precedence.
- [ ] Biết phân biệt Variables và Facts.
- [ ] Biết phân biệt Variables và
register. - [ ] Không hard-code configuration không cần thiết.
- [ ] Có thể viết Playbook chạy trên nhiều loại server.
70. Tổng kết
Sau Lab 5, người học đã đi qua một bước rất quan trọng:
Lab 1
Ansible Fundamentals
↓
Lab 2
Inventory & SSH
↓
Lab 3
Ad-Hoc Commands
↓
Lab 4
Playbook
↓
Lab 5
Variables & Facts
Tư duy đã chuyển từ:
"Chạy command này trên server"
sang:
"Đưa server về Desired State"
và tiếp tục tiến tới:
"Đưa mọi server về Desired State
dựa trên configuration và thông tin thực tế của từng server."
Kiến trúc hiện tại:
Ansible
│
┌───────┴────────┐
▼ ▼
Variables Facts
│ │
│ │
Configuration Server Info
│ │
└───────┬────────┘
▼
Playbook
│
Tasks
│
Modules
│
▼
Managed Node
Và đây là nền tảng trực tiếp cho Lab 6 — Ansible Templates với Jinja2.
Ở Lab 6, chúng ta sẽ giải quyết vấn đề tiếp theo:
Variable đã giúp Playbook thay đổi dữ liệu, nhưng làm thế nào để dùng những dữ liệu đó sinh ra cả một file configuration động?
Ví dụ:
Variables
│
├── app_name
├── app_port
├── app_host
└── workers
│
▼
Jinja2 Template
│
▼
nginx.conf / app.conf
│
▼
Server
Đây là lúc Ansible bắt đầu trở nên rất mạnh trong việc tự động hóa configuration của production server.
All rights reserved