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

使用 Ansible Automation Platform、GitLab CE 和 Webhook 部署 IIS 网站

使用 Ansible Automation Platform、GitLab CE 和 Webhook 部署 IIS 网站

在 Red Hat Ansible Automation Platform 内部,Ansible Tower REST API 是帮助将自动化集成到环境中现有流程或工具的关键机制。在 Ansible Tower 3.6 中,我们实现了与 GitHub 和 GitLab Webhook 的直接集成,包括企业内部版本。这意味着源代码管理中的更改可以触发自动化,以应用基础设施配置更改、部署新服务、重新配置现有应用程序等等。在本博文中,我将介绍一个简单的场景并应用新的集成 Webhook 功能。

环境

我的环境包括 Ansible Tower(Red Hat Ansible Automation Platform 的一个组件)、带有已创建项目的 GitLab CE 和运行 IDE 的代码服务器(已克隆相同的 Git 存储库)。Ansible Tower 上存在一个清单,其中只有一个主机,即在经过认证的云上运行的 Windows 2019 Server 实例。在本例中,我将在此 Windows 服务器上部署 IIS,并对我想从此站点提供的 html 文件进行一些修改。

我部署 IIS 的 Playbook *非常*简单

 ---
- name: Configure IIS
  hosts: windows

  tasks:
  - name: Install IIS
    win_feature:
      name: Web-Server
      state: present

  - name: Start IIS service
    win_service:
      name: W3Svc
      state: started

  - name: Create website index.html
    win_copy:
      src: files/web.html
      dest: C:\Inetpub\wwwroot\index.html

我在这里所做的只是添加 Web-Server 功能,启动 IIS 并将我的站点的 html 文件复制到 IIS 提供的 Web 内容的默认位置。

我的 html 文件也同样简单

<html>
<title></title>
<body>

</body>
</html>

目标和设置

我希望发生的是,对于对这个 IIS 站点进行更改的每个合并请求,都应该重新部署该站点并使用此基本 html 文件。

Colin blog new one

GitLab 访问令牌

由于我的 Webhook 被触发,我想使用 Ansible Tower 作业的状态更新在 GitLab 中创建的合并请求。

为此,我首先必须为我的 GitLab 帐户创建一个个人访问令牌,以便 Ansible Tower 可以访问 GitLab API。这非常简单。我所要做的就是导航到我的用户设置,并从左侧导航面板中选择“访问令牌”。

Colin blog two

我为我的访问令牌提供了一个易于识别的名称“Ansible Tower”,将过期日期设置为月末,并将此访问令牌的范围限定为仅 API。点击“创建个人访问令牌”后,令牌本身就会可见,并且此页面底部会显示一个新条目。

Colin blog three

接下来,我将使用此令牌在 Ansible Tower 中创建一个类型为“GitLab 个人访问令牌”的新凭据。

Colin blog four

保存后,Ansible Tower 现在可以访问我的 GitLab 帐户的 API。

Ansible Tower 作业模板

现在 Ansible Tower 能够更新我的合并请求,我需要将 Webhook 访问配置到配置为运行我的简单 IIS Playbook 的作业模板。从 Ansible Tower 3.6 版本开始,每个作业模板上都有一个名为 **启用 Webhook** 的复选框。

coling blog new three

选择 **启用 Webhook** 选项后,将显示一些新字段。我选择 GitLab 作为我的 **Webhook 服务**,提供我使用 GitLab 个人访问令牌创建的凭据,**Webhook URL** 已预先填充到此作业模板的路径,并且保存修改后,将生成一个 **Webhook 密钥**,我将使用它来配置 GitLab 中的项目钩子。此外,请注意我的项目允许我覆盖 SCM 分支。这意味着该项目将从“change-web-text”分支而不是 Master 分支拉取更新。

GitLab 项目钩子集成

下一步将我带回 GitLab,这次导航到我想执行 Webhook 的项目的集成页面。

Colin blog six

