通用提示
这些概念适用于所有 Ansible 活动和工件。
保持简单
尽可能以简单的方式处理事务。
仅在必要时使用高级功能,并选择最符合您用例的功能。例如,您可能不需要同时使用 vars、vars_files、vars_prompt 和 --extra-vars,同时还要使用外部清单文件。
如果某件事让你觉得复杂,那它很可能确实很复杂。请花时间寻找更简单的解决方案。
使用版本控制
将您的剧本 (playbooks)、角色 (roles)、清单 (inventory) 和变量文件保存在 git 或其他版本控制系统中,并在进行更改时提交带有明确注释的记录。版本控制提供了一个审计追踪,描述了您何时以及为何更改自动化基础设施的规则。
自定义 CLI 输出
您可以使用 回调插件 (Callback plugins) 更改 Ansible CLI 命令的输出。
避免依赖配置的内容
为了确保您的自动化项目易于理解、修改并与他人共享,您应该避免依赖配置的内容。例如,与其将 ansible.cfg 作为项目的根目录,不如使用魔术变量(如 playbook_dir 或 role_name)来确定相对于项目目录中已知位置的路径。这有助于保持自动化内容的灵活性、可重用性和易维护性。有关更多信息,请参阅 特殊变量。
剧本提示
这些提示有助于使剧本和角色更易于阅读、维护和调试。
使用空格
慷慨地使用空格(例如,在每个块或任务之前留出一行空白)会使剧本易于扫描。
始终为 Play、任务和块命名
Play、任务和块的 - name: 是可选的,但非常有用。Ansible 会在其输出中显示它运行的每个已命名实体的名称。请选择能够描述每个 Play、任务和块的功能及目的的名称。
始终说明状态
对于许多模块而言,state 参数是可选的。
不同的模块对于 state 有不同的默认设置,有些模块支持多种 state 设置。显式设置 state: present 或 state: absent 会使剧本和角色更清晰。
使用注释
即使有了任务名称和显式状态,有时剧本或角色(或清单/变量文件)的某一部分仍需要进一步解释。添加注释(任何以 # 开头的行)可以帮助他人(可能也包括未来的您自己)理解 Play、任务或变量设置的作用、方式及其原因。
使用完全限定的集合名称
使用 完全限定集合名称 (FQCN),以避免在搜索每个任务的正确模块或插件时产生歧义。
对于 内置模块和插件,请使用 ansible.builtin 集合名称作为前缀,例如 ansible.builtin.copy。
清单提示
这些提示有助于保持您的清单组织良好。
在云环境中使用动态清单
对于维护基础设施规范列表的云提供商和其他系统,请使用 动态清单 来检索这些列表,而不是手动更新静态清单文件。对于云资源,您可以使用标签来区分生产环境和预发布环境。
按功能划分清单组
一个系统可以属于多个组。请参阅 如何构建您的清单 和 模式:针对主机和组。如果您根据组中节点的功来命名组(例如 webservers 或 dbservers),您的剧本就可以根据功能针对机器进行操作。您可以使用组变量系统分配特定功能的变量,并设计 Ansible 角色来处理特定功能的用例。请参阅 角色。
分离生产和预发布清单
您可以通过为每个环境使用单独的清单文件或目录,将生产环境与开发、测试和预发布环境分开。这样,您就可以使用 -i 选择您的目标环境。将所有环境保存在一个文件中可能会导致意外!例如,当使用清单时,该清单中使用的所有 Vault 密码都必须可用。如果一个清单同时包含生产环境和开发环境,那么使用该清单的开发人员将能够访问生产环境的机密信息。
保持被加密变量的安全可见性
您应该使用 Ansible Vault 加密敏感或机密变量。但是,同时加密变量名称和变量值会使查找值的来源变得困难。为了规避这一点,您可以单独使用 ansible-vault encrypt_string 加密变量,或添加以下间接层,以便在不暴露任何机密的情况下保持变量名称的可访问性(例如通过 grep):
创建一个以组名命名的
group_vars/子目录。在此子目录中,创建两个名为
vars和vault的文件。在
vars文件中,定义所需的所有变量,包括任何敏感变量。将所有敏感变量复制到
vault文件中,并为这些变量添加vault_前缀。调整
vars文件中的变量,使用 Jinja2 语法指向对应的vault_变量:db_password: "{{ vault_db_password }}"。加密
vault文件以保护其内容。在您的剧本中使用来自
vars文件的变量名称。
运行剧本时,Ansible 会在未加密的文件中找到变量,从而从加密文件中拉取敏感变量值。变量和 Vault 文件的数量或名称没有限制。
请注意,在清单中使用此策略时,在使用该清单运行时,仍然需要 所有 Vault 密码均可用(例如对于 ansible-playbook 或 AWX/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 文件中拉取变量。