ansible 的 block、rescue 和 always 组合实现部署链路“事务闭环”:block 封装强关联任务并统一控制执行;rescue 在 block 失败时执行确定性兜底动作;always 无条件运行收尾任务保障善后。

Ansible 的 block、rescue 和 always 三者组合,是实现部署链路“事务闭环”的核心机制——它不提供数据库级原子性,但能模拟“成功则全走通、失败则兜底补救、收尾动作必执行”的类事务行为。关键在于逻辑分层清晰、意图明确、收口可控。
用 block 封装一组强关联的部署任务
把本应一起成功或一起跳过的操作归为一个逻辑单元。比如安装软件、写配置、启动服务这三步必须连贯执行,不能只装不启,也不能只启不配。
- 所有任务写在
block:下,作为整体受统一条件控制(如when: ansible_distribution == "Rocky") - 避免每个任务单独加
when,减少重复判断和维护成本 - 若 block 内任一任务失败(
failed状态),整个 block 立即中止,不再执行后续任务
用 rescue 实现失败后的确定性兜底
当 block 失败时,rescue 不是重试,而是执行预设的补偿或诊断动作,确保环境可恢复、可观测、可排查。
- 常见做法:清理临时文件、回滚部分变更、记录错误日志、发送告警、启动备用服务
- rescue 中的任务仅在 block 出现
failed时运行,不会因skipped或ok触发 - 示例:block 中创建 LVM 失败 → rescue 中输出提示并尝试创建更小容量的卷
用 always 保障收尾动作无条件执行
无论 block 成功、失败还是被跳过,always 中的任务都会运行。这是闭环的“最后一步”,用于统一收口。
- 典型用途:清理工作目录、关闭连接、重启监控代理、归档部署日志、更新部署状态标记文件
- 注意:always 本身失败不会中断 playbook,但会记录 warning;如需严格保障,可在 always 内加
ignore_errors: yes - 与 rescue 不同,always 不处理异常,只做“善后”
结合 fail 模块主动干预流程走向
有时需要人工判定某步不可继续(比如校验失败、依赖缺失),这时用 fail: 主动终止 block,触发 rescue 流程。
-
fail: msg: "目标路径 /opt/app 不存在,中止部署"可让流程快速进入 rescue - 配合
failed_when:可自定义失败阈值(如命令返回码非 0 不一定算错,需按业务判断) - 避免用
ignore_errors: yes掩盖问题,而要用 block+rescue 显式表达“这里可能出错,我们有对策”











