Ansible: Erro fatal lançado por include_tasks mesmo se um bloco de resgate de bloco for usado

1

Estou tentando incluir várias tarefas com base em alguns valores definidos em um hostvar, mas alguns erros fatais são gerados mesmo se eu estiver usando o bloco block-rescue. Eu tenho a variável profiles definida em host_vars / hostname.yml :

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

e o papel test_profiles em / etc / ansible / roles . Aqui, no diretório de tarefas, eu tenho os seguintes arquivos .yml: profile1.yml, profile2.yml, main.yml .

O conteúdo do arquivo 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

O conteúdo do Playbook é:

 - name: Test profiles config
   hosts: myhost
   roles:
     - test_profiles

A saída é algo assim:

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

Do meu ponto de vista, esse erro fatal não deve aparecer. O que estou fazendo errado aqui e como posso me livrar disso? Eu também tentei com um quando condicional, mas sem sucesso.

Estou usando o Ansible 2.4.2.0 e as tarefas são executadas para alguns hosts do Windows.

    
por pandoJohn 15.02.2018 / 15:35

2 respostas

0

No final, removi o bloco de resgate de blocos. Eu descobri uma maneira de verificar se o meu arquivo .yml existe. Isso está usando a variável role_path (que retornará o caminho da função atual - disponível desde o Ansible 1.8 - isso funciona apenas dentro de uma função) e o teste is_file .

Meu main.yml para a função descrita acima está assim:

- name: Import profiles
   include_tasks: "{{ item }}.yml"
   with_items: "{{ profiles|default([]) }}"
   when: (role_path + '/tasks/' + item + '.yml') | is_file

Devido a essa verificação, uma exceção fatal não será mais lançada - o arquivo trap1.yml será ignorado.

A saída será algo como:

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

Estou bem com esta solução, mas também estou aberto a outras sugestões.

    
por 16.02.2018 / 13:22
1

block / rescue não impede que o erro aconteça. Ele detecta uma tarefa com falha e executa o rescue block para recuperar-se do erro. Mas a tarefa que falhou ainda está lá e será visível na recapitulação do jogo.

Eu recomendaria usar a abordagem rápida de falha ao projetar livros didáticos. No seu caso, você pode varrer seus arquivos locais para testar se a entrada do usuário (configuração fornecida) é válida: se os arquivos de perfis estão no lugar. Usuário assert / fail modules.

    
por 15.02.2018 / 17:32