通用提示

这些概念适用于所有 Ansible 活动和工件。

保持简单

尽可能以简单的方式处理事务。

仅在必要时使用高级功能,并选择最符合您用例的功能。例如,您可能不需要同时使用 varsvars_filesvars_prompt--extra-vars,同时还要使用外部清单文件。

如果某件事让你觉得复杂,那它很可能确实很复杂。请花时间寻找更简单的解决方案。

使用版本控制

将您的剧本 (playbooks)、角色 (roles)、清单 (inventory) 和变量文件保存在 git 或其他版本控制系统中,并在进行更改时提交带有明确注释的记录。版本控制提供了一个审计追踪,描述了您何时以及为何更改自动化基础设施的规则。

自定义 CLI 输出

您可以使用 回调插件 (Callback plugins) 更改 Ansible CLI 命令的输出。

避免依赖配置的内容

为了确保您的自动化项目易于理解、修改并与他人共享,您应该避免依赖配置的内容。例如,与其将 ansible.cfg 作为项目的根目录,不如使用魔术变量(如 playbook_dirrole_name)来确定相对于项目目录中已知位置的路径。这有助于保持自动化内容的灵活性、可重用性和易维护性。有关更多信息,请参阅 特殊变量

剧本提示

这些提示有助于使剧本和角色更易于阅读、维护和调试。

使用空格

慷慨地使用空格(例如,在每个块或任务之前留出一行空白)会使剧本易于扫描。

始终为 Play、任务和块命名

Play、任务和块的 - name: 是可选的,但非常有用。Ansible 会在其输出中显示它运行的每个已命名实体的名称。请选择能够描述每个 Play、任务和块的功能及目的的名称。

始终说明状态

对于许多模块而言,state 参数是可选的。

不同的模块对于 state 有不同的默认设置,有些模块支持多种 state 设置。显式设置 state: presentstate: absent 会使剧本和角色更清晰。

使用注释