在集成页面上,我提供 URL(Ansible Tower 中的作业模板中的 **Webhook URL**)和秘密令牌(Ansible Tower 中的作业模板中的 **Webhook 密钥**)。我还将触发器指定为“合并请求事件”,这意味着每当打开合并请求时,都会启动我指定的 URL。

colin blog new two

操作:更新我的网站文本

现在我已经使用个人访问令牌作为新的凭据类型授予 Ansible Tower 访问我的项目的权限,配置了我的作业模板以启用 Webhook,并在 GitLab 上配置了一个项目钩子以响应我的项目的合并请求事件,我准备对我的 html 文件进行测试提交。

在这里,我在 html 文档的 <title><body> 标签中添加文本并保存文件。

Colin blog eight

在“change-web-text”分支上提交更改后,我将推送我的代码,返回 GitLab 并打开一个合并请求以将更改合并回 master。

colin new blog

打开此合并请求现在将触发我的 Webhook,这将把我的网页更改部署到我的 IIS 站点。因为我已经使用我的个人访问令牌配置了 Ansible Tower,所以 Ansible Tower 将在合并请求上发布指向由于 Webhook 触发而执行的作业的链接。

如果所有配置都正确,我应该会看到一个新的作业正在执行,该作业对应于配置了 Webhook 的作业模板。我还应该看到一个已启动的作业,更新我的项目,这将从我的 GitLab 项目中提取最新的更改。

Colin blog nine

选择“iis website create”的作业,这是我为 Webhook 执行配置的作业模板,显示该作业是 **由** Webhook **启动的**。**额外变量** 将显示许多特定于项目的配置信息,更重要的是,作业输出应显示作业正在执行其应执行的操作。

Colin blog ten

完成后,我应该能够调出我的 IIS 服务器的 IP 并查看我令人惊叹的 html 页面的更改。

Colin blog eleven

要点

Ansible Tower 3.6 中引入的 Webhook 是一种非常强大的方法,可以响应源代码控制中的事件启动自动化。虽然此基本网站只是一个非常快速简单的示例,但将此功能应用于基础设施即代码(其中所有服务配置都在 Ansible Playbook 中定义)极大地突出了此强大功能。




深入探讨网络自动化的 VLAN 资源模块

深入探讨网络自动化的 VLAN 资源模块

2019 年 10 月,作为 Red Hat Ansible Engine 2.9 的一部分,Ansible 网络自动化团队引入了资源模块的概念。这些有主见的网络模块使网络自动化对于在生产环境中自动化各种网络平台的人员来说更容易、更一致。资源模块的目标是避免为呈现网络配置创建过于复杂的 jinja2 模板。这篇博文介绍了 Arista EOS 网络平台的 eos_vlans 模块。我将介绍几个示例,并描述每个状态参数的使用案例以及我们如何设想它们在现实世界场景中的使用。

在开始之前,让我们快速解释一下网络资源模块命名背后的基本原理。请注意,对于配置 VLAN 的资源模块,存在单数形式(eos_vlan、ios_vlan、junos_vlan 等)和复数形式(eos_vlans、ios_vlans、junos_vlans)。新的资源模块是我们今天要介绍的复数形式。我们已弃用单数形式。这样做是为了确保使用现有网络模块的用户不会导致其 Ansible Playbook 停止工作,并有足够的时间迁移到新的网络自动化模块。

VLAN 示例

让我们从 eos_vlans 资源模块的示例开始。

---
- name: add vlans
  hosts: arista
  gather_facts: false
  tasks:
    - name: add VLAN configuration
      eos_vlans:
        config:
          - name: desktops
            vlan_id: 20
          - name: servers
            vlan_id: 30
          - name: printers
            vlan_id: 40
          - name: DMZ
            vlan_id: 50

有一个隐式状态参数,默认为 merged(即 state: merged)。如果我们运行此 Ansible Playbook,则 VLAN 20、30、40 和 50 将合并到 arista 组中任何设备的运行配置中。新 Arista 交换机上的 show vlan 输出将如下所示

