Ansible的block是Playbook中用于逻辑组织任务的语法结构,本身不执行操作,但可统一控制任务行为,并通过rescue实现错误捕获与回滚、always保证收尾动作必执行。

Ansible 的 block 模块不是独立模块,而是 Playbook 中用于逻辑组织任务的语法结构,它本身不执行操作,但能统一控制一组任务的行为,并配合 rescue 和 always 实现可靠的分组执行与异常捕获。核心在于把“可能出错的操作”放进 block,“补救动作”写在 rescue,“收尾动作”放在 always。
用 block 统一控制多任务的执行条件和权限
避免为每个任务重复写 when、become、ignore_errors 等参数。直接在 block 层级声明,整组任务自动继承:
- 所有任务只在 CentOS 8 上运行:
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "8" - 整组需提权操作:
become: true,无需每个 task 再加become: true - 允许某类失败不中断流程:
ignore_errors: yes(但更推荐用 rescue 做精准处理)
用 block + rescue 实现错误捕获与自动回滚
block 相当于 try,rescue 相当于 except。只要 block 中任意一个任务失败(返回非零状态、模块报错等),Ansible 就跳过剩余 block 任务,立即执行 rescue 中的任务:
- 典型场景:更新 Nginx 配置前先备份,部署后执行
nginx -t验证;若验证失败,rescue 中恢复备份配置并重启服务 - rescue 不是“重试”,而是“故障应对”——它只执行一次,且仅在 block 出错时触发
- rescue 内任务同样支持
become、when等,可做权限判断或环境适配
用 always 保证清理与日志等收尾动作必执行
always 块无论 block 成功、失败,还是 rescue 是否触发,都会执行。适合做资源释放、状态记录等不可省略的收尾工作:
- 删除临时目录或文件(如
file: state=absent path=/tmp/deploy-tmp) - 写入操作日志到集中位置(如
shell: echo "$(date) deploy_nginx: {{ ansible_date_time.epoch }}" >> /var/log/ansible-deploy.log) - 触发 handler(如
meta: flush_handlers)确保服务最终处于期望状态
实际部署指令分组示例(Nginx 配置热更)
以下是一个贴近生产环境的 block 分组结构,涵盖准备、变更、验证、回滚、收尾全流程:
- name: Deploy and validate nginx config
block:
- name: Backup current config
copy:
src: /etc/nginx/nginx.conf
dest: /etc/nginx/nginx.conf.bak
backup: no
- name: Deploy new config from template
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
- name: Test nginx config syntax
command: nginx -t
changed_when: false
rescue:
- name: Rollback config on syntax error
copy:
src: /etc/nginx/nginx.conf.bak
dest: /etc/nginx/nginx.conf
- name: Restart nginx to apply fallback
systemd:
name: nginx
state: restarted
always:
- name: Log deployment outcome
shell: echo "$(date '+%Y-%m-%d %H:%M') nginx deploy: {{ 'SUCCESS' if ansible_failed is not defined else 'FAILED' }}" >> /var/log/ansible-nginx.log
args:
executable: /bin/bash


















