我们希望听到您的声音!帮助我们深入了解 Ansible 生态系统的现状。
参加 2024 年 Ansible 项目调查

网络自动化 cli_command 深度解析

网络自动化 cli_command 深度解析

2018 年 10 月发布的 Ansible 2.7 为我们带来了两个强大的与网络平台无关的模块,cli_commandcli_config。您的环境中是否有多个网络供应商?这些与平台无关的模块旨在简化网络工程师处理各种网络平台时的 Ansible Playbook。您现在可以使用 cli_command 或 cli_config 来减少 playbook 中的任务和条件的数量,并使 playbook 更易于使用,而不是处理特定于平台的模块(例如 eos_config、ios_config、junos_config)。本文将演示如何使用这些模块并将它们与特定于平台的模块进行对比。我将展示一些 playbook 示例和常见用例,以帮助说明如何使用这些新的与平台无关的模块。

cli_commandcli_config 都只适用于 network_cli 连接插件。network_cli 的目标是使 playbook 在网络设备上的外观、感觉和操作方式与 Ansible 在 Linux 主机上的操作方式相同。

cli_command 可以做什么?

cli_command 允许您在网络设备上运行任意命令。让我们以 Arista vEOS 设备上的 cli_command 为例,展示一个简单的示例。

---
- name: RUN COMMAND AND PRINT TO TERMINAL WINDOW
  hosts: arista
  gather_facts: false

  tasks:

- name: RUN ARISTA COMMAND
  cli_command:
    command: show ip interface brief
  register: command_output

- name: PRINT TO TERMINAL WINDOW
  debug:
    msg: "{{command_output.stdout}}"

以前,这需要 eos_command 模块,并且如下所示

---
- name: RUN COMMAND AND PRINT TO TERMINAL WINDOW
  hosts: arista
  gather_facts: false

  tasks:

- name: RUN ARISTA COMMAND
  eos_command:
    commands: show ip interface brief
  register: command_output

- name: PRINT TO TERMINAL WINDOW
  debug:
    msg: "{{command_output.stdout}}"

这两个 Ansible Playbook 都很简单,并且输出结果相同。如下所示

screenshot

现在这两个 playbook 看起来并没有太大区别,但是当您添加多个供应商时,如果没有这些新的与平台无关的网络模块,playbook 的复杂性会迅速增加。以前,如果我有一个混合供应商的环境,我会看到 playbook 以几种不同的方式演变。有时它们包含许多条件(when 语句),如下所示

- name: RUN ARISTA COMMAND
  eos_command:
    commands: show ip int br
  when: ansible_network_os == 'eos'

- name: RUN CISCO NXOS COMMAND
  nxos_command:
    commands: show ip int br
  when: ansible_network_os == 'nxos'

- name: RUN JUNOS COMMAND
  junos_command:
    commands: show interface terse
  when: ansible_network_os == 'junos'

或者稍微好一点,网络自动化 playbook 会像这样演变

- name: RUN JUNOS COMMAND
  include_tasks: “{{ansible_network_os}}”

第二种方法要干净得多。include_tasks 调用名为 eos.yml、ios.yml、nxos.yml 等的 Ansible Playbook,并运行所需的相应命令或任务。虽然这要好得多,因为您可以根据网络平台分离 Ansible Playbook,但它仍然不如与平台无关的模块简洁或易用。底层功能相同,但 Ansible Playbook 变得更加简单。

我之所以提到这种 include_tasks 方法,是因为即使使用与平台无关的模块,仍然存在分离 playbook 逻辑的时间和地点。例如,上面显示的 Juniper 命令与 Arista 和 Cisco 不同(show ip interface brief 与 show interface terse)。

使用 cli_command,让我们看看如何为 Cisco、Juniper 和 Arista 创建一个极其简单的与平台无关的 playbook

---
- name: RUN COMMAND AND PRINT TO TERMINAL WINDOW
  hosts: routers
  gather_facts: false

  tasks:
    - name: RUN SHOW COMMAND
      cli_command:
        command: "{{show_interfaces}}"
      register: command_output

    - name: PRINT TO TERMINAL WINDOW
      debug:
        msg: "{{command_output.stdout}}"

三个 *os_command 任务减少到一个任务。show_interfaces 变量存储在每个平台的基础上作为组变量。有关完整示例,请查看此 GitHub 存储库

备份示例

让我们看看 cli_command 模块的另一个用例。备份网络配置是一项常见的网络操作任务。Ansible 网络自动化模块具有一个备份参数,可帮助网络工程师自动化这项平凡但至关重要的任务。例如,使用 Arista EOS,我们可以这样做

---
- name: BACKUP NETWORK CONFIGURATIONS
  hosts: arista
  gather_facts: false

  tasks:

    - name: BACKUP CONFIG
      eos_config:
        backup: yes

cli_command 模块没有备份参数。为什么?因为备份参数可能非常不灵活且难以操作。Ansible 用户最常见的特性请求之一是每个配置模块能够设置备份目标。与其在每个配置模块中重新创建大量逻辑和代码,我们可以重用现有模块。在这种情况下,我们可以利用已经广泛使用的 copy 模块!

---
- name: RUN COMMAND AND PRINT TO TERMINAL WINDOW
  hosts: arista
  gather_facts: false

  tasks:

- name: RUN ARISTA COMMAND
  cli_command:
    command: show run
  register: backup

- name: PRINT TO TERMINAL WINDOW
  copy:
    content: "{{backup.stdout}}"
    dest: "{{inventory_hostname}}.backup"

这使得操作要保存的命令输出变得很容易。在这种情况下,它是运行配置,但现在我们可以轻松地切换到启动配置。它还允许用户控制备份目标目录和文件名。Arista EOS、Juniper Junos 和 Cisco IOS 备份的与平台无关的 playbook 示例可以在这里找到

https://github.com/network-automation/agnostic_example

我们可以使用与平台无关的模块做很多不可思议的事情,这些模块有助于使我们的 Ansible 网络自动化 Playbook 更加简洁和简单。cli_comand 和 cli_config 模块自 2018 年 10 月起就已包含在 Ansible 项目中。如果您尚未升级,请考虑升级。如果您已经在使用 cli_command 或 cli_config 模块,请分享!我将在后续的博文中重点介绍更多使用与平台无关的模块的示例,敬请期待。