使用 NetBox 作为 Ansible 事实来源
使用 NetBox 作为 Ansible 事实来源
在这里,您将了解 NetBox 的高级概念,它如何成为事实来源 (SoT),以及 Ansible 内容集合的使用,该集合可在 Ansible Galaxy 上获得。目标是展示一些使 NetBox 成为出色工具的功能,以及为什么您希望将 NetBox 用作网络自动化的事实来源!
事实来源
为什么需要事实来源?事实来源是您获取设备预期状态的地方。不需要单一的事实来源,但每个数据域都应该有一个事实来源,通常称为记录系统 (SoR)。例如,如果您有一个数据库维护您的物理站点,并且该数据库被 IT 域之外的团队使用,那么它应该成为物理站点的 事实来源。您可以将来自物理站点事实来源的数据聚合到其他数据源中以进行自动化。请注意,当需要收集数据时,应该从该其他工具中获取。
创建网络自动化框架的第一步是确定数据的 事实来源,这些数据将用于未来的自动化。对于传统的网络,设备本身通常被视为 SoT。每次您需要配置数据点进行自动化时都从设备读取配置效率低下,并且假设设备配置符合预期,而不仅仅是在故障排除中或以其他意外方式留下。在向网络组织之外的团队提供数据时,公开 API 可以帮助加快数据收集速度,而无需首先检查设备。
NetBox
对于事实来源,一个流行的开源选择是 NetBox。从主要文档站点 netbox.readthedocs.io
"NetBox 是一款开源 Web 应用程序,旨在帮助管理和记录计算机网络"。
NetBox 目前旨在帮助管理您的
- DCIM(数据中心基础设施管理)
- IPAM(IP 地址管理)
- 数据电路
- 连接(网络、控制台和电源)
- 设备机架
- 虚拟化
- 密钥
由于 NetBox 是一个 IPAM 工具,因此有时会对 NetBox 能够做什么产生误解。需要明确的是,NetBox 不是
- 网络监控
- DNS 服务器
- RADIUS 服务器
- 配置管理
- 设施管理
为什么选择 NetBox?
NetBox 是一个基于许多常见 Python 开源工具构建的工具,使用 Postgres 作为后端数据库,使用 Python Django 作为后端 API 和前端 UI。API 非常友好,因为它支持 CRUD(创建、读取、更新、删除)操作,并且使用 Swagger 文档进行了全面记录。NetBox 集合有助于 NetBox 的多个方面,包括清单插件、查找插件以及用于更新 NetBox 中数据的多个模块。
从网络组织的角度来看,NetBox 提供了一个现代化的 UI,以帮助记录 IP 地址,同时主要强调网络设备、系统基础设施和虚拟机。这使其成为用作自动化事实来源的理想选择。
NetBox 本身不执行任何网络资源扫描。它旨在让人类维护数据,因为这将成为事实来源。它表示环境应该是什么样子。
用于 NetBox 的 Ansible 内容集合
您将在 netbox-community GitHub 组织中找到该集合 (github.com/netbox-community/)。在这里,您可以找到 Docker 容器镜像、设备类型库、社区生成的 NetBox 报告 以及 NetBox 本身源代码。
如果您不熟悉 Ansible 内容集合是什么,请观看此简短的 YouTube 视频。
该集合的 Galaxy 链接位于 galaxy.ansible.com/netbox/netbox。
NetBox 集合允许您快速开始将信息添加到 NetBox 实例中。唯一的要求是提供 API 密钥和 URL 才能开始。使用此集合、基本清单和 NetBox 环境,您可以非常快速地填充事实来源。
让我们逐步完成基本设置,以达到开始使用 NetBox 清单插件作为 Ansible 清单的位置。首先是将包含要与任务一起使用的项目列表的示例 group_vars/all.yml
文件。
--- site_list: - name: “NYC” time_zone: America/New_York status: Active - name: “CHI” time_zone: America/Chicago status: Active - name: “RTP” time_zone: America/New_York status: Active manufacturers: # In alphabetical order - Arista - Cisco - Juniper device_types: - model: “ASAv” manufacturer: “Cisco” slug: “asav” part_number: “asav” Full_depth: False - model: “CSR1000v” manufacturer: “Cisco” slug: “csr1000v” part_number: “csr1000v” Full_depth: False - model: “vEOS” manufacturer: “Arista” slug: “veos” part_number: “veos” Full_depth: False - model: “vSRX” manufacturer: “Juniper” slug: “vsrx” part_number: “vsrx” Full_depth: False platforms: - name: “ASA” slug: “asa” - name: “EOS” slug: “eos” - name: “IOS” slug: “ios” - name: “JUNOS” slug: “junos”
第一步是创建站点。由于 NetBox 对物理设备进行建模,因此您在物理位置安装设备。无论是在您自己的设施中还是在云中,这都是一个站点。此模块是 netbox.netbox.netbox_site
模块。
剧本中的一个任务可能是
- name: "TASK 10: SETUP SITES" netbox.netbox.netbox_site: netbox_url: "{{ lookup('ENV', 'NETBOX_URL') }}" netbox_token: "{{ lookup('ENV', 'NETBOX_API_KEY') }}" data: "{{ item }}" loop: "{{ site_list }}"
接下来的两部分是将设备添加到 NetBox 的基础。为了创建特定设备,您还需要在 NetBox 实例中拥有设备类型和制造商。为此,可以使用特定的模块来创建它们。平台将有助于识别设备的操作系统。我建议您使用自动化平台正在使用的操作系统,例如 IOS、NXOS 和 EOS 是不错的选择,并且应该与您的 ansible_network_os 选择相匹配。这些任务如下所示
- name: "TASK 20: SETUP MANUFACTURERS" netbox.netbox.netbox_manufacturer: netbox_url: "{{ lookup('ENV', 'NETBOX_URL') }}" netbox_token: "{{ lookup('ENV', 'NETBOX_API_KEY') }}" data: name: "{{ manufacturer }}" loop: "{{ manufacturers }}" loop_control: loop_var: manufacturer - name: "TASK 30: SETUP DEVICE TYPES" netbox.netbox.netbox_device_type: netbox_url: "{{ lookup('ENV', 'NETBOX_URL') }}" netbox_token: "{{ lookup('ENV', 'NETBOX_API_KEY') }}" data: model: "{{ device_type.model }}" manufacturer: "{{ device_type.manufacturer }}" slug: "{{ device_type.slug }}" part_number: "{{ device_type.part_number }}" is_full_depth: "{{ device_type.full_depth }}" loop: "{{ device_types }}" loop_control: loop_var: device_type label: "{{ device_type['model'] }}" - name: "TASK 40: SETUP PLATFORMS" netbox.netbox.netbox_platform: netbox_url: "{{ lookup('ENV', 'NETBOX_URL') }}" netbox_token: "{{ lookup('ENV', 'NETBOX_API_KEY') }}" data: name: "{{ platform.name }}" slug: "{{ platform.slug }}" loop: "{{ platforms }}" loop_control: loop_var: platform label: "{{ platform['name'] }}"
在此阶段,您可以开始将设备和设备信息添加到 NetBox 中。以下任务利用 Ansible 自动收集的 ansible_facts。因此,对于这些特定设备类型,除了使用 Ansible 收集事实之外,不需要额外的解析/数据收集。在此添加设备的示例中,您会注意到 custom_fields。NetBox 的一个很好的扩展是,如果尚未定义字段,则可以设置自己的字段并在工具中使用它们。
- name: "TASK 100: NETBOX >> ADD DEVICE TO NETBOX" netbox.netbox.netbox_device: netbox_url: "{{ lookup('ENV', 'NETBOX_URL') }}" netbox_token: "{{ lookup('ENV', 'NETBOX_API_KEY') }}" data: name: "{{ inventory_hostname }}" device_type: "{{ ansible_facts['net_model'] }}" platform: IOS # May be able to use a filter to define in future serial: "{{ ansible_facts['net_serialnum'] }}" status: Active device_role: "{{ inventory_hostname | get_role_from_hostname }}" site: “ANSIBLE_DEMO_SITE" custom_fields: code_version: "{{ ansible_facts['net_version'] }}" - name: "TASK 110: NETBOX >> ADD INTERFACES TO NETBOX" netbox.netbox.netbox_device_interface: netbox_url: "{{ lookup('ENV', 'NETBOX_URL') }}" netbox_token: "{{ lookup('ENV', 'NETBOX_API_KEY') }}" data: device: "{{ inventory_hostname }}" name: "{{ item.key }}" form_factor: "{{ item.key | get_interface_type }}" # Define types mac_address: "{{ item.value.macaddress | ansible.netcommon.hwaddr }}" state: present with_dict: - "{{ ansible_facts['net_interfaces'] }}"
拥有接口后,您可以添加 ansible_facts 数据中包含的 IP 地址信息,我展示了三个步骤。首先是添加临时接口(任务 200),然后添加 IP 地址(任务 210),最后将 IP 地址关联到设备(任务 220)。
- name: "TASK 200: NETBOX >> Add temporary interface" netbox.netbox.netbox_device_interface: netbox_url: "{{ lookup('ENV', 'NETBOX_URL') }}" netbox_token: "{{ lookup('ENV', 'NETBOX_API_KEY') }}" data: device: "{{ inventory_hostname }}" name: Temporary_Interface form_factor: Virtual state: present - name: "TASK 210: NETBOX >> ADD IP ADDRESS OF ANSIBLE HOST" netbox.netbox.netbox_ip_address: netbox_url: "{{ lookup('ENV', 'NETBOX_URL') }}" netbox_token: "{{ lookup('ENV', 'NETBOX_API_KEY') }}" data: family: 4 address: "{{ ansible_host }}/24" status: active interface: name: Temporary_Interface device: "{{ inventory_hostname }}" - name: "TASK 220: NETBOX >> ASSOCIATE IP ADDRESS TO DEVICE" netbox.netbox.netbox_device: netbox_url: "{{ lookup('ENV', 'NETBOX_URL') }}" netbox_token: "{{ lookup('ENV', 'NETBOX_API_KEY') }}" data: name: "{{ inventory_hostname }}" device_type: "{{ ansible_facts['net_model'] }}" platform: IOS serial: "{{ ansible_facts['net_serialnum'] }}" status: Active primary_ip4: "{{ ansible_host }}/24"
示例:添加临时接口、添加 IP 地址、重新添加与 IP 地址关联的设备
Ansible 清单源
此时,您已使用静态清单中的所有设备填充了 NetBox。现在是时候将 NetBox 用作 Ansible 动态清单插件的事实来源了。这样,当您对环境进行更改时,就不必继续查找所有需要更新的项目。您只需要更改事实来源数据库 - NetBox。
您可以使用 YAML 文件定义要使用哪个清单插件,该文件定义了如何配置您预期的插件用途。下面是一个示例,显示您可以查询 NetBox 的许多组件以在 Ansible 清单中使用。您可能只想更新您的接入交换机?使用 query_filters 密钥定义应执行哪些 NetBox API 搜索。请查看 GitHub 或 ReadTheDocs 上的插件文档以获取更新的支持参数。compose 密钥允许您传递要由 Ansible 使用的其他变量,因此上面的平台将与 ansible_network_os 密钥一起使用。这是您看到定义和从清单源传递的内容的地方。
此定义还根据 NetBox 中定义的 device_roles 和平台创建了组。因此,您可以访问所有 platforms_ios 设备或 platforms_eos 设备(例如),这基于事实来源中的信息。
--- plugin: netbox.netbox.nb_inventory api_endpoint: http://netbox03 validate_certs: false config_context: false group_by: - device_roles - platforms compose: ansible_network_os: platform.slug query_filters: - site: "minnesota01" - has_primary_ip: True
使用插件扩展 NetBox
NetBox 本身最近添加的功能之一是能够通过您自己或社区驱动的插件扩展它。来自 Wiki
"插件是打包的 Django 应用程序,可以与 NetBox 一起安装以提供核心应用程序中不存在的自定义功能"
https://github.com/netbox-community/netbox/wiki/Plugins
您可以在该链接中找到社区中的一些特色插件。其中包括
- 动态 DNS 连接器
- NetBox 入职插件(从网络到代码) - 这将读取有关设备的其他信息并对 NetBox 进行更新
- NetBox 二维码 - 生成有关设备的二维码
- 使用 SAML2 进行 SSO
社区提供了许多可供您选择的插件,或者您可以编写自己的插件!
搜索 https://github.com/topics/netbox-plugi 以查找主题 NetBox 插件。
总结
NetBox 和 Ansible 结合在一起,是满足您网络自动化需求的绝佳组合!
NetBox 是一款出色的开源工具,有助于轻松创建、更新和使用事实来源。即使您不想使用可用于 Ansible 的 NetBox 集合,API 也易于使用,并且可以轻松更新数据库。对于通过事实来源交付自动化,必须拥有灵活、功能强大且准确的工具。NetBox 在这些方面都提供了满足。
这篇文章的灵感来自于 2020 年 3 月在明尼阿波利斯 Ansible 聚会上的一次演讲。有关此内容的更多资料,我在 ansible_netbox_demo 上提供了许多这些任务作为工作示例。来自 Ansible 聚会的演讲视频 也已上线。