Назад | Перейти на главную страницу

Ansible: фатальная ошибка, создаваемая include_tasks, даже если используется блок восстановления блока

Я пытаюсь включить несколько задач на основе некоторых значений, определенных в одной hostvar, но возникают некоторые фатальные ошибки, даже если я использую блок спасения блока. У меня есть переменная профили определено в host_vars / hostname.yml:

profiles: '["profile1","trap1"]'

и роль test_profiles в / etc / ansible / роли. Здесь, в каталоге задач, у меня есть следующие файлы .yml: profile1.yml, profile2.yml, main.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

Содержание пособия:

 - 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.

block/rescue не препятствует возникновению ошибки. Он обнаруживает неудачную задачу и выполняет rescue блок для восстановления после ошибки. Но невыполненная задача все еще существует и будет видна в обзоре игры.

Я бы рекомендовал использовать отказоустойчивый подход при разработке плейбуков. В вашем случае вы можете сканировать свои локальные файлы, чтобы проверить, действителен ли ввод пользователя (предоставленная конфигурация): находятся ли файлы профилей на месте. Пользователь assert/fail модули.

В конце концов я снял блок-спасательный блок. Я нашел способ проверить, существует ли мой файл .yml. Это использует role_path переменная (которая будет возвращать путь к текущей роли - доступна начиная с Ansible 1.8 - работает только внутри роли) и test is_file.

Мой 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

Я согласен с этим решением, но я открыт и для других предложений.