Ansible 任务调试:检查变量、修正参数并重新执行

Ansible 提供任务调试器,让你能在执行过程中修正错误。你可以直接在出错任务的上下文中检查或设置变量、更新模块参数,再使用新的变量和参数重新执行任务。这样可以查明失败原因,并继续执行 playbook。

启用调试器

调试器默认关闭。要在 playbook 执行期间进入调试器,必须先启用它。可以使用 debugger 关键字、配置文件或环境变量,也可以使用调试策略。

使用 debugger 关键字

此功能在 Ansible 2.5 中加入。debugger 可以在 play、role、block 或 task 上启用或禁用调试器,适合开发和扩展 playbook、play 及 role 时使用。对于新增或修改后的任务,启用调试器后就能在失败时直接修正问题。这个关键字接受以下五个值:

值 行为
always 无论任务结果如何,始终进入调试器。
never 无论任务结果如何,都不进入调试器。
on_failed 仅在任务失败时进入调试器。
on_unreachable 仅在主机无法访问时进入调试器。
on_skipped 仅在任务被跳过时进入调试器。

debugger 的显式设置会覆盖启用或禁用调试器的全局配置。如果在多个层级设置了这个关键字,Ansible 采用粒度最细的定义。play 或 role 级定义适用于其中所有 block 和 task,除非更具体的层级指定了其他值;block 级定义覆盖 play 或 role,并适用于该 block 中的任务;task 级定义仅适用于该任务,且优先于 block、play 和 role 的定义。

关键字使用示例

在单个任务上设置:

- name: Execute a command
  ansible.builtin.command: "false"
  debugger: on_failed

在 play 上设置:

- name: My play
  hosts: all
  debugger: on_skipped
  tasks:
    - name: Execute a command
      ansible.builtin.command: "true"
      when: False

在多个层级设置:

- name: Play
  hosts: all
  debugger: never
  tasks:
    - name: Execute a command
      ansible.builtin.command: "false"
      debugger: on_failed

最后一个示例中,play 的值是 never,而 task 的值是 on_failed。如果任务失败,Ansible 仍会进入调试器,因为任务定义覆盖了父级 play 的定义。

使用配置文件或环境变量

这两种全局启用方式在 Ansible 2.5 中加入。可以在 ansible.cfg 或环境变量中设置任务调试器,只接受 True 与 False。设置为 True 后,Ansible 默认在任务失败时进入调试器。

要从 ansible.cfg 启用,在 [defaults] 节中加入:

[defaults]
enable_task_debugger = True

要通过环境变量启用,在运行 playbook 时传入该变量:

ANSIBLE_ENABLE_TASK_DEBUGGER=True ansible-playbook -i hosts site.yml

全局启用后,每个失败的任务都会进入调试器,除非 role、play、block 或 task 明确禁用它。如果需要更精确地控制触发条件,请使用 debugger 关键字。

使用调试策略

旧版 playbook 或 role 可能通过 strategy 启用调试器。可以在 play 级别、ansible.cfg,或通过环境变量 ANSIBLE_STRATEGY=debug 设置。例如:

- hosts: test
  strategy: debug
  tasks:
    - name: Example task
      debug:
        msg: "This is a debug message"

也可以在 ansible.cfg 中配置:

[defaults]
strategy = debug

这是一种与 Ansible 2.5 之前版本相兼容的旧方法,未来版本可能移除它。

在调试器中解决错误

进入调试器后,可以使用下文列出的七个命令排查错误。下面的 playbook 定义了变量 var1,却在任务中误用了未定义的 wrong_var:

- hosts: test
  debugger: on_failed
  gather_facts: false
  vars:
    var1: value1
  tasks:
    - name: Use a wrong variable
      ansible.builtin.ping: data={{ wrong_var }}

运行该 playbook 时,任务失败会触发调试器。在调试提示符中,可以修改模块参数或变量,然后重新运行任务。以下是官方文档提供的示例输出:

PLAY ***************************************************************************
TASK [wrong variable] **********************************************************
fatal: [192.0.2.10]: FAILED! => {"failed": true, "msg": "ERROR! 'wrong_var' is undefined"}
Debugger invoked
[192.0.2.10] TASK: wrong variable (debug)> p result._result
{'failed': True,
 'msg': 'The task includes an option with an undefined variable. The error '
        "was: 'wrong_var' is undefined\n"
        '\n'
        'The error appears to have been in '
        "'playbooks/debugger.yml': line 7, "
        'column 7, but may\n'
        'be elsewhere in the file depending on the exact syntax problem.\n'
        '\n'
        'The offending line appears to be:\n'
        '\n'
        '  tasks:\n'
        '    - name: wrong variable\n'
        '      ^ here\n'}
