Ansible 变量类型:如何在 Ansible 中使用变量?

Ansible 变量在管理不同系统之间的差异时非常有用。该平台可以通过一条命令同时在多个系统上执行 playbook 和任务。系统之间的差异可以通过使用 YAML 语法(包括列表和字典)定义变量来表达。

这些变量可以在多个位置设置,例如命令行、可复用的文件或角色、inventory 或 playbook。此外,在 playbook 运行期间,还可以通过将任务的返回值赋给变量来生成新变量。

在本指南中,我们将深入介绍 Ansible 变量的概念,详细讲解它们的用法、类型和功能。

Ansible 变量有什么意义?

Ansible 是一款流行的配置管理工具,被广泛用于高效管理多台服务器。它通过自动化流程简化了服务器配置和应用安装等任务。借助 Ansible,您可以轻松管理大量远程服务器,并从一个中央控制节点按顺序执行任务。这简化了管理工作,提高了效率,并确保整个基础设施的一致性。Ansible 中的变量是简化项目中动态值管理的强大工具,能够降低人为出错的可能性。它们为处理不同环境和系统之间的差异提供了便捷的方式。借助变量,我们可以灵活地在不同位置定义它们,每个位置都有不同的优先级,以满足特定需求。此外,Ansible 还允许我们通过捕获任务输出,直接在 playbook 中注册新变量,进一步增强了定制能力。Ansible 中一种值得关注的变量类型是 Ansible facts,它提供从远程主机获取的有价值的信息。这些 facts 可以通过 ansible_facts 变量访问,帮助我们了解目标系统的各个方面。

例如,我们可以获取操作系统发行版(ansible_distribution)和版本(ansible_version)的详细信息、主机设备信息、Ansible 使用的 Python 版本(ansible_python_version)以及系统架构等。利用 Ansible facts,可以帮助我们做出更明智的决策,构建高效的自动化工作流,从而丰富我们的项目。

Ansible 变量命名规则

Ansible 中的变量需要遵循特定的命名规范进行定义。

  • 在 Ansible 中,变量名必须以大写或小写字母开头,例如 username、Saleprice 等。
  • Ansible 中的变量可以包含字母(大写、小写或两者组合)、下划线和数字,例如 username、sale_price、foo23 等。
  • 某些字符串或关键字被保留用于特殊功能,不能用作有效的变量名,包括 Playbook 关键字和 Python 关键字。

虽然不是强制要求,但建议使用简单且具有描述性的变量名。这样可以简化您在 Ansible 中的工作流程。

Ansible 变量的类型

Ansible 变量有多种类型,您可以在 playbook 中以不同方式定义和使用它们。

  • 简单变量;
  • 特殊变量(连接变量、魔法变量、Ansible facts);
  • 注册变量。

Ansible 简单变量

简单变量最基本的用法,是在 playbook YAML 文件中使用单个值定义一个变量。

我们来看一个打印消息的简单 playbook 示例。

---
- name: Example Playbook with Variables
  hosts: all
  gather_facts: false
  vars:
    greeting_message: "Hello, welcome to Ansible variables understanding!"
  tasks:
    - name: Display Greeting
      debug:
        msg: "{{ greeting_message }}"

在上面的 playbook 中,我们演示了 Ansible 简单变量的用法:

  • name: 标识 playbook 并提供描述。
  • hosts: 指定执行任务的目标主机。这里我们设置为 all。
  • tasks: 包含要在指定主机上执行的任务列表。
  • name(在任务内部):描述该任务。
  • greeting_message 是一个变量,包含消息 "Hello, welcome to Ansible variables understanding!"。
  • debug: 指定一个用于打印调试消息的模块。debug 任务会显示 greeting_message 变量的值。
  • msg: 定义要打印的消息。

运行该 playbook,greeting_message 的值将显示在 msg 中。

在任务中设置 Ansible 变量

通过 set_fact 设置的变量是用户自定义的变量,您可以在 playbook 或角色中定义它们并为其赋值。这些变量通常用于存储可能随环境或需求变化的信息。您可以在不同的作用域级别设置变量,例如全局、playbook 内部或特定任务中。我们来看一个示例:

---
- name: Set variables
  hosts: localhost
  tasks:
    - name: Set user role variables
      set_fact:
        user_name: "supervisor"
        user_permissions: "rwx"
    - name: Display user variables
      debug:
        msg: "The user '{{ user_name }}' has permissions '{{ user_permissions }}'"

使用数组和循环的 Ansible 变量

在 Ansible 中,与编程语言一样,数组用于存储相关项的集合。这些称为数组的集合可以包含多个相同数据类型的值。

下面是一个 Ansible playbook 示例,它使用包含数组/列表的变量,并演示如何遍历它们:

---
- name: Example Playbook with Variable Arrays and Loops
  hosts: all
  gather_facts: false
  vars:
    fruits:
      - apple
      - banana
      - orange
  tasks:
    - name: Display Fruits
      debug:
        msg: "The fruit is {{ item }}"
      loop: "{{ fruits }}"

在上面的 playbook 中,“fruits”是一个包含水果数组/列表的变量。loop 指令用于遍历 fruits 数组。在循环内部,debug 任务通过 item 变量显示每一种水果。

Ansible 特殊变量

在 Ansible 中,特殊变量是预定义的变量,包含有关系统、inventory 或 playbook 执行上下文的重要信息。Ansible 特殊变量分为不同类型,例如魔法变量、连接变量和 Ansible facts。它们的名称是保留的,这意味着您不能定义与这些特殊变量同名的变量。

Ansible Facts

