¿Cómo ejecutar una tarea cuando la variable no está definida en ansible?

115

Estoy buscando una forma de realizar una tarea cuando la variable ansible no está registrada / indefinida, por ejemplo

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

Respuestas:

213

De los documentos ansible : si no se ha establecido una variable requerida, puede omitir o fallar usando la prueba definida de Jinja2. Por ejemplo:

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

Entonces, en tu caso, when: deployed_revision is not defineddebería funcionar

Kyle
fuente
4
gracias, esto funcionó para míwhen: deployed_revision is not defined or deployed_revision.stdout is not defined or deployed_revision.stdout == ''
sakhunzai
5
También puede combinarlo con diferentes condiciones:when: item.sudo is defined and item.sudo == true
czerasz
5
No hagas lo que hice y pongas corchetes alrededor del foo when: foo is defined(por ejemplo, esto no funciona:when: {{ foo }} is defined
David
2
@David Me enfrenté al mismo problema que tú. poner llaves cuando rompe el condicional. Para que esto funcione, debe agregar paréntesis alrededor del condicional. Por ejemplo when: ({{ foo }} in undefined)
Tarun
7
El uso de llaves para condicionales en Ansible está en desuso. Además, ninguna declaración de Ansible puede comenzar con expansión variable (como {{ foo }}). Esto no se debe a Ansible, pero Yaml lo interpretaría como un objeto. Si necesita comenzar con una expansión de variable, simplemente rodee todo con comillas dobles (como "{{ foo }}"), para obligar a Yaml a verlo como una cadena y pasarlo como está a Ansible.
Victor Schröder
11

Según la última versión 2.5 de Ansible, para verificar si una variable está definida y, dependiendo de esto, si desea ejecutar alguna tarea, use la undefinedpalabra clave.

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

Documentación Ansible

Abhijeet Kamble
fuente
5

Estrictamente establecido, debe marcar todo lo siguiente: definido, no vacío Y no Ninguno.

Para las variables "normales", hay una diferencia si se definen y configuran o no. Vea fooy baren el ejemplo siguiente. Ambos están definidos pero solo fooestán configurados.

Por otro lado, las variables registradas se establecen en el resultado del comando en ejecución y varían de un módulo a otro. En su mayoría son estructuras json. Probablemente deba marcar el subelemento que le interesa. Consulte xyzy xyz.msgen el siguiente ejemplo:

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
fuente