web-dev-qa-db-ja.com

Ansible:複合条件付きwhenステートメントを理解する

この些細なansibleプレイブックと関連する以下の出力を検討してください。タスク5が実行されるのはなぜですか?これらのタスクはdebianに対して実行されました。タスク1は期待どおりに失敗します。では、なぜ「ansible_lsb.major_release | int <14」でそれを実現するのですか?これは演算子の優先順位と関係がありますか?

-jk

---
- name: These tests run against debian
  hosts: frontend001
  vars:
    - bcbio_dir: /mnt/bcbio
    - is_ubuntu: "'{{ansible_distribution}}' == 'Ubuntu'"
    - is_debian: "'{{ansible_distribution}}' == 'Debian'"
  tasks:
    - name: 1. Expect skip because test is_ubuntu
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_ubuntu 

    - name: 2. Expect to print msg because test is_debian
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_debian

    - name: 3. Expect to print msg because release 7 of wheezy
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when:  ansible_lsb.major_release|int < 14

    - name: 4. Expect to print msg because true and true is true
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_debian and ansible_lsb.major_release|int < 14

    - name: 5. Expect to skip because false and true is false
      debug: msg="ansible distribution - {{ansible_distribution}}, release - {{ansible_distribution_release}}, {{ ansible_lsb.major_release }}"
      when: is_ubuntu and ansible_lsb.major_release|int < 14 


$ ansible-playbook -i ~/.elasticluster/storage/ansible-inventory.jkcluster  zbcbio.yml 

PLAY [These tests run against debian] ***************************************** 

GATHERING FACTS *************************************************************** 
ok: [frontend001]

TASK: [1. Expect skip because test is_ubuntu] ********************************* 
skipping: [frontend001]

TASK: [2. Expect to print msg because test is_debian] ************************* 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

TASK: [3. Expect to print msg because release 7 of wheezy] ******************** 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

TASK: [4. Expect to print msg because true and true is true] ****************** 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

TASK: [5. Expect to skip because false and true is false] ********************* 
ok: [frontend001] => {
    "msg": "ansible distribution - Debian, release - wheezy, 7"
}

PLAY RECAP ******************************************************************** 
frontend001                : ok=5    changed=0    unreachable=0    failed=0   

編集済み:誰かが自宅でフォローしている場合に備えて、以下のtedder42の回答に基づいて変更をリストします。

1)変更

- is_ubuntu: "'{{ansible_distribution}}' == 'Ubuntu'"

- is_ubuntu: "{{ansible_distribution == 'Ubuntu'}}"

2)変更

when: is_ubuntu and ansible_lsb.major_release|int < 14 

when: is_ubuntu|bool and ansible_lsb.major_release|int < 14 

やった!

-jk

14
John

TLDR:変数は評価されずに文字列として出力されます。 jinja2を使用して評価を修正し、変数を|boolとしてフィルタリングします。

デバッグ中

この問題をデバッグするために欠けているのは1つだけです。これは私が私のローカルOSXボックスで実行したものです:

- name: stackoverflow 26188055
  hosts: local
  vars:
    - bcbio_dir: /mnt/bcbio
    - is_ubuntu: "'{{ansible_distribution}}' == 'Ubuntu'"
    - is_debian: "'{{ansible_distribution}}' == 'Debian'"
  tasks:
    - debug: var=is_ubuntu
    - debug: var=is_debian
    - debug: msg="this shows the conditional passes even though it shouldnt"
      when: is_ubuntu and true

そして出力:

TASK: [debug var=is_ubuntu] *************************************************** 
ok: [127.0.0.1] => {
    "is_ubuntu": "'MacOSX' == 'Ubuntu'"
}

TASK: [debug var=is_debian] *************************************************** 
ok: [127.0.0.1] => {
    "is_debian": "'MacOSX' == 'Debian'"
}

TASK: [debug msg="this shows the conditional passes even though it shouldnt"] *** 
ok: [127.0.0.1] => {
    "msg": "this shows the conditional passes even though it shouldnt"
}

評価中

私の知る限り、真偽値で評価することはできません。通常、これは変数を展開することによって行われます(すべての「いつ」に配置します)。ただし、ブール値を文字列として取得し、それをブール値 にキャストして、変数のansibleページ (「ブール値」を検索する)に示唆されているように実現できます。

- name: stackoverflow 26188055
  hosts: local
  vars:
    - bcbio_dir: /mnt/bcbio
    - is_ubuntu: "{{ansible_distribution == 'Ubuntu'}}"
    - is_debian: "{{ansible_distribution == 'Debian'}}"
  tasks:
    - debug: var=is_ubuntu
    - debug: var=is_debian
    - debug: msg="this shows the conditional passes even though it shouldnt"
      when: is_ubuntu|bool and true

そして、これが出力です。

TASK: [debug var=is_ubuntu] *************************************************** 
ok: [127.0.0.1] => {
    "is_ubuntu": "False"
}

TASK: [debug var=is_debian] *************************************************** 
ok: [127.0.0.1] => {
    "is_debian": "False"
}

TASK: [debug msg="this shows the conditional passes even though it shouldnt"] *** 
skipping: [127.0.0.1]

バージョン比較フィルター

Ansibleのversion_compareフィルター を利用したい場合があります。使い方は読者の練習問題として残しておきます。

14
tedder42