Ansible:特定の条件が満たされた場合、varsファイルで変数を条件付きで定義します


19

group_varsに定義された変数の値(True / False)に応じて、varsファイルにいくつかの変数を定義しようとしています。それらの値は、グループ変数の値に依存します。

私の現在のvarファイルは次のようになります。

{% if my_group_var %}
test:
   var1: value
   var2: value
   ...
   varn: value
{% else %}
test:
   var1: other_value
   var2: other_value
   ...
   varn: other_value
{% endif %}

役割ごとに、このファイルに定義された変数を使用しています。

私のテストプレイブックは次のようになります。

- name: blabla
  hosts: blabla
  vars_files:
     - <path>/test_vars.yml
  roles: blabla 

プレイブックの実行後に表示されるエラーは次のとおりです。

{% if my_group_var %}
 ^ here

exception type: <class 'yaml.scanner.ScannerError'>
exception: while scanning for the next token
found character that cannot start any token
  in "<unicode string>"

私はここで愚かなことをしていますか、これはサポートされていませんか?私はこれらの変数を定義する別の方法を見つけようとしました(私はそれらをたくさん持っています)が、ここで何か機能的なものを得ることができませんでした。助言がありますか?


これらの変数はどこで使用されることになりますか?これを使用するのがtemplateモジュール呼び出しの一部である場合、これは不要な場合があります。
84104

testグループに依存する場合は、group_varsに配置する必要があります。
コンスタンチンス

残念ながら、テストはグループに依存しません。説明で述べたように、テストはgroup_var変数の値に依存します。
パンドジョン

回答:


11

私は通常、条件付き変数コレクションを保持する個別のファイルを作成whenし、特定の条件にそれらを含める句を使用します。

- include_vars: test_environment_vars.yml
  when: global_platform == "test"

- include_vars: staging_environment_vars.yml
  when: global_platform == "staging"

- include_vars: prod_environment_vars.yml
  when: 
    - global_platform != "test" 
    - global_platform != "staging" 

2
これは私が避けようとしていたことです。include varsを使用したり、タスクに2つの追加のvarファイルを定義したりしません。
パンドジョン

条件付きでinclude_varsを使用できる場合、条件付きで変数を定義できないのはなぜですか?
-GP92

10

Ansibleでは、次のいずれかの形式で条件付きで変数を定義できます。

    test:
      var1: "{% if my_group_var %}value{% else %}other_value{% endif %}"
      var2: "{{'value' if (my_group_var) else 'other_value'}}"

上記の構文とvarsルックアップを組み合わせて、複雑なvars(この場合はリスト)をロードできます。

test_value_when_my_group_var_is_true:
   var1: value
   var2: value

test_value_when_my_group_var_is_false:
   var1: other_value
   var2: other_value

test: "{{ lookup('vars','test_value_when_my_group_var_is_true') if (my_group_var) else lookup('vars','test_value_when_my_group_var_is_false')}}"

varsルックアップを使用して条件ツリーをロードする別の方法があります。この方法は、ケースロジックを実装する必要がある場合(つまり、条件変数に3つ以上の可能な値がある場合)に便利です。

test_value_when_my_group_var_is_foo:
   var1: value
   var2: value

test_value_when_my_group_var_is_bar:
   var1: other_value
   var2: other_value

test_value_when_my_group_var_is_baz:
   var1: yet_another_value
   var2: yet_another_value

test: "{{ lookup('vars','test_value_when_my_group_var_is_' + my_group_var) }}"

2

それは良いことですが、私はあなたの方法が不可能であることを恐れています(または私は正しい方法を認識していません)。

最初にjinjaテンプレートからvarsファイルを準備し、それをinclude_varsに含めることをお勧めします。サンプルプレイブックを参照してください。

---
- name: -Test-
  hosts: local
  vars:
    my_group_var: False
#    my_group_var: True

  tasks:

  - name: Prepare vars file from template.
    template: src=/tmp/vars.yaml.j2
              dest=/tmp/vars.yaml

  - name: Include vars
    include_vars: "/tmp/vars.yaml"

サンプルのjinjaテンプレート/tmp/vars.yaml.j2の内容は次のとおりです。

{% if my_group_var %}                                                                                                                                                                                             
test:                                                                                                                                                                                                             
   var1: value                                                                                                                                                                                                    
   var2: value                                                                                                                                                                                                    
{% else %}                                                                                                                                                                                                        
test:                                                                                                                                                                                                             
   var1: other_value                                                                                                                                                                                              
   var2: other_value                                                                                                                                                                                              
{% endif %}

私はこれが好きですが、問題はjinjaテンプレートから.ymlファイルを生成した後、これは私のプレイブックの後続のタスクで利用できないことです。
パンドジョン

どうして?私はデバッグタスクとテスト・脚本を拡張しようとすると- debug: var=test、私はそこの両方に定義されていることを、見ることができるtest.var1test.var2期待値と。したがって、これらの変数をプレイブックの他のタスクで使用できるはずです。
ヤロスラフクセラ

0

知る限り、あなたが試みているこの{}ことは、Jinja2テンプレート用であり、ymlファイル用ではありません。ドキュメントから:

ansibleはテンプレートでJinja2ループと条件を許可しますが、プレイブックではそれらを使用しません。

when句を使用して必要な変数を設定するplayを備えた別の.ymlファイルを準備し、メインのプレイブックにそれらをインポート(またはインクルード)できます。これにより、すべての変数を単一のファイルで条件付きで定義できます。

または:ロールを使用します。あなたの問題を解決するには、役割が最も適切なアプローチだと思います。


0

私が最後にしたことは、2つの別々のvarファイルを作成することでした-それらtype_a.ymlを呼び出しましょうtype_b.yml-そして、使用するファイルを示すグループ変数を定義しました-のようなものですtype_of_file: a。これが私のプレイブックの外観です。

- name: blabla
  hosts: blabla
  vars_files:
     - <path>/type_{{ type_of_file }}.yml
  roles: blabla

すべての答えをありがとう。私はそれらが本当に役立つと思います。


0

次の断片(Ansible Documentationから取得)が上記の他の人々からの有益な貢献に価値のある追加を加えることを願っています。

- name: Show value of 'variablename'
  debug: msg="{{ lookup('vars', 'variabl' + myvar)}}"
  vars:
    variablename: hello
    myvar: ename
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.