rtr2#show vlan
VLAN  Name                             Status    Ports
----- -------------------------------- --------- -------------------------------
1     default                          active
20    desktops                         active
30    servers                          active
40    printers                         active
50    DMZ                              active

而运行配置将如下所示

rtr2#show running-config | s vlan
vlan 20
   name desktops
!
vlan 30
   name servers
!
vlan 40
   name printers
!
vlan 50
   name DMZ

现在让我们手动更改网络配置

rtr2(config)#vlan 100
rtr2(config-vlan-100)#name artisanal_vlan
rtr2(config-vlan-100)#end
rtr2#wr
Copy completed successfully.

如果我重新运行 Ansible Playbook,它将返回 changed=0,因为它只关心 VLAN 20、30、40 和 50。它不会删除 VLAN 100,因为我们默认将状态参数设置为 merged,因此它只会合并它知道的模型数据。它只是在执行我发送的 VLAN 的配置策略。

使用“state”参数

如果我将状态参数更改为 replaced 会发生什么?只需将前面的示例更改为以下内容

---
- name: add vlans
  hosts: arista
  gather_facts: false
  tasks:
    - name: add VLAN configuration
      eos_vlans:
        state: replaced
        config:
          - name: desktops
            vlan_id: 20
          - name: servers
            vlan_id: 30
          - name: printers
            vlan_id: 40
          - name: DMZ
            vlan_id: 50

Ansible Playbook 运行方式与之前相同,changed=0。我们能判断它是否删除了 artisanal_vlan 100 吗?

rtr2#show vlan
VLAN  Name                             Status    Ports
----- -------------------------------- --------- -------------------------------
1     default                          active
20    desktops                         active
30    servers                          active
40    printers                         active
50    DMZ                              active
100   artisanal_vlan                   active

不能!资源模块的目标是更新现有资源以匹配现有数据模型。由于我们的数据模型(表示 VLAN 的键值对,它们在 playbook 中的 config 参数下传递)仅包含 VLAN 20、30、40 和 50,因此 eos_vlans 模块仅更新与这些特定 VLAN 相关的参数。

为什么我会使用它而不是 merged?merged 和 replaced 之间的主要区别在于,merged 只是确保存在数据模型中表示的命令,而 replaced 参数使您的资源与数据模型匹配。让我们看看 eos_vlans 模块以了解它将哪些内容视为 vlan 资源的一部分。

目前有三个参数用于 **vlans** 资源

  • name
  • state(active 或 suspend)
  • vlan_id(1-4094 之间的范围)

让我们看看下面的例子

发送的数据模型

- name: desktops
  vlan_id: 20

现有的 Arista 配置

vlan 200
   state suspend
!

这就是 merged 与 replaced 的比较方式

merged

vlan 200
  name desktops
  state suspend
!

replaced

vlan 200
   name desktops
!

replaced 参数对每个配置的 VLAN 对网络设备执行数据模型。在上面的示例中,它将删除 state suspend,因为它不在数据模型中。换句话说,replaced 参数知道哪些命令不应该存在以及哪些命令应该存在。

使用覆盖的状态参数

如果我将状态参数更改为 overridden 会发生什么?只需将原始示例更改为以下内容

---
- name: add vlans
  hosts: arista
  gather_facts: false
  tasks:
    - name: add VLAN configuration
      eos_vlans:
        state: overridden
        config:
          - name: desktops
            vlan_id: 20
          - name: servers
            vlan_id: 30
          - name: printers
            vlan_id: 40
          - name: DMZ
            vlan_id: 50

现在运行 Ansible Playbook

screenshot

Ansible Playbook 现在 changed=1。但是它是否删除了 artisanal_vlan 100?

登录到其中一台 Arista 设备确认确实删除了!

rtr2#show vlan
VLAN  Name                             Status    Ports
----- -------------------------------- --------- -------------------------------
1     default                          active
20    desktops                         active
30    servers                          active
40    printers                         active
50    DMZ                              active

