WIP:ansible filter(フィルタ)勉強

## はじめに
ansibleコードを見ていくと以下の様な記述が度々見受けられる。
最初はこれを単に「ぁぁ。デフォルト値の設定なんだな。」と思ったが、<font color="red">他にもなんか色々有る。</font>
共通的に言えるのは<font color="red">「変数に対して何かしている」</font>ということである。

調べたところ、変数等にパイプで繋げて値を整形するものは「filter」と呼ばれている。
はansibleの基本的な機能らしい。

これらansibleのfilterについて何が出来るのか調べてみよう！

```yml:sample01
{{ node_count | default(5) }}
```

```yaml:sample02
{{ node_list | unique }}
```

##### - machine specs
- OS : MacBook
- ansible: 2.7.10
- cloud : conoha VPS

##### - Reference
- [Filters](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html)

## 勉強開始

##### - Forcing Variables To Be Defined(強制的に変数定義する)

##### - Defaulting Undefined Variables(デフォルト値を規定する)
機能は「値が存在しない場合は規定した値を設定する」である。
default filterに「規定値」を予め設定しておき、変数に値がない場合は参照する。
各々以下のように表示される
- sample01: "I'm here"
- sample02: "Not Found"
- sample03: "I'm other"

```yml:tasks/ansible_filter/defaulting_undefined_variables.yml
---
- hosts: all
  tasks:
  - name: Sample01 Defaulting Undefined Variables(value is in variable)
    become: yes
    vars:
      some_variable: "I'm here"
    debug:
      msg: "{{ some_variable | default('Not Found') }}"

  - name: Sample02 Defaulting Undefined Variables(value is not in variable)
    become: yes
    debug:
      msg: "{{ some_variable | default('Not Found') }}"

  - name: Sample03 Defaulting Undefined Variables(value is not in variable type:refer variable)
    become: yes
    vars:
      other_variable: "I'm other."
    debug:
      msg: "{{ some_variable | default(other_variable) }}"
```

##### - Omitting Parameters(モジュールパラメータを省略する)
<font color="red"> モジュールパラメータを省略することが出来る。</font>
例としては以下の様に特定のループでモジュールを実行する際に全てのリストに対して
複数のパラメータを付与せず、省略（ommit)が行える。
<font color="red"> 本例では「/tmp/bar」ファイルを生成する際のみ「mode」を省略している。</font>

```yml:tasks/ansible_filter/omitting_parameters.yml
---
- hosts: all
  tasks:
  - name: Sample01 Omitting Parameters
    become: yes
    file:
      dest={{ item.path }}
      state=touch
      mode={{ item.mode | default(omit) }}
    loop:
    - path: /tmp/foo
      mode: "777"
    - path: /tmp/bar
    - path: /tmp/baz
      mode: "0644"
```

##### - List Filters(リストフィルタ)
listのfilterは以下の種類が存在する。

- min(Sample01) : 対象のlistから最小値を抽出する
- max(Sample02) : 対象のlistから最大値を抽出する(文字列が含まれると文字列が最大値に入った）
- flatten(sample03/04) : 入れ子listを1つのlistにまとめる（平坦にする)
    - ネストはデフォルト１階層まで。階層のlevelを指定できる

```yml:tasks/ansible_filter/list_filters.yml
---
- hosts: all
  vars:
    number_list: [-1, 1, 2, 10]
    number_list_nest:  [3, [4, 2] ]
    number_list_nest_deep:  [3, [4, 2,[5,6]] ]

  tasks:
  - name: Sample01 List Filters (minimum value from list of numbers)
    become: yes
    debug:
      msg: "minimum number : {{ number_list | min }}"

  - name: Sample02 List Filters (max value from list of numbers)
    become: yes
    debug:
      msg: "minimum number : {{ number_list | max }}"

  - name: Sample03 List Filters (Flatten a list)
    become: yes
    debug:
      msg: "{{ number_list_nest | flatten }}"

  - name: Sample04 List Filters (Flatten a deep list)
    become: yes
    debug:
      msg: "{{ number_list_nest_deep | flatten(levels=2) }}"
```

##### - Set Theory Filters(論理フィルタ)
主に OR,ANDなどの論理フィルタを指す。
２つのlistを掛け合わせて新しい結果を作る(対象はリストのみ?)

- unique(Sample01) : 対象のlistから最小値を抽出する
- union(Sample02) : 対象同士のOR(論理和）を抽出する
    - <font color="red">listを結合するわけではなく、論理和結果を出すところが注意点</font>
- intersect(Sample03) : 対象同士のAND(論理積)の結果を抽出する
- difference(Sample04) : 指定したリストに対してfilterで対象にしたリストと異なる値のみを抽出する。ブラックリストみたいな使い方が出来る。(対象の指定方法に注意)
    - Sample04-01 : "NEC"
    - Sample04-02 : "ADR", "CCA"
- difference(Sample05) : 指定したリスト同士の異なる値のみを抽出する。

```yml:tasks/ansible_filter/set_theory_filters.yml
---
- hosts: all
  vars:
    number_list1: [-1, 1, 2, 10, 100, 1000, 1, -1]
    number_list2: [1000, 1001, 500, 250]
    string_list1: ["NEC", "LED", "OCR"]
    string_list2: ["LED", "ADR", "CCA", "OCR"]

  tasks:
  - name: Sample01 Set Theory Filters (by unique)
    become: yes
    debug:
      msg: "uniq number : {{ number_list1 | unique }}"

  - name: Sample02 Set Theory Filters (by union)
    become: yes
    debug:
      msg: "union number : {{ number_list1 | union(number_list2) }}"

  - name: Sample03 Set Theory Filters (by intersect)
    become: yes
    debug:
      msg: "intersect string : {{ string_list1 | intersect(string_list2) }}"

  - name: Sample04-01 Set Theory Filters (by difference)
    become: yes
    debug:
      msg: "difference string : {{ string_list1 | difference(string_list2) }}"

  - name: Sample04-02 Set Theory Filters (by difference)
    become: yes
    debug:
      msg: "difference string : {{ string_list2 | difference(string_list1) }}"

  - name: Sample05 Set Theory Filters (by symmetric_difference)
    become: yes
    debug:
      msg: "symmetric_difference string : {{ string_list1 | symmetric_difference(string_list2) }}"
```