そうしたい時もあると思います。
過去、ループで回した値を定義した配列に順次入れ込んでいきたい場合はこんな感じにしていた。
- name: Define empty array ansible.builtin.set_fact: array: [] - name: Set array ansible.builtin.set_fact: array: "{{ array + [item] }}" loop: - "a" - "b"
最初のタスク Define empty array
で空配列 array
を定義して、次のタスクで実際の値を入れていく形。
これで Set array
後、 array
の中身は ["a", "b"]
となる。
まぁこの書き方でも別に良いのだけど、なんだか冗長だなーと。
できれば空配列の定義と、それに値を入れ込む処理は1タスクでいい感じに処理したい。
で、調べたり検証したところ、以下のように書けば一つの処理で完結できることがわかった。
- name: Define array and Set ansible.builtin.set_fact: array: "{{ array | default([]) + [item] }}" loop: - "a" - "b"
default
フィルターを使うことで、 array
が定義されていない場合に空配列 []
が設定される。
この default
フィルターは、変数が定義されていない場合にのみ適用されるため、初回以外は無視されるのだ。
その後にループで回した値が入れられていくので、結果は上のタスクと同じとなる。
これをどう使うかというと register
で取得したタスクの結果とか、自分で定義した vars
の配列をループさせて必要な情報だけ取り出したい時とか、そういう時に使ったりする。
変数定義に1タスク使うのもなんだかなではあるのでこういう形で短縮できると見通しも良くなっていいんじゃないだろうか。
まあ場合によるとは思うけど…。
例えばこのタスクにwhen句があって、場合によって処理されない時があるのに、後続処理では定義したarrayを絶対使う…とかだと、空配列の定義と値の入れ込み処理は分けた方が良さそう。
まあやっぱり処理の方法による…か…。
この書き方は元々確かStack OverFlowに記載されていたのだけど、そのURLは失念…。
どう調べたら出てくるかなあ…。