overridden 参数将所有 **vlans** 资源强制执行到数据模型。这意味着它会删除数据模型中未定义的 VLAN。

要点

目前有三种方法可以使用资源模块推送配置。这些是 merged、replaced 和 overridden 参数。这些允许网络工程师以增量步骤采用自动化获得更大的灵活性。我们意识到大多数人将从 merged 参数开始,因为他们熟悉新的资源模块概念。随着时间的推移,组织将转向 overridden 参数,因为他们采用其数据模型的标准 SoT(真相来源),无论它们位于何处。




使用 Ansible 和 NRE Labs 的平台无关网络自动化示例

使用 Ansible 和 NRE Labs 的平台无关网络自动化示例

2月10日,NRE Labs 项目在 Red Hat 和 Juniper Networks 的支持下启动了四个 Ansible 网络自动化练习。这篇博文涵盖了 NRE 的工作职责、NRE Labs 的目标,以及对新练习和 Red Hat 与 Juniper 联合演示的概念的快速概述。这些初始练习的目标受众是 Ansible 网络自动化的新手,他们对 Ansible 和网络自动化经验有限。这些练习的初始网络拓扑涵盖了 Ansible 自动化 Juniper Junos OS 和 Cumulus VX 虚拟网络实例。

关于 NRE Labs

Juniper 将 NRE 或网络可靠性工程师定义为可以帮助组织进行现代网络自动化的人员。这个概念有很多不同的名称,包括网络 DevOps、NetDevOps,或者简单地称为网络自动化。Juniper 和 Red Hat 意识到这项技能对于许多传统的网络工程师来说是新的,因此他们合作创建了在线练习来帮助人们开始使用 Ansible 网络自动化。具体来说,Juniper 通过 NRE Labs 与我们合作,这是一个他们发起并共同赞助的项目,它提供了一个无约束、以社区为中心的计划,使每个人都能获得自动化技能。这通过在您的浏览器中进行简短、简单的练习来实现。您可以在以下位置找到 NRE Labs:https://nrelabs.io

在 Red Hat Ansible Engine 2.9 中,我们引入了资源模块和原生事实收集的概念,因此我想确保这些练习涵盖了 Ansible 网络自动化的最新和最棒的方面,以便网络工程师能够轻松上手。如果您不熟悉资源模块、原生事实收集,甚至只是 Juniper 网络平台,我认为值得浏览一下这些练习!

让我们从网络图开始

NRE diagram

这四个练习中的每一个都有不同的目标概述、分步说明和 Ansible 知识的要点。

练习 1

本练习介绍了基于 INI 的 Ansible 清单是什么样子、Ansible 配置文件 (ansible.cfg) 以及运行 Ansible Playbook 以在 Juniper Junos 上启用 NETCONF。本练习还说明了幂等性的概念以及它为什么对网络自动化很重要。

练习 2 - 事实

本练习介绍了原生事实收集(使用 gather_facts: True)和使用 debug 模块。我们展示了如何仅使用三个任务将序列号和版本号快速打印到终端窗口。

练习 3 - 资源事实

本练习介绍了使用 junos_facts 模块结合新的 gather_network_resources 参数进行更深入的事实收集。这允许 junos_facts 模块从任何资源模块收集事实以读取网络配置并将其存储为 YAML/JSON。本练习还介绍了如何将这些事实转换为结构化的 YAML 文件。

练习 4 - 网络配置模板

本练习介绍了如何使用和理解主机变量、使用简单的 Jinja2 模板、使用 junos_config 模块用于 Juniper Junos 以及使用 template 模块用于 Cumulus Linux。本练习的总体目标是使用 Ansible 网络自动化在 Cumulus VX 设备 cvx11 和 Juniper Junos 设备 vqfx1 之间创建 OSPF 邻接关系。




Ansible 在云原生 Kubernetes 环境中有多有用?

Ansible 在云原生 Kubernetes 环境中有多有用?