Ansible facts 是在 playbook 执行期间收集的主机详细信息。这个过程称为收集 facts,包括获取系统的 IP 地址、当前日期和时间、BIOS 规格、磁盘分区以及其他相关硬件信息。

在这个示例中:

我们将 gather_facts 设置为 true,告诉 Ansible 收集目标主机的信息。然后使用 debug 模块显示部分收集到的 facts,例如主机名(ansible_hostname)、发行版(ansible_distribution)及其版本(ansible_distribution_version),以及总内存(ansible_memtotal_mb)。当您使用 ansible-playbook 运行该 playbook 时,Ansible 会从 inventory 文件中指定的所有主机收集 facts,并显示每台主机的相关信息。这里我们只收集“localhost”的信息。

要查看与本地系统相关的 Ansible facts,请执行以下命令:

$ sudo ansible -m setup localhost

上述命令使用 setup 模块收集“localhost”系统的 facts。它会输出 JSON 格式的结果,包含有关本地系统的大量信息,例如硬件详情、网络配置、操作系统等。

Ansible 魔法变量

Ansible 魔法变量是预定义的变量,提供有关执行环境、当前主机或其他上下文的详细信息。Ansible 中的魔法变量由工具自动生成,并且是不可变的,这意味着用户无法修改它们的值。这些变量始终代表 Ansible 的内部状态,用户无法更改。因此,它们只能以预定义的形式使用,无法自定义。

以下是在 playbook 中使用 Ansible 魔法变量的示例:

---
- hosts: all
  tasks:
    - debug:
        var: ansible_version

Ansible 连接变量

Ansible 中的连接变量是一种配置设置,决定了 Ansible 在执行任务和 playbook 时如何与远程主机建立连接。它们为管理不同的连接类型、认证机制和特定主机配置提供了灵活性。

我们来看一个在 localhost 上运行 date 命令的示例。

---
- name: Run Command on Localhost
  hosts: localhost
  connection: local
  gather_facts: no
  vars:
    command_to_run: "date"
  tasks:
    - name: Execute Command
      ansible.builtin.shell: "{{ command_to_run }}"
      register: command_output
    - name: Display Command Output
      ansible.builtin.debug:
        msg: "Command output: {{ command_output.stdout }}"

在上面的示例中:

  • name: 描述 playbook 的名称,即 "Run Command on Localhost"。
  • hosts: 指定 playbook 的目标主机。这里设置为 localhost,表示 playbook 只在本地机器上运行。
  • connection: 指定 Ansible 如何连接目标主机。设置为 local 表示 Ansible 直接在控制节点(即本地机器)上执行任务。
  • gather_facts: 控制 Ansible 是否收集目标主机的 facts。这里设置为 no,表示 Ansible 不收集任何 facts。
  • vars: 定义该 playbook 专用的变量。这里设置了一个名为 command_to_run 的变量,其值为 "date",代表获取当前日期的 shell 命令。
  • tasks: 包含 Ansible 将要执行的任务列表。
  • name: 描述任务的用途,即执行命令并显示其输出。
  • ansible.builtin.shell: 该任务模块在目标主机上执行 shell 命令。这里它运行 command_to_run 变量中指定的命令。
  • register: 捕获 shell 命令的输出以供后续使用。输出保存在 command_output 中。
  • ansible.builtin.debug: 该任务模块用于打印调试消息。这里它显示保存在 command_output.stdout 中的命令输出。

运行此 Ansible playbook 后,您将看到 date 命令在 localhost 上执行,并显示输出结果,即当前的日期和时间。

Ansible 注册变量

Ansible 的 register 模块用于将任务的输出保存到变量中。通常,这涉及使用 shell 或 command 等模块在远程主机上执行任务。register 模块捕获任务输出后,就可以在各种场景中引用它,例如条件语句或打印输出。

我们来看看如何使用 register 捕获任务输出。在下面的 playbook 中,free 命令在本地主机上执行。register 模块捕获该命令的输出,然后将其显示在标准输出(stdout)上。

---
- name: Ansible Register Variable Example
  hosts: localhost
  tasks:
    - name: Get Memory Usage
      shell: "free"
      register: memory_usage
    - debug:
        var: memory_usage.stdout

在这个示例中:

shell 模块用于执行 free 命令,该命令显示内存使用情况。free 命令的输出被 register 模块捕获并保存在 memory_usage 变量中。随后,debug 模块通过 memory_usage 变量的 stdout 属性显示捕获到的 free 命令输出。该 playbook 会在 localhost 上执行 free 命令,但您也可以将 hosts 指定为 inventory 文件中的所有主机,并显示从每台主机捕获的内存使用信息。

总结

在本指南中,我们深入探讨了 Ansible 变量,介绍了如何在不同场景中定义和引用它们。通过使用变量,您可以对 playbook 进行定制和参数化,从而提升灵活性和适应性。

此外,我们还概述了在 playbook 中简化变量使用的关键最佳实践,以确保更顺畅的自动化工作流并降低复杂度。我们演示了如何在 playbook 中使用不同类型的 Ansible 变量并在您的系统上运行。如果您使用的是远程主机或 Linux VPS 服务器,可以按照上述指南在您的 Linux 服务器上使用 Ansible 变量。

如需进一步了解 Ansible 变量并探索更多可能性,建议您查阅 Ansible 官方文档。在那里,您将找到全面的资源和有关 Ansible 变量的更多见解,帮助您充分发挥这一强大功能的潜力。善用 Ansible 变量的灵活性,优化您的自动化策略,提升整个基础设施的效率。