Jak uruchomić zadanie, gdy zmienna jest niezdefiniowana w ansiblu?

115

Szukam sposobu na wykonanie zadania gdy zmienna ansibla nie jest rejestrami / niezdefiniowana np

-- 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
źródło

Odpowiedzi:

214

Z dokumentów ansible : Jeśli wymagana zmienna nie została ustawiona, możesz pominąć lub zakończyć się niepowodzeniem, używając testu zdefiniowanego przez Jinja2. Na przykład:

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

Więc w twoim przypadku when: deployed_revision is not definedpowinno działać

Kyle
źródło
4
dzięki, że zadziałało dla mniewhen: deployed_revision is not defined or deployed_revision.stdout is not defined or deployed_revision.stdout == ''
sakhunzai
5
Można to również połączyć z różnymi warunkami:when: item.sudo is defined and item.sudo == true
czerasz
5
Nie rób tego, co zrobiłem i umieść nawiasy klamrowe wokół foo w when: foo is defined(np. To nie działa:when: {{ foo }} is defined
David
2
@David Spotkałem się z tym samym problemem co Ty. umieszczanie nawiasów klamrowych, gdy łamie warunek. Aby to zadziałało, musisz dodać nawias wokół warunku. np. when: ({{ foo }} in undefined)
Tarun
7
Użycie nawiasów klamrowych dla warunkowych w Ansible jest przestarzałe. Ponadto żadna instrukcja Ansible nie może zaczynać się od interpretacji zmiennych (np {{ foo }}.). Nie dzieje się tak z powodu Ansible, ale Yaml zinterpretowałby to jako przedmiot. Jeśli chcesz zacząć od rozwinięcia zmiennej, po prostu "{{ foo }}"otocz całość podwójnymi cudzysłowami (jak ), aby zmusić Yamla do postrzegania go jako ciągu i przekazania go w takim stanie, w jakim jest do Ansible.
Victor Schröder
12

Zgodnie z najnowszą wersją Ansible 2.5, aby sprawdzić, czy zmienna jest zdefiniowana iw zależności od tego, czy chcesz uruchomić jakieś zadanie, użyj undefinedsłowa kluczowego.

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

Dokumentacja Ansible

Abhijeet Kamble
źródło
5

Ściśle mówiąc, musisz zaznaczyć wszystkie następujące elementy: zdefiniowane, nie puste ORAZ nie Brak.

W przypadku „normalnych” zmiennych ma znaczenie, czy są zdefiniowane i ustawione, czy nie. Zobacz fooiw barponiższym przykładzie. Obie są zdefiniowane, ale tylko fooustawione.

Z drugiej strony zarejestrowane zmienne są ustawiane na wynik uruchomionego polecenia i różnią się w zależności od modułu. W większości są to struktury json. Prawdopodobnie musisz sprawdzić podelement, który Cię interesuje. Zobacz xyziw xyz.msgponiższym przykładzie:

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
źródło