我最近经常听到一个问题:“为什么您在 Kubernetes 项目中仍然使用 Ansible?” 然后经常会跟着一句:“当您开始使用 Kubernetes 后,编写您的书籍Ansible for Kubernetes有什么意义,因为 Ansible 实际上并不是必需的?”

我花了一些时间思考这些问题及其背后的动机,并想写一篇博文来解答这些问题,因为似乎很多人可能对 Kubernetes 的作用、Ansible 的作用以及为什么两者都是迁移到云原生技术栈(甚至完全云原生业务)的现代企业中必要的技术感到困惑。

需要提前说明一个重要的注意事项,我直接引用我的书中的内容

虽然 Ansible 几乎可以为您完成所有事情,但它可能不是您基础设施自动化的每个方面的正确工具。有时,其他工具可以更干净地与应用程序开发人员的工作流程集成,或者从应用程序供应商那里获得更好的支持。

我们应该始终警惕金锤谬误。没有一个单一的基础设施工具——即使是最好的 Kubernetes 作为服务平台——能够满足整个企业 IT 运营的需求。如果说有什么区别的话,那就是我们已经看到了专业工具的爆炸式增长,这在CNCF 全景图中得到了证明。

Ansible 适用于云原生基础设施管理的多个领域,但我想在这篇文章中重点介绍三个领域

Ansible_cloud-native-venn-diagram

即,Ansible 如何适应容器构建、集群管理和应用程序生命周期流程。

我特别提醒团队不要在没有更广泛的自动化策略的情况下,一头扎进 Kubernetes。Kubernetes 无法管理您的整个应用程序生命周期,也无法自行引导;您不应该满足于自动化 Kubernetes 集群内部,同时使用手动流程来构建和管理您的集群;如果您管理多个集群,这将变得尤其危险,因为对于大多数环境来说,这都是最佳实践(至少拥有一个暂存集群和一个生产集群,或者一个私有内部集群和一个面向公众的集群)。

容器构建

在过去的十年里,服务器管理和应用程序部署变得越来越自动化。通常,自动化变得更加直观和易于维护,尤其是在引入了配置管理和编排工具(如 CFEngine、Puppet、Chef 和 Ansible)之后。

然而,即使使用现代自动化工具,也没有一个完美的解决方案可以满足所有应用程序部署的需求。Java 有 WAR 文件和虚拟机。Python 有虚拟环境。PHP 有脚本和多个执行引擎。Ruby 有 Ruby 环境。能够有效管理五个、十个或更多开发栈(有时每个栈的多个版本,如 Java 7、Java 8 和 Java 11)的服务器和部署的操作团队是一个失败的主张。

幸运的是,容器化开始解决这个问题。开发人员不再交付源代码并期望操作团队能够处理多个环境的复杂性,而是交付容器,这些容器可以在几乎任何现代服务器环境中由兼容的容器运行时运行。

但在某些方面,容器构建领域的发展已经停滞不前;Dockerfile,它只不过是一个 shell 脚本,其中包含一些 Docker 特定的 DSL 和用于解决镜像层大小问题的技巧性内联命令,在许多地方仍然被用作事实上的应用程序构建脚本。

Geerling Blog 3

您遇到过多少次像这样的难以理解的 Dockerfile?

我们可以做得更好。当然,Ansible 可以使用 Dockerfile 构建和管理容器,但 Ansible 也非常擅长直接构建容器镜像——如今,您甚至不需要安装 Docker!有一些更轻量级的开源构建工具,如Buildah,它与 Ansible 容器构建工具ansible-bender集成,可以使用更具表现力和可维护性的 Ansible Playbook 构建容器。

还有其他方法可以构建容器。但我对许多开发人员和系统管理员选择使用最低公分母 Dockerfile 来构建其关键基础设施组件感到惋惜,因为还有更具表现力、可维护性和通用性的工具(如 Ansible)可以产生相同的最终结果。

集群管理

Kubernetes 集群并非凭空出现。根据您使用的集群类型,它们需要进行升级和集成的管理。集群管理可能会变得非常麻烦,尤其是在像大多数组织一样,您管理多个集群(多个生产集群、暂存和 QA 集群等)的情况下。

