Khi bắt đầu làm Network Automation với Ansible, một lỗi mình gặp khá nhiều là đưa toàn bộ thông tin cấu hình vào Playbook.
Ví dụ cần tạo Loopback cho nhiều router, nếu mỗi router có IP khác nhau thì Playbook sẽ ngày càng dài và khó quản lý.
Trong lab này, mình giải quyết vấn đề đó bằng cách tách data và logic:
👉 Inventory → xác định thiết bị
👉 Group Variables → chứa thông tin cần cấu hình
👉 Playbook → chứa logic triển khai
Mục tiêu là dùng Ansible tự động tạo Loopback1 và Loopback2 trên R1, R2, với thông tin interface/IP được lấy từ group_vars. Đây cũng là mô hình tổ chức chính của Lab 32 trong tài liệu.
🧩 1. CHUẨN BỊ CẤU TRÚC PROJECT
Mình tổ chức thư mục Ansible như sau:
ansible-lab/
├── inventory
├── group_vars/
│ └── Router.yml
└── interface.yml
Điểm quan trọng là thư mục phải có tên chính xác:
group_vars
và file Variable được đặt theo quy tắc:
<group_name>.yml
Vì Inventory sử dụng group Router, nên file tương ứng sẽ là:
group_vars/Router.yml
Ansible sẽ dựa vào cấu trúc này để tự động gán biến cho các host thuộc group Router.
🖥️ 2. KHAI BÁO ROUTER TRONG INVENTORY
Trong Inventory, mình đưa R1 và R2 vào cùng một group:
[Router]
R1
R2
Ở đây cần chú ý tên Router.
Nó không chỉ đơn giản là tên group, mà sẽ được sử dụng để liên kết với:
group_vars/Router.yml
Có thể hình dung:
[Router]
├── R1
└── R2
↓
group_vars/Router.yml
Như vậy, mọi biến trong Router.yml sẽ được sử dụng khi Playbook chạy trên các thiết bị thuộc group này.
📁 3. KHAI BÁO DATA TRONG Router.yml
Tiếp theo, mình tạo biến loopback để chứa danh sách interface cần cấu hình.
Cấu trúc dữ liệu có dạng:
loopback:
- name: Loopback1
ip: <IP_LOOPBACK_1>
- name: Loopback2
ip: <IP_LOOPBACK_2>
Điểm cần hiểu ở đây là loopback là một list, trong đó mỗi phần tử gồm hai thuộc tính:
name
ip
Tức là thay vì viết trực tiếp IP vào Playbook, mình đưa toàn bộ dữ liệu cần cấu hình vào Variable.
Đây chính là tư duy Data-driven Automation: dữ liệu thay đổi thì chỉ cần thay đổi Variable, không phải sửa logic Playbook.
⚙️ 4. VIẾT PLAYBOOK
Tạo file:
interface.yml
Phần khai báo chính:
- name: Configure Loopback
hosts: Router
gather_facts: no
hosts: Router có nghĩa Playbook sẽ chạy trên toàn bộ thiết bị thuộc group Router, tức R1 và R2.
gather_facts: no được sử dụng trong lab để không thực hiện bước thu thập facts thông thường.
🔄 5. DÙNG LOOP ĐỂ TẠO NHIỀU LOOPBACK
Đây là phần quan trọng nhất của lab.
Thay vì viết hai task:
Task 1 → Loopback1
Task 2 → Loopback2
mình sử dụng:
with_items
để loop qua biến:
loopback
Task sử dụng module:
ios_l3_interface
với hai giá trị:
name: "{{ item.name }}"
ipv4: "{{ item.ip }}"
Khi Ansible chạy vòng lặp, item sẽ lần lượt đại diện cho từng phần tử trong loopback.
Ví dụ:
item.name → Loopback1
item.ip → IP của Loopback1
sau đó:
item.name → Loopback2
item.ip → IP của Loopback2
Tài liệu cũng xác định {{ item.name }} lấy giá trị name và {{ item.ip }} lấy giá trị ip từ từng phần tử của biến loopback.
Vì vậy chỉ cần một task, Ansible có thể xử lý nhiều interface.
▶️ 6. CHẠY PLAYBOOK
Sau khi hoàn tất Inventory, Variable và Playbook, mình chạy:
ansible-playbook interface.yml
Lab sử dụng Inventory mặc định của Ansible nên không cần khai báo thêm -i.
Nếu cấu hình đúng, Ansible sẽ thực hiện task trên cả R1 và R2.
🔍 7. VERIFY TRÊN ROUTER
Sau khi Playbook chạy thành công, mình không chỉ kiểm tra output của Ansible mà phải verify trực tiếp trên thiết bị.
Trên R1:
show ip interface brief
Kiểm tra sự xuất hiện của:
Loopback1
Loopback2
Sau đó kiểm tra IP đã đúng với dữ liệu trong Router.yml.
Thực hiện tương tự trên R2.
Kết quả của lab: R1 và R2 đều được tạo thêm 2 Loopback với IP đúng như khai báo trong Group Variable.
💡 DEVNET TAKEAWAY
Điểm mình thấy quan trọng nhất sau khi hoàn thành lab không phải là việc tạo được 2 Loopback, mà là hiểu được flow:
Inventory
↓
group_vars/Router.yml
↓
loopback
↓
with_items
↓
item.name / item.ip
↓
ios_l3_interface
↓
R1 + R2
Đây chính là cách tư duy rất quan trọng khi làm Network Automation: tách dữ liệu khỏi logic.
Khi số lượng thiết bị tăng lên, chúng ta có thể thay đổi dữ liệu trong Variable mà vẫn giữ nguyên Playbook.
Ví dụ cần tạo Loopback cho nhiều router, nếu mỗi router có IP khác nhau thì Playbook sẽ ngày càng dài và khó quản lý.
Trong lab này, mình giải quyết vấn đề đó bằng cách tách data và logic:
👉 Inventory → xác định thiết bị
👉 Group Variables → chứa thông tin cần cấu hình
👉 Playbook → chứa logic triển khai
Mục tiêu là dùng Ansible tự động tạo Loopback1 và Loopback2 trên R1, R2, với thông tin interface/IP được lấy từ group_vars. Đây cũng là mô hình tổ chức chính của Lab 32 trong tài liệu.
🧩 1. CHUẨN BỊ CẤU TRÚC PROJECT
Mình tổ chức thư mục Ansible như sau:
ansible-lab/
├── inventory
├── group_vars/
│ └── Router.yml
└── interface.yml
Điểm quan trọng là thư mục phải có tên chính xác:
group_vars
và file Variable được đặt theo quy tắc:
<group_name>.yml
Vì Inventory sử dụng group Router, nên file tương ứng sẽ là:
group_vars/Router.yml
Ansible sẽ dựa vào cấu trúc này để tự động gán biến cho các host thuộc group Router.
🖥️ 2. KHAI BÁO ROUTER TRONG INVENTORY
Trong Inventory, mình đưa R1 và R2 vào cùng một group:
[Router]
R1
R2
Ở đây cần chú ý tên Router.
Nó không chỉ đơn giản là tên group, mà sẽ được sử dụng để liên kết với:
group_vars/Router.yml
Có thể hình dung:
[Router]
├── R1
└── R2
↓
group_vars/Router.yml
Như vậy, mọi biến trong Router.yml sẽ được sử dụng khi Playbook chạy trên các thiết bị thuộc group này.
📁 3. KHAI BÁO DATA TRONG Router.yml
Tiếp theo, mình tạo biến loopback để chứa danh sách interface cần cấu hình.
Cấu trúc dữ liệu có dạng:
loopback:
- name: Loopback1
ip: <IP_LOOPBACK_1>
- name: Loopback2
ip: <IP_LOOPBACK_2>
Điểm cần hiểu ở đây là loopback là một list, trong đó mỗi phần tử gồm hai thuộc tính:
name
ip
Tức là thay vì viết trực tiếp IP vào Playbook, mình đưa toàn bộ dữ liệu cần cấu hình vào Variable.
Đây chính là tư duy Data-driven Automation: dữ liệu thay đổi thì chỉ cần thay đổi Variable, không phải sửa logic Playbook.
⚙️ 4. VIẾT PLAYBOOK
Tạo file:
interface.yml
Phần khai báo chính:
- name: Configure Loopback
hosts: Router
gather_facts: no
hosts: Router có nghĩa Playbook sẽ chạy trên toàn bộ thiết bị thuộc group Router, tức R1 và R2.
gather_facts: no được sử dụng trong lab để không thực hiện bước thu thập facts thông thường.
🔄 5. DÙNG LOOP ĐỂ TẠO NHIỀU LOOPBACK
Đây là phần quan trọng nhất của lab.
Thay vì viết hai task:
Task 1 → Loopback1
Task 2 → Loopback2
mình sử dụng:
with_items
để loop qua biến:
loopback
Task sử dụng module:
ios_l3_interface
với hai giá trị:
name: "{{ item.name }}"
ipv4: "{{ item.ip }}"
Khi Ansible chạy vòng lặp, item sẽ lần lượt đại diện cho từng phần tử trong loopback.
Ví dụ:
item.name → Loopback1
item.ip → IP của Loopback1
sau đó:
item.name → Loopback2
item.ip → IP của Loopback2
Tài liệu cũng xác định {{ item.name }} lấy giá trị name và {{ item.ip }} lấy giá trị ip từ từng phần tử của biến loopback.
Vì vậy chỉ cần một task, Ansible có thể xử lý nhiều interface.
▶️ 6. CHẠY PLAYBOOK
Sau khi hoàn tất Inventory, Variable và Playbook, mình chạy:
ansible-playbook interface.yml
Lab sử dụng Inventory mặc định của Ansible nên không cần khai báo thêm -i.
Nếu cấu hình đúng, Ansible sẽ thực hiện task trên cả R1 và R2.
🔍 7. VERIFY TRÊN ROUTER
Sau khi Playbook chạy thành công, mình không chỉ kiểm tra output của Ansible mà phải verify trực tiếp trên thiết bị.
Trên R1:
show ip interface brief
Kiểm tra sự xuất hiện của:
Loopback1
Loopback2
Sau đó kiểm tra IP đã đúng với dữ liệu trong Router.yml.
Thực hiện tương tự trên R2.
Kết quả của lab: R1 và R2 đều được tạo thêm 2 Loopback với IP đúng như khai báo trong Group Variable.
💡 DEVNET TAKEAWAY
Điểm mình thấy quan trọng nhất sau khi hoàn thành lab không phải là việc tạo được 2 Loopback, mà là hiểu được flow:
Inventory
↓
group_vars/Router.yml
↓
loopback
↓
with_items
↓
item.name / item.ip
↓
ios_l3_interface
↓
R1 + R2
Đây chính là cách tư duy rất quan trọng khi làm Network Automation: tách dữ liệu khỏi logic.
Khi số lượng thiết bị tăng lên, chúng ta có thể thay đổi dữ liệu trong Variable mà vẫn giữ nguyên Playbook.