2017-06-30 3 views
0

when文で複数の条件文を使用してタスクを実行する必要があるかどうかを判断する際に問題があります。基本的に私は、セキュリティパッチ、カーネルのみのパッチ、およびパッケージをvarファイルで指定するためのオプションを使って、自動化されたシステムパッチを適用するためのプレイブックを作っています。可能性:when句内の複数の条件文

私は以下のコマンドで脚本を実行し、脚本はカーネルを除いて、システム上のすべてのパッケージを更新しますが、私は希望のデフォルトでは、拡張変数オプション(-e)

ansible-playbook site.yml -i inventory --ask-vault -u (username) -e "security=true restart=true" -k -K

て変数を定義いくつかの変数のいずれかを指定するとそのアクションをスキップします。私が持っているコードは以下の通りです:アイブ氏は、以下の組み合わせの全て試してみました

- name: Update all packages 
    yum: 
    name: "*" 
    state: latest 
    exclude: "kernel*" 
    when: security is not defined or kernel is not defined or specified_packages 
is not defined and ansible_os_family == "RedHat" 

when: (ansible_os_family == "RedHat") and (security is defined or kernel is defined or specified_packages is defined)

when: (ansible_os_family == "RedHat") and (security == true or kernel == true or specified_packages == true) < - 私はすべての変数を定義しないので、この場合は定義されていないエラーがスローされます毎回私は脚本を実行

when: ansible_os_family == "RedHat" when: security is defined or kernel is defined or specified_packages is defined

注:私はこのタスクをスキップしてwhen節when: ansible_os_family == "RedHat" and skip is not definedを使用することを認識しており、「スキップ」などの余分な変数を使用していますが、ユーザーがこのデフォルトアクションをスキップするために余分な変数を使用する必要はありません。

アップグレードの前後でパッケージのリストを収集しているので、私もタグを使用していませんので、ローカルアクションコマンドと同じように実行することはできません。このため、私は、複数のタスクが拡張変数を使用してオン/オフされる1つのロールを使用しています。私はノブのように、プレイブックをより効率的な方法で書き直す提案はありません。

when: 
    - ansible_os_family == "RedHat" 
    - security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != '' 

更新:

+0

はい、あなたは '他の条件でこの方法をdefined'さ組み合わせることはできません。変数が未定義の場合は機能しません。 – techraf

+0

したがって、OSのチェックに加えて、変数のリストが定義されているかどうかに基づいてタスクを実行する方法はありませんか?これは '':ansible_os_familyとセキュリティが定義されていない ''のようなものですが、複数ではありません。 – Jay

+0

はい、正しく定義されているのは1つだけです。私が正しく覚えていれば、最後にあるはずです。問題は、変数が定義されていない場合、内部的に常にAnabilitiesが例外に直面することです。次に、 'defined'条件を探し、それがあれば、失敗するのではなく例外を処理します。しかし、複数の条件を処理することはできません。チェックの目的のためだけに 'default'フィルタか追加のファクトを含むようにコードをリファクタリングする必要があります。 – techraf

答えて

0

それは、このような単純な答えでした!

次作品:

when: not (security is defined or kernel is defined or specified_packages is defined) and ansible_os_family == "RedHat"

1

@techrafはコメントで述べたように、defined/undefinedは、このような厄介なテスト...

リファクタリングです。再現性の例:

- hosts: localhost 
    gather_facts: no 
    tasks: 
    - debug: 
     msg: hello 
     when: 
     - '"RedHat" == "RedHat"' 
     - security|d('') != '' or kernel|d('') != '' or specified_packages|d('') != '' 

実行:

ansible-playbook -e kernel=true playbook.yml 

PLAY [localhost] *************************************************************** 

TASK [debug] ******************************************************************* 
ok: [localhost] => { 
    "msg": "hello" 
} 

PLAY RECAP ********************************************************************* 
localhost     : ok=1 changed=0 unreachable=0 failed=0 

バージョン:

$ pip list | grep -iP 'ansible|jinja' 
ansible (2.2.1.0) 
Jinja2 (2.8) 
+0

残念なことに、それは1つのみで動作します。最初の変数を指定するとうまくいきますが、2番目の変数を指定すると、エラーがスローされます: ''args'フィールドに無効な値があります。 \ n \ nエラーが表示されています。 – Jay

+0

AnsibleとJinja2のどちらのバージョンを使用していますか?この式は最近のバージョンでうまくいきます:osが指定されていればタスクを実行します。 RedHatとsecurity/kernel/specified_pa​​ckagesのいずれかが設定されています –

+0

Jinjaのバージョンを確認する方法がわかりませんが、2.2.0上であっても2.3.1に更新されているだけで、うまく動作するかどうかはわかりません。最初に定義された変数の組み合わせは動作しますが、最初のスロットにない変数を定義すると、定義されていない最初の変数についてのエラーがスローされます。例えばkernel = trueならセキュリティは定義されていません – Jay