如果您在私有云或裸机服务器内部运行,则需要一种方法来安装 Kubernetes 并管理集群中的单个服务器。Ansible 在编排多服务器应用程序方面拥有良好的记录,而 Kubernetes 本身就是一个多服务器应用程序——它碰巧通过容器化管理一个或数千个其他多服务器应用程序。

Kubespray这样的项目已经使用 Ansible 进行自定义 Kubernetes 集群构建,并且与数十种不同的基础设施安排兼容。

即使您使用托管的 Kubernetes 产品(如 AKS、EKS 或 GKE),Ansible 也有azure_rm_aksaws_eks_clustergcp_container_cluster等模块,这些模块可以管理集群,以及数千个其他模块,从而简化并在不同云提供商之间标准化集群管理。

即使您不需要多云功能,Ansible 也提供了有用的抽象,例如使用cloudformation模块管理 AWS 上的 CloudFormation 模板部署,或者使用terraform模块管理 Terraform 部署。

很少有应用程序可以完全在 Kubernetes 内部运行,而不需要与任何外部资源(例如网络设备、存储、外部数据库服务等)协调。如果您很幸运,可能会有一个 Kubernetes 运算符来帮助您将应用程序与外部服务集成,但更多情况下则没有。同样,Ansible 通过在一个使用云原生通用语言 YAML 编写的 playbook 中管理 Kubernetes 应用程序以及外部集成来提供帮助。

我再说一遍我之前说过的话:您不应该满足于自动化 Kubernetes 集群内部,同时使用手动流程来构建和管理您的集群——尤其是在您拥有多个集群的情况下!

应用程序生命周期

Ansible 显示出巨大潜力的最后一个领域是管理 Kubernetes 内部应用程序。使用 Ansible 通过Operator SDK构建运算符,您可以将应用程序的所有生命周期管理(部署、升级、备份等)编码到Kubernetes 运算符中,以便将其放置在任何 Kubernetes 集群中——即使您不使用 Ansible 管理该集群中的任何其他内容。

与其强迫开发人员和运维团队学习 Go 或其他专门的语言来维护运算符,不如使用 YAML 和 Ansible 构建它。

这里有很多希望,尽管在某些情况下——至少在 Operator SDK 的当前状态下——您可能需要回退到 Go 以处理更高级的用例。其优势在于能够在集群中运行的应用程序运算符中依赖 Ansible 的数千个模块,以及任何类型的开发团队都能轻松采用。

对于已经使用 Ansible 的团队来说,将其现有的 Ansible 知识、角色、模块和 playbook 迁移到 Kubernetes 管理 playbook 和基于 Ansible 的运算符中,这将是轻而易举的事情。对于 Ansible 的新手团队来说,其在所有与 IT 自动化相关的事物(网络、Windows、Linux、安全等)方面的灵活性和易用性使其成为云原生编排的理想伴侣。




使用 Ansible 重启网络设备

使用 Ansible 重启网络设备

随着 11 月份 Red Hat Ansible Automation Platform 版本的发布,我们发布了 50 多个网络资源模块,以帮助网络工程师更轻松、更便捷地实现网络设备自动化。除了新的资源模块外,Andrius还在他的博客文章中讨论了事实收集增强功能,这意味着对于每个新的资源模块,用户都能够获得网络设备更广泛的事实覆盖范围。在这篇博文中,我想介绍另一个可能被忽视的酷炫增强功能。那就是网络设备能够使用wait_for_connection 模块。如果您是网络工程师,并且拥有需要重新引导设备或将其离线的操作 Ansible Playbook,则此模块将帮助您创建更多程序化的 Playbook 来处理断开连接。通过利用 wait_for_connection,网络自动化 Playbook 可以看起来和表现得更像 Linux 或 Windows 主机的 Playbook。

比较 wait_for 和 wait_for_connection