即使有了任务名称和显式状态,有时剧本或角色(或清单/变量文件)的某一部分仍需要进一步解释。添加注释(任何以 # 开头的行)可以帮助他人(可能也包括未来的您自己)理解 Play、任务或变量设置的作用、方式及其原因。

使用完全限定的集合名称

使用 完全限定集合名称 (FQCN),以避免在搜索每个任务的正确模块或插件时产生歧义。

对于 内置模块和插件,请使用 ansible.builtin 集合名称作为前缀,例如 ansible.builtin.copy

清单提示

这些提示有助于保持您的清单组织良好。

在云环境中使用动态清单

对于维护基础设施规范列表的云提供商和其他系统,请使用 动态清单 来检索这些列表,而不是手动更新静态清单文件。对于云资源,您可以使用标签来区分生产环境和预发布环境。

按功能划分清单组

一个系统可以属于多个组。请参阅 如何构建您的清单模式:针对主机和组。如果您根据组中节点的功来命名组(例如 webserversdbservers),您的剧本就可以根据功能针对机器进行操作。您可以使用组变量系统分配特定功能的变量,并设计 Ansible 角色来处理特定功能的用例。请参阅 角色

分离生产和预发布清单

您可以通过为每个环境使用单独的清单文件或目录,将生产环境与开发、测试和预发布环境分开。这样,您就可以使用 -i 选择您的目标环境。将所有环境保存在一个文件中可能会导致意外!例如,当使用清单时,该清单中使用的所有 Vault 密码都必须可用。如果一个清单同时包含生产环境和开发环境,那么使用该清单的开发人员将能够访问生产环境的机密信息。

保持被加密变量的安全可见性

您应该使用 Ansible Vault 加密敏感或机密变量。但是,同时加密变量名称和变量值会使查找值的来源变得困难。为了规避这一点,您可以单独使用 ansible-vault encrypt_string 加密变量,或添加以下间接层,以便在不暴露任何机密的情况下保持变量名称的可访问性(例如通过 grep):

  1. 创建一个以组名命名的 group_vars/ 子目录。

  2. 在此子目录中,创建两个名为 varsvault 的文件。

  3. vars 文件中,定义所需的所有变量,包括任何敏感变量。

  4. 将所有敏感变量复制到 vault 文件中,并为这些变量添加 vault_ 前缀。

  5. 调整 vars 文件中的变量,使用 Jinja2 语法指向对应的 vault_ 变量:db_password: "{{ vault_db_password }}"

  6. 加密 vault 文件以保护其内容。

  7. 在您的剧本中使用来自 vars 文件的变量名称。

运行剧本时,Ansible 会在未加密的文件中找到变量,从而从加密文件中拉取敏感变量值。变量和 Vault 文件的数量或名称没有限制。

请注意,在清单中使用此策略时,在使用该清单运行时,仍然需要 所有 Vault 密码均可用(例如对于 ansible-playbookAWX/Ansible Tower)。

执行技巧

这些技巧适用于使用 Ansible,而不是针对 Ansible 工件本身。

使用执行环境 (Execution Environments)

使用名为 执行环境 的便携式容器镜像来降低复杂性。

优先在预发布环境中尝试

在将更改部署到生产环境之前,先在预发布环境中测试更改始终是一个好主意。您的环境不必具有相同的规模,您可以使用组变量来控制环境之间的差异。您还可以使用 --syntax-check 标志在预发布环境中检查任何语法错误,如下例所示:

ansible-playbook --syntax-check

分批更新

使用 serial 关键字来控制批处理中一次更新多少台机器。请参阅 控制任务运行位置:委托和本地操作

处理操作系统和发行版差异

组变量文件和 group_by 模块可以协同工作,帮助 Ansible 在需要不同设置、包和工具的一系列操作系统和发行版上执行操作。group_by 模块会创建符合特定条件的主机的动态组。此组不需要在清单文件中定义。这种方法让您可以针对不同的操作系统或发行版执行不同的任务。

例如,以下 Play 根据操作系统名称将所有系统归类到动态组中:

- name: Talk to all hosts just so we can learn about them
  hosts: all
  tasks:

    - name: Classify hosts depending on their OS distribution
      ansible.builtin.group_by:
        key: os_{{ ansible_facts['distribution'] }}

后续的 Play 可以使用这些组作为 hosts 行上的模式,如下所示:

- hosts: os_CentOS
  gather_facts: False
  tasks:

    # Tasks for CentOS hosts only go in this play.
    - name: Ping my CentOS hosts
      ansible.builtin.ping:

您还可以在组变量文件中添加特定于组的设置。在以下示例中,CentOS 机器的 asdf 值为“42”,而其他机器则为“10”。您还可以使用组变量文件将角色应用于系统以及设置变量。

---
# file: group_vars/all
asdf: 10

---
# file: group_vars/os_CentOS.yml
asdf: 42

注意

所有三个名称必须匹配:group_by 任务创建的名称、后续 Play 中模式的名称以及组变量文件的名称。

当您只需要特定于操作系统的变量而非任务时,可以使用与 include_vars 相同的设置:

- name: Use include_vars to include OS-specific variables and print them
  hosts: all
  tasks:

    - name: Set OS distribution dependent variables
      ansible.builtin.include_vars: "os_{{ ansible_facts['distribution'] }}.yml"

    - name: Print the variable
      ansible.builtin.debug:
        var: asdf

这会从 group_vars/os_CentOS.yml 文件中拉取变量。

另请参阅

YAML 语法

学习 YAML 语法

使用 Playbook

复习基础剧本功能

集合索引

浏览现有的集合、模块和插件

您应该开发模块吗?

学习如何通过编写自己的模块来扩展 Ansible

模式:定位主机和组

学习如何选择主机

交流方式

有疑问?需要帮助?想分享你的想法?请访问 Ansible 通信指南