この投稿は Ansible 3 Advent Calendar 2019 の七日目の記事です。
ここでは @sky_jokerxx さんの五日目の記事 Ansibleの呼吸 肆ノ型 フィルター芸「0,1反転」 の別解を Jinja2 の macro を使って実装してみます。(なおまた別の @akira6592 さんの別解はこちらに: [Ansible] 【別解】 Ansibleの呼吸 肆ノ型 フィルター芸「0,1反転」)
御二方の記事とまったく同じように入力ファイルを用意します。 内容は同じなので手順は割愛します。
---
- hosts: localhost
connection: local
gather_facts: false
vars:
input: >-
{{ lookup('file', 'before_number.txt') }}
tasks:
- name: Compute the result
set_fact:
_result: >-
{% macro inv(s) -%}
{% for c in s | list -%}
{% if c == '0' %}1{%
elif c == '1' %}0{%
else -%}
{{ c -}}
{% endif -%}
{% endfor -%}
{% endmacro -%}
{{ inv(input) }}
- name: Output the computed result
copy:
content: |
{{ _result }}
dest: after_number.txt
force: false
# vim:sw=2:ts=2:et:
- 他記事と同様に変数 input に入力ファイルの内容を読み込んだ文字列を代入
- 文字列を受け取って一文字毎に処理 (if .. endif 部分) して '0' は '1' に '1' は '0' に変換、他はそのままにするような Jinja2 Macro inv を定義
- Jinja2 Macro inv に変数 input (文字列) を処理させ、結果 (文字列)を得て変数 _result に代入
- 変数 _result の内容を出力ファイルに出力
set_fact で変数 _result の内容として Jinja2 Macor 定義 ( {% macro ~ {% endmacro -%}) と Macro の呼び出し ( inv(input) 行) を続けて書くのがポイントです。
また Macro 定義部分では、結果の文字列に余計な改行が含まれてしまわないよう '-' を利用 ('-}}' や '-%}') したり、節の途中で意図的に改行したりしています (参考: Jinja2 Template Designer Documentation: Whitespace Control)。
$ cat inv.yml
---
- hosts: localhost
connection: local
gather_facts: false
vars:
input: >-
{{ lookup('file', 'before_number.txt') }}
tasks:
- name: Compute the result
set_fact:
_result: >-
{% macro inv(s) -%}
{% for c in s | list -%}
{% if c == '0' %}1{%
elif c == '1' %}0{%
else -%}
{{ c -}}
{% endif -%}
{% endfor -%}
{% endmacro -%}
{{ inv(input) }}
- name: Output the computed result
copy:
content: |
{{ _result }}
dest: after_number.txt
force: false
# vim:sw=2:ts=2:et:
$ ansible-playbook inv.yml
PLAY [localhost] ***************************************************************************************************
TASK [Compute the result] ******************************************************************************************
ok: [localhost]
TASK [Output the computed result] **********************************************************************************
changed: [localhost]
PLAY RECAP *********************************************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ cat after_number.txt
110101010101010101101010
000111010101011000101100
011110101011110101010101
001010101010101101010101
010101011010101010101111
000000011111000101111111
$
Jinj2 Macro の利用はしばしば Ansible Playbook の難読化の向上に大きく貢献しますが場合によっては非常に強力かもしれません。