有两个很棒的模块可以等待满足某个条件,wait_for 和 wait_for_connection。如果可以避免,我强烈建议不要使用 pause 模块,我将其等同于在 Ansible Playbook 中使用编程等效的 sleep。使用这两个 wait_for 模块中的任何一个都优于 Ansible Playbook 中的随机暂停,因为它们是更具程序性的解决方案,更能适应设备完成任务所需的不同时间。pause 模块的另一个问题是,在 Ansible Tower 中使用提示符不起作用。更好的用于人机交互的解决方案是使用带有审批节点的 Ansible Tower 工作流。

wait_for 模块可以等待文件系统上的路径存在,或者等待端口重新激活。这非常适合大多数重启用例,除了系统在端口启动后无法立即登录的情况。wait_for_connection 将 wait_for 用例的功能扩展了一点。wait_for_connection 模块将确保 Ansible 能够重新登录到设备并在完成任务之前收到相应的提示。对于 Linux 和 Windows 主机,它将使用 ping 或 win_ping 模块,对于网络设备,它将确保最后使用的连接插件能够完全连接到设备。在撰写本博文时,这仅适用于network_cli连接插件。这意味着后续任务可以在 wait_for_connection 完成后立即开始按预期运行,而 wait_for 只知道端口已打开。

处理提示

对于网络设备,当我们执行诸如重新引导之类的操作任务时,通常会出现提示以确认您是否要执行操作。

例如,在 Juniper vSRX 设备上

admin@rtr3> request system reboot
Reboot the system ? [yes,no] (no)

用户必须确认重新加载才能继续。我在 cli_command 博客的深入探讨中忽略了一个内容,那就是cli_command 模块可以处理提示。cli_command 模块甚至可以处理多个提示!对于此示例,Cisco 路由器尚未保存其配置,我们正在执行重新加载。首先,Cisco 路由器将提醒我系统配置已修改,并询问我是否要在丢失运行配置之前保存。

rtr1#reload

System configuration has been modified. Save? [yes/no]:

确认yesno后,您将收到第二个提示

Proceed with reload? [confirm]

我们需要构建一个可以使用 cli_command 模块处理这两个提示的任务

---
- name: reboot ios device
  cli_command:
    command: reload
    prompt:
      - Save?
      - confirm
    answer:
     - y
     - y

上述任务将对这两个提示回答 yes,保存配置并重新加载设备。提示答案列表和答案列表必须匹配并按相同顺序排列。这意味着prompt[0]的答案必须是answer[0]

如果您想查看处理多个提示的更详细示例,这里有一个在 Juniper vSRX 设备上重置密码的示例

结合使用 reset_connection

现在您已经了解了如何使用 cli_command 重新引导设备,我们可以将其与 wait_for_connection 结合使用以创建可重用的 Ansible Playbook。但是,我们需要添加另一个任务,一个meta: reset_connection 以使此操作程序化。

我们需要确保关闭与网络设备的当前连接,以便在重新引导后重新建立到网络设备的套接字。如果连接未关闭并且命令超时时间长于重新引导所需的时间,则持久连接将尝试重用已关闭的 SSH 连接,从而导致错误“Socket is closed”。正确的 Ansible Playbook 如下所示

- reboot task (this is a snippet, full task removed for brevity)

- name: reset the connection
  meta: reset_connection

- name: Wait for the network device to reload
  wait_for_connection:
    delay: 10

现在我们有一个 Ansible Playbook,它可以在发出重新引导后重新连接到网络设备!有关完整示例,请参考此 reboot.yml 用于 Arista vEOS 网络设备的 Ansible Playbook。

下一步去哪里?

这篇博文概述了如何为重新引导网络设备创建可重用的 Ansible Playbook。接下来的步骤之一显然是构建一个可以重新引导多个网络平台的 Ansible 角色。我已经创建了一个并将其上传到 Github。此角色将在 Juniper Junos、Cisco IOS 和 Arista EOS 设备上运行,并且可以轻松修改以处理更多网络操作系统。