Ansibleの呼吸 肆ノ型 フィルター芸「0,1反転」

この投稿は[Ansible 3 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ansible3)の5日目の記事です。

今回はテキストファイルに羅列した「0」「1」の数字を反転させてみるフィルター例です。
<font color="#FC0107">ここではシーケンスをリスト、マッピングを辞書と表現します</font>

# 使用するファイル

`before_number.txt` に01をランダムに書いた物を用意しておきます。

```
[root@localhost ansible]# cat before_number.txt
001010101010101010010101
111000101010100111010011
100001010100001010101010
110101010101010010101010
101010100101010101010000
111111100000111010000000
```

このファイルを元に「0」と「1」を反転させて `after_number.txt` と言うファイルを作成します。

# Playbook

Playbookは2つ作成しました。

**main.yml**

```yaml
---
- name: shi no kata playbook
  hosts: localhost
  gather_facts: no
  vars:
    before_number: "{{ lookup('file', 'before_number.txt') }}"
  tasks:
    - name: set nested_list variable
      set_fact:
        nested_list: >-
         {{ nested_list | default([])
           + [item | list]
         }}
      loop: "{{ before_number.split('\n') }}"

    - name: include tasks from inversion.yml
      include_tasks: inversion.yml
      loop: "{{ nested_list }}"
      loop_control:
        loop_var: number

    - name: create output file
      file:
        path: after_number.txt
        state: touch

    - name: write to file
      lineinfile:
        path: after_number.txt
        line: "{{ item | join('') }}"
      loop: "{{ list2 }}"
```

**inversion.yml**

```yaml
---
- name: set init list1 variable
  set_fact:
    list1: []

- name: add data to list1
  set_fact:
    list1: "{{ list1 + [data] }}"
  vars:
    data: "{{ item | regex_replace('1', '0') if (item == '1') else ('1') }}"
  loop: "{{ number }}"

- name: add list1 to list2
  set_fact:
    list2: "{{ list2 | default([]) + [list1] }}"
```

`main.yml` の方で `before_number.txt` を読み込んで改行コードで分割しリストの中にリストを作成します。(nested_list)
loopで `nested_list` 内にあるリストの数だけ `inversion.yml` の処理を実行して `list2` を作成します。
最後に作成した `list2` をファイルに書き出します。

# Playbook実行

これを実行します。

```
[root@localhost ansible]# ansible-playbook main.yml
 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


PLAY [shi no kata playbook] *************************************************************************************************************************************************

TASK [set multiple_list variable] *******************************************************************************************************************************************
ok: [localhost] => (item=001010101010101010010101)
ok: [localhost] => (item=111000101010100111010011)
ok: [localhost] => (item=100001010100001010101010)
ok: [localhost] => (item=110101010101010010101010)
ok: [localhost] => (item=101010100101010101010000)
ok: [localhost] => (item=111111100000111010000000)
(snip)
TASK [add list1 to list2] ***************************************************************************************************************************************************
ok: [localhost]

TASK [create output file] ***************************************************************************************************************************************************
changed: [localhost]

TASK [write to file] ********************************************************************************************************************************************************
changed: [localhost] => (item=['1', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0'])
changed: [localhost] => (item=['0', '0', '0', '1', '1', '1', '0', '1', '0', '1', '0', '1', '0', '1', '1', '0', '0', '0', '1', '0', '1', '1', '0', '0'])
changed: [localhost] => (item=['0', '1', '1', '1', '1', '0', '1', '0', '1', '0', '1', '1', '1', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1'])
changed: [localhost] => (item=['0', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '0', '1'])
changed: [localhost] => (item=['0', '1', '0', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '1', '1', '1'])
changed: [localhost] => (item=['0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '0', '0', '0', '1', '0', '1', '1', '1', '1', '1', '1', '1'])

PLAY RECAP ******************************************************************************************************************************************************************
localhost                  : ok=27   changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

作成されたフィアルの中身を見てみます。

```
[root@localhost ansible]# cat after_number.txt
110101010101010101101010
000111010101011000101100
011110101011110101010101
001010101010101101010101
010101011010101010101111
000000011111000101111111
```

`before_number.txt` とは反転した数字が出来上がりました :)