Como executar uma tarefa quando a variável é indefinida no ansible?

114

Estou procurando uma maneira de realizar uma tarefa quando a variável ansible não é registradora / indefinida, por exemplo

-- name: some task
   command:  sed -n '5p' "{{app.dirs.includes}}/BUILD.info" | awk '{print  $2}'
   when: (! deployed_revision) AND ( !deployed_revision.stdout )
   register: deployed_revision
Sakhunzai
fonte

Respostas:

212

Dos documentos ansible : Se uma variável necessária não foi definida, você pode pular ou falhar usando o teste definido de Jinja2. Por exemplo:

tasks:

- shell: echo "I've got '{{ foo }}' and am not afraid to use it!"
  when: foo is defined

- fail: msg="Bailing out. this play requires 'bar'"
  when: bar is not defined

Então, no seu caso, when: deployed_revision is not defineddeve funcionar

Kyle
fonte
4
obrigado, funcionou para mimwhen: deployed_revision is not defined or deployed_revision.stdout is not defined or deployed_revision.stdout == ''
sakhunzai
5
Você também pode combiná-lo com diferentes condições:when: item.sudo is defined and item.sudo == true
czerasz
5
Não faça o que eu fiz e coloque chaves em volta do foo when: foo is defined(por exemplo, isso não funciona:when: {{ foo }} is defined
David
2
@David Eu enfrentei o mesmo problema que você. colocar chaves quando quebra a condicional. Para fazer isso funcionar, você precisa adicionar parênteses ao redor da condicional. por exemplo when: ({{ foo }} in undefined)
Tarun
7
O uso de chaves para condicionais em Ansible foi descontinuado. Além disso, nenhuma instrução Ansible pode começar com expansão de variável (como {{ foo }}). Isso não é por causa de Ansible, mas Yaml interpretaria isso como um objeto. Se você precisar começar com uma expansão de variável, simplesmente "{{ foo }}"coloque tudo entre aspas (como ), para forçar o Yaml a vê-lo como uma string e passá-lo como está para Ansible.
Victor Schröder
10

De acordo com a versão 2.5 do Ansible mais recente, para verificar se uma variável está definida e, dependendo disso, se você deseja executar qualquer tarefa, use a undefinedpalavra-chave.

tasks:
    - shell: echo "I've got '{{ foo }}' and am not afraid to use it!"
      when: foo is defined

    - fail: msg="Bailing out. this play requires 'bar'"
      when: bar is undefined

Documentação Ansible

Abhijeet Kamble
fonte
5

De forma estrita, você deve verificar todos os itens a seguir: definido, não vazio E não nenhum.

Para variáveis ​​"normais", faz diferença se definido e definido ou não definido. Veja fooe barno exemplo abaixo. Ambos são definidos, mas apenas fooestá definido.

Por outro lado, as variáveis ​​registradas são definidas como o resultado do comando em execução e variam de módulo para módulo. Eles são principalmente estruturas json. Você provavelmente deve verificar o subelemento no qual está interessado. Veja xyze xyz.msgno exemplo abaixo:

cat > test.yml <<EOF
- hosts: 127.0.0.1

  vars:
    foo: ""          # foo is defined and foo == '' and foo != None
    bar:             # bar is defined and bar != '' and bar == None

  tasks:

  - debug:
      msg : ""
    register: xyz    # xyz is defined and xyz != '' and xyz != None
                     # xyz.msg is defined and xyz.msg == '' and xyz.msg != None

  - debug:
      msg: "foo is defined and foo == '' and foo != None"
    when: foo is defined and foo == '' and foo != None

  - debug:
      msg: "bar is defined and bar != '' and bar == None"
    when: bar is defined and bar != '' and bar == None

  - debug:
      msg: "xyz is defined and xyz != '' and xyz != None"
    when: xyz is defined and xyz != '' and xyz != None
  - debug:
      msg: "{{ xyz }}"

  - debug:
      msg: "xyz.msg is defined and xyz.msg == '' and xyz.msg != None"
    when: xyz.msg is defined and xyz.msg == '' and xyz.msg != None
  - debug:
      msg: "{{ xyz.msg }}"
EOF
ansible-playbook -v test.yml
wolfrevo
fonte