[192.0.2.10] TASK: wrong variable (debug)> p task.args
{u'data': u'{{ wrong_var }}'}
[192.0.2.10] TASK: wrong variable (debug)> task.args['data'] = '{{ var1 }}'
[192.0.2.10] TASK: wrong variable (debug)> p task.args
{u'data': '{{ var1 }}'}
[192.0.2.10] TASK: wrong variable (debug)> redo
ok: [192.0.2.10]
PLAY RECAP *********************************************************************
192.0.2.10               : ok=1    changed=0    unreachable=0    failed=0

将任务参数从 wrong_var 改为 var1 后,示例中的任务成功完成。

可用的调试命令

可以在调试提示符中使用以下七个命令:

命令 简写 作用
print p 输出任务信息。
task.args[key] = value 无 更新模块参数。
task_vars[key] = value 无 更新任务变量;之后必须执行 update_task。
update_task u 使用更新后的任务变量重新创建任务。
redo r 重新运行任务。
continue c 从下一个任务开始继续执行。
quit q 退出调试器。

输出信息:print

print task、print task.args、print task_vars、print host 与 print result 用于输出对应的任务信息。例如:

[192.0.2.10] TASK: install package (debug)> p task
TASK: install package
[192.0.2.10] TASK: install package (debug)> p task.args
{u'name': u'{{ pkg_name }}'}
[192.0.2.10] TASK: install package (debug)> p task_vars
{u'ansible_all_ipv4_addresses': [u'192.0.2.10'],
 u'ansible_architecture': u'x86_64',
 ...
}
[192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name']
u'bash'
[192.0.2.10] TASK: install package (debug)> p host
192.0.2.10
[192.0.2.10] TASK: install package (debug)> p result._result
{'_ansible_no_log': False,
 'changed': False,
 u'failed': True,
 ...
 u'msg': u"No package matching 'not_exist' is available"}

更新模块参数:task.args

task.args[key] = value 用来更新模块参数。下面的 playbook 使用了无效的软件包名称:

- hosts: test
  strategy: debug
  gather_facts: true
  vars:
    pkg_name: not_exist
  tasks:
    - name: Install a package
      ansible.builtin.apt: name={{ pkg_name }}

运行时,无效的软件包名称导致错误并进入调试器。可以先查看模块参数,再把软件包名称改为正确的值:

[192.0.2.10] TASK: install package (debug)> p task.args
{u'name': u'{{ pkg_name }}'}
[192.0.2.10] TASK: install package (debug)> task.args['name'] = 'bash'
[192.0.2.10] TASK: install package (debug)> p task.args
{u'name': 'bash'}
[192.0.2.10] TASK: install package (debug)> redo

更新模块参数后,使用 redo,让任务以新的参数重新执行。

更新任务变量:task_vars

task_vars[key] = value 用来更新任务变量。对于上一个示例,也可以查看并更新变量,而不直接修改模块参数:

[192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name']
u'not_exist'
[192.0.2.10] TASK: install package (debug)> task_vars['pkg_name'] = 'bash'
[192.0.2.10] TASK: install package (debug)> p task_vars['pkg_name']
'bash'
[192.0.2.10] TASK: install package (debug)> update_task
[192.0.2.10] TASK: install package (debug)> redo

修改任务变量后,必须先使用 update_task 加载新变量,然后才能使用 redo 重新运行任务。

从 Ansible 2.5 起,这个名称由 vars 改为 task_vars,以避免与 Python 的 vars() 函数冲突。

重新创建任务:update_task

此命令在 Ansible 2.8 中加入。u 或 update_task 会依据任务原始数据结构及模板,使用更新后的任务变量重新创建任务。上面的更新变量示例展示了它的用法。

重新执行:redo

r 或 redo 会重新运行当前任务。

继续执行:continue

c 或 continue 会从下一个任务开始继续执行。

退出:quit

q 或 quit 会退出调试器,并中止 playbook 执行。

调试器与 free 策略如何交互

使用默认的 linear 策略时,调试器处于活动状态期间,Ansible 会暂停执行;输入 redo 后,会立即重新运行被调试的任务。

free 策略不等待所有主机同步推进。因此,在一台主机上的任务失败之前,另一台主机的后续任务可能已经排入队列。调试器处于活动状态时,Ansible 不会新增排队任务,也不会执行任务,但已排队的任务仍会保留。

退出调试器后,这些已排队任务会立即恢复执行。如果通过 redo 重新安排一个任务,其他已排队任务可能先于该任务执行。更多说明见 执行策略。

延伸阅读

来源:Ansible 社区文档 Debugging tasks。版权归 Ansible 文档贡献者所有。本文依据 官方文档源仓库的 GNU GPL 第 3 版许可制作中文翻译,译文与排版修改日期为 2026-10-03,代码及示例输出保持原样。本文及其修改依 GNU GPL 第 3 版提供,不提供担保。许可全文随离线稿件保存在 COPYING.GPL-3.0.txt,也可阅读 原仓库许可全文;可编辑原文位于官方 RST 源文件。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容