Variável Ansible é indefinida, a menos que seja definida como padrão

2

Estou tentando adicionar uma nova variável a um repositório git existente, repleto de arquivos Ansible, que fazem uso pesado de funções. Então, onde quer que foo seja referenciado, abaixo

vars_files:
   - vars/aws.yml
   - vars/aws-credentials.yml

Eu adicionei a nova linha

   - vars/rpm-repo.yml

e criei vars/rpm-repo.yml com o conteúdo:

---
yum_rpm_dir: https://example.com/repo/noarch

que é válido YAML de acordo com o comando dado em esta resposta para verificar se um arquivo é válido YAML.

E em roles/foo/tasks/main.yml alterei uma tarefa yum para instalar isto:

name: "{{ yum_rpm_dir }}/rest-api-{{ rest_api_version }}-1.noarch.rpm"

(o objetivo desta URL explícita é remediar um erro em nosso repositório RPM).

Mas eu recebo:

fatal: [1.2.3.4]: FAILED! => {"failed": true, "msg": "'yum_rpm_dir' is undefined"}

Então eu pensei, claramente eu não entendi as complexidades de como as variáveis interagem com os papéis no Ansible, então eu adicionarei isso como um padrão e isso definitivamente funcionará.

Então eu copiei o arquivo acima para roles/foo/defaults/main.yml também.

Isso funciona, mas é um hack. O ponto principal de tornar isso uma variável era que seu valor poderia ser usado por várias funções sem ser copiado e colado.

tl; dr: Como eu configuro uma variável no Ansible corretamente para que ela possa ser escolhida por uma função?

    
por Robin Green 26.10.2016 / 22:14

2 respostas

0

O problema era simplesmente que eu havia perdido um arquivo em que a função foo estava sendo usada.

A referência a foo não se parece com isso:

 roles:
    - foo

mas assim:

 roles:
     - { role: foo, rest_api_version: "{{ blah_version }}" }

então eu tinha esquecido isso. Uma vez que eu adicionei a mesma referência ao arquivo vars antes da "chamada" para o papel foo, ele funcionou sem o arquivo defaults.

    
por 26.10.2016 / 23:16
2

Você não especifica qual versão de ansible é a que você está usando, e há mudanças importantes de 1.x para 2.x.

Da documentação on-line , a resposta para

How do I set a variable in Ansible properly so that it can be picked up by a role?

seria:

Em 1.x, a precedência é a seguinte (com as últimas variáveis listadas ganhando a priorização):

  • "padrões de função", que perdem prioridade para tudo e são mais facilmente substituídos
  • variáveis definidas no inventário
  • fatos descobertos sobre um sistema
  • “quase todo o resto” (opções de linha de comando, vars in play, vars incluídos, vars de função, etc.)
  • variáveis de conexão (ansible_user, etc.)
  • extra vars (-e na linha de comando) sempre ganha

Em 2.x, a ordem de precedência é mais específica (com as últimas variáveis listadas ganhando a priorização):

  • padrões de função (as tarefas em cada função verão os padrões de suas próprias funções. As tarefas definidas fora de uma função verão os padrões da última função)
  • inventário vars (Variáveis definidas no arquivo de inventário ou fornecidas pelo inventário dinâmico)
  • inventário group_vars
  • inventário host_vars
  • playbook group_vars
  • playbook host_vars
  • fatos do host
  • jogar vars
  • reproduzir vars_prompt
  • reproduza vars_files
  • registrou vars
  • set_facts
  • role e inclua vars
  • block vars (somente para tarefas no bloco)
  • vars da tarefa (somente para a tarefa)
  • extra vars (sempre ganha precedência)

A resposta ao seu caso de uso específico requer que você forneça o local dos arquivos var (como não pode ser inferido a partir dos dados fornecidos) na estrutura do diretório. Dependendo de onde esses arquivos foram colocados, eles têm uma precedência diferente.

Pessoalmente, prefiro agrupar dados em group_vars (consulte o documento melhores práticas para o layout preferido), para que eu possa atribuir dados a grupos de hosts, principalmente porque isso geralmente é mapeado diretamente para funções.

    
por 26.10.2016 / 23:08

Tags