Tóm tắt: Tạo file netbox.yml với plugin: netbox.netbox.nb_inventory, token qua biến NETBOX_TOKEN. Lọc thiết bị bằng query_filters/device_query_filters (chính là filter REST API), chia group bằng group_by hoặc keyed_groups, sinh biến bằng compose. Plugin tự đặt ansible_host từ primary IP. Luôn xem kết quả bằng ansible-inventory --graph trước khi chạy playbook. Inventory tĩnh: Thu thập inventory IOS XR bằng Ansible.
Luồng hoạt động
flowchart LR A["netbox.yml"] --> B["nb_inventory"] B -->|"GET /api/dcim/devices/?status=active"| C["NetBox"] C --> B B --> D["group_by, keyed_groups"] B --> E["compose: ansible_network_os"] D --> F["ansible-inventory --graph"] E --> F F --> G["ansible-playbook -i netbox.yml"]
Cấu hình
Cài collection và biến môi trường
ansible-galaxy collection install netbox.netbox
python3 -m pip install pynetbox pytz # module của collection cần pynetbox
export NETBOX_API=https://netbox.example.com
export NETBOX_TOKEN='***'File inventory
Tên file phải kết thúc bằng netbox.yml, netbox.yaml, nb_inventory.yml hoặc nb_inventory.yaml, nếu không plugin sẽ bỏ qua.
plugin: netbox.netbox.nb_inventory
# api_endpoint và token đọc từ NETBOX_API / NETBOX_TOKEN nếu không khai báo
validate_certs: true
config_context: false
interfaces: false # true = kéo cả interface, chậm hơn nhiều
plurals: false # biến host dạng đơn: site, platform... (thay vì list)
query_filters:
- status: active
device_query_filters:
- has_primary_ip: "true"
- role: pe
- role: p # cùng key = OR; khác key = AND
- tag: automation
group_by:
- site
- platform
keyed_groups:
- key: platform
prefix: os
separator: "_" # → group os_iosxr, os_junos
compose:
ansible_network_os: >-
{'iosxr': 'cisco.iosxr.iosxr', 'junos': 'junipernetworks.junos.junos'}[platform]
ansible_connection: >-
'ansible.netcommon.netconf' if platform == 'junos' else 'ansible.netcommon.network_cli'Giá trị trong compose là biểu thức Jinja2 không có {{ }}. Biểu thức lỗi (host không có platform) bị bỏ qua lặng lẽ, trừ khi đặt strict: true.
| Option | Ý nghĩa |
|---|---|
query_filters |
Filter áp cho cả device lẫn VM |
device_query_filters / vm_query_filters |
Filter riêng cho device / virtual machine |
group_by |
Group sẵn có: site, role, platform, tag, region, tenant, status, manufacturer, device_type... |
keyed_groups / groups / compose |
Tính năng Constructable chuẩn của Ansible: group theo giá trị, group theo điều kiện, tạo biến |
config_context |
Kéo config context của NetBox thành biến host |
ansible_host_dns_name |
Dùng dns_name của primary IP thay cho địa chỉ |
fetch_all |
false = gọi API theo từng host khi danh sách filter dài (tránh URL quá dài) |
cache, cache_plugin, cache_timeout |
Cache kết quả, đỡ gọi API mỗi lần chạy |
timeout |
Timeout HTTP (giây) |
Danh sách tên group hợp lệ trong group_by và tên biến host (role hay device_role, dạng đơn hay số nhiều) thay đổi theo phiên bản collection và plurals. Đừng đoán: chạy ansible-inventory --host <tên> để xem biến thật rồi mới viết compose/keyed_groups.
Biến theo group
Credential và biến chung để trong group_vars cạnh file inventory, tên thư mục trùng tên group sinh ra:
ansible_user: "{{ lookup('env', 'NET_USER') }}"
ansible_password: "{{ lookup('env', 'NET_PASS') }}"
ansible_command_timeout: 120Kiểm tra và chạy
# Cây group
ansible-inventory -i inventory/netbox.yml --graph
# Toàn bộ biến của 1 host (xem tên biến thật: site, platform, role...)
ansible-inventory -i inventory/netbox.yml --host pe1-hni
# Xuất ra YAML để so sánh / debug
ansible-inventory -i inventory/netbox.yml --list --yaml > /tmp/inv.yml
# Chạy playbook trên 1 group sinh từ NetBox
ansible-playbook -i inventory/netbox.yml collect.yml -l os_iosxrCó thể gộp NetBox với inventory tĩnh: trỏ -i inventory/ (cả thư mục), Ansible đọc mọi nguồn trong đó.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
--graph chỉ có all, ungrouped, không có host |
Tên file sai đuôi nên plugin không nhận, hoặc filter không khớp | Đổi tên *netbox.yml; chạy với -vvv để xem URL API được gọi |
Unknown plugin 'netbox.netbox.nb_inventory' |
Chưa cài collection hoặc cài vào path khác | ansible-galaxy collection list | grep netbox |
403 Forbidden |
Token sai hoặc thiếu quyền đọc | Thử curl tới /api/status/ với cùng token, xem NetBox REST API và pynetbox |
Host có nhưng không có ansible_host |
Device chưa đặt primary IP | Đặt primary IPv4 trong NetBox, hoặc filter has_primary_ip: "true" |
ansible_network_os không được set |
Biểu thức compose lỗi (tên biến sai, platform rỗng) và bị bỏ qua |
Đặt strict: true để thấy lỗi, kiểm tra --host |
| Inventory chậm (vài chục giây) | interfaces: true, config_context: true hoặc NetBox lớn |
Tắt phần không dùng, bật cache, lọc chặt hơn |
| Tên host có khoảng trắng / trùng | Device không có tên hoặc trùng tên giữa các site | Đặt tên duy nhất trong NetBox |