我尝试根据一个 hostvar 中定义的一些值包含多个任务,但即使我使用 block-rescue 块,也会引发一些致命错误。我有变量个人资料定义于host_vars/主机名.yml:
profiles: '["profile1","trap1"]'
和角色测试配置文件在/etc/ansible/角色。在这里,在任务目录中我有以下 .yml 文件:配置文件1.yml、配置文件2.yml、主配置文件.yml。
main.yml文件的内容为:
- name: import profiles
block:
- include_tasks: "{{ item }}.yml"
with_items: "{{ profiles|default([]) }}"
rescue:
- debug: msg='Error encountered while trying to include a .yml file corresponding to a defined profile from profiles variable. Profiles - "{{ profiles }}"'
when: profiles is defined
Playbook的内容是:
- name: Test profiles config
hosts: myhost
roles:
- test_profiles
输出如下:
TASK [test_profiles : include_tasks] ***********************************************************************************************************************************************************************
included: /etc/ansible/roles/test_profiles/tasks/profile.yml for <my_host>
fatal: [<my_host>]: FAILED! => {"reason": "Unable to retrieve file contents\nCould not find or access '/etc/ansible/trap1.yml'"}
TASK [test_profiles : Ensure that profile directory exists into the D:\profiles directory] ************************************************************************************************
ok: [<my_host>]
TASK [test_profiles : Update profile.properties file] ***************************************************************************************************************************************************
ok: [<my_host>]
TASK [test_profiles : debug] *******************************************************************************************************************************************************************************
ok: [<my_host>] => {
"msg": "Error encountered while trying to include a .yml file corresponding to a defined profile from profiles variable. Profiles - \"[\"profile1\",\"trap1\"]\""
}
to retry, use: --limit @/etc/ansible/playbook_test_profiles.retry
PLAY RECAP ********************************************************************************************************************************************************************************************************
<my_host> : ok=5 changed=0 unreachable=0 failed=1
从我的角度来看,不应该出现致命错误。我在这里做错了什么,我该如何摆脱它?我也试过什么时候有条件但没有成功。
我在用着Ansible 2.4.2.0并且针对一些 Windows 主机执行任务。
答案1
block
/rescue
不会阻止错误发生。它会检测失败的任务并执行rescue
块以从错误中恢复。但失败的任务仍然存在,并将在播放回顾中可见。
我建议在设计剧本时使用快速失败方法。对于您的情况,您可以扫描本地文件以测试用户输入(提供的配置)是否有效:配置文件是否到位。用户assert
/fail
模块。
答案2
最后我删除了 block-rescue 块。我找到了一种方法来检查我的 .yml 文件是否存在。这是使用角色路径变量(将返回当前角色的路径 - 自 Ansible 1.8 起可用 - 这仅在角色内部有效)和测试是文件。
对于上述角色,我的 main.yml 如下所示:
- name: Import profiles
include_tasks: "{{ item }}.yml"
with_items: "{{ profiles|default([]) }}"
when: (role_path + '/tasks/' + item + '.yml') | is_file
由于这次检查,将不再抛出致命异常 - trap1.yml 文件将被跳过。
输出结果如下:
TASK [test_profiles : Import profiles] ***********************************************************
skipping: [<my_host>] => (item=trap1)
included: /etc/ansible/roles/test_profiles/tasks/profile1.yml for <my_host>
TASK [test_profiles : Ensure that profile directory exists into the D:\profiles directory] *******
ok: [<my_host>]
TASK [test_profiles : Update profile.properties file] ********************************************
changed: [<my_host>]
to retry, use: --limit @/etc/ansible/playbook_test_profiles.retry
PLAY RECAP ***************************************************************************************
<my_host> : ok=4 changed=1 unreachable=0 failed=0
我同意这个解决方案,但我也愿意接受其他一些建议。