Sổ tay kỹ thuật

Ansible inventory động từ NetBox

how-to#ansible#netbox#inventory· cập nhật 2026-11-06

Dùng khi muốn Ansible lấy danh sách router trực tiếp từ NetBox bằng plugin netbox.netbox.nb_inventory, chia group theo site/role/platform và tự gán biến kết nối.

Sửa trang này
Mục lục

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.

inventory/netbox.yml
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:

inventory/group_vars/os_iosxr.yml
ansible_user: "{{ lookup('env', 'NET_USER') }}"
ansible_password: "{{ lookup('env', 'NET_PASS') }}"
ansible_command_timeout: 120

Kiể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_iosxr

Có 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

Tham khảo