Ansible 任务控制与事实管理指南:从事实收集到任务流程掌控
三、 Ansible 事实 (Facts)
1.事实是Ansible在执行play之前,通过 setup 模块自动从受管主机收集的系统信息。
2.事实的用途:
获取主机的动态信息(如主机名、IP地址、操作系统、硬件配置、网络信息等)。
基于这些信息在Playbook中做出决策(条件判断、动态配置)。
3.访问事实 (Facts as Variables):
新命名规范 (Ansible 2.5+):事实变量存储在 ansible_facts 字典中。例如:{{ ansible_facts['hostname'] }}, {{ ansible_facts['default_ipv4']['address'] }}。
旧命名规范 (兼容):旧版本中使用 ansible_ 前缀(如 {{ ansible_hostname }})。Ansible目前仍兼容,但推荐使用新规范。
魔法变量 (Magic Variables):一些特殊的内置变量,如:
hostvars:访问其他主机的变量和事实。
group_names:当前主机所属的组列表。
groups:所有主机组和主机的列表。
inventory_hostname:主机在清单文件中的名称。
4.事实管理:
关闭事实收集:如果不需要事实或为了加快执行速度,可以在play中设置 gather_facts: no。
收集事实子集:使用 setup 模块的 filter 参数,只收集特定类型的事实(如 filter: ansible_os_*)或排除特定事实(如 filter: "!ansible_mounts")。
创建自定义事实:
位置:在受管主机的 /etc/ansible/facts.d/ 目录下创建文件。
格式:文件名必须以 .fact 结尾,格式为INI或JSON(不能是YAML)。
使用:自定义事实被收集后,会像内置事实一样,通过 ansible_facts['custom_facts']['section']['key'] 的方式访问。
四、 任务控制 (Task Control)
1.任务控制是编写复杂、健壮Playbook的关键,包括循环、条件、处理程序和错误处理。
2.循环 (Looping)
目的:避免重复编写相似的任务。
关键字:loop (Ansible 2.5+ 推荐)。旧的 with_* 关键字(如 with_items)已过时。
简单循环:迭代一个简单列表。
yaml
loop: ["httpd", "firewalld"]
字典列表循环:迭代一个字典列表,使用 item 访问每个字典的键值。
yaml
loop: "{{ users_list }}"
注册循环结果:register 变量会包含一个包含每次迭代结果的列表。
3.条件判断 (Conditional Execution)
目的:根据特定条件决定是否执行某个任务。
关键字:when。
条件来源:变量、注册变量、事实、魔法变量。
语法:
布尔值:when: some_variable
比较:when: ansible_facts['distribution'] == "Rocky" (注意使用 ==)
多条件:使用 and, or, not 或将条件放入列表(列表内条件为 and 关系)。
组合循环与条件:when 条件会对 loop 中的每一项进行评估。
4.处理程序 (Handlers)
目的:在其他任务改变了系统状态后,触发需要执行的操作(通常是重启服务或重启主机),实现幂等性。
核心机制:
触发:由任务使用 notify: 关键字通知一个处理程序。
执行时机:在play中所有其他任务完成后,仅执行一次,无论被通知多少次。
执行条件:只有当触发它的任务状态为 CHANGED 时,处理程序才会被调用。如果任务没有改变系统(OK 状态),则不会通知。
定义位置:在play中使用 handlers: 关键字定义处理程序列表。
优点:确保服务只在必要时重启,提高效率和安全性。
5.错误处理 (Error Handling)
忽略失败:使用 ignore_errors: yes 使play在任务失败后继续执行。适用于预期可能失败的命令。
强制执行处理程序:使用 force_handlers: yes 在play级别。即使通知了处理程序的任务失败,也强制执行该处理程序。
自定义失败条件:使用 failed_when 关键字。即使命令本身返回成功,但根据其输出内容,可以将其标记为失败。
覆盖变更状态:使用 changed_when 关键字。可以强制将任务标记为 CHANGED 或 OK,从而控制是否触发处理程序。例如,changed_when: true 会强制触发处理程序。
块 (Blocks):将多个任务分组,实现更复杂的错误处理逻辑。
block: 主要任务组。
rescue: 当 block 中任何任务失败时执行的任务(类似 except)。
always: 无论 block 成功还是失败,都始终会执行的任务(类似 finally)。