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


はじめに

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

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

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

sample01
{{ node_count | default(5) }}
sample02
{{ node_list | unique }}
- machine specs
  • OS : MacBook
  • ansible: 2.7.10
  • cloud : conoha VPS
- Reference

勉強開始

- Forcing Variables To Be Defined(強制的に変数定義する)
- Defaulting Undefined Variables(デフォルト値を規定する)

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

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(モジュールパラメータを省略する)

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

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にまとめる(平坦にする)
    • ネストはデフォルト1階層まで。階層のlevelを指定できる
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などの論理フィルタを指す。
2つのlistを掛け合わせて新しい結果を作る(対象はリストのみ?)

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