はじめに
2021/02/06 に、YouTube Live で「つまずき Ansible 【Part29】フィルター」という配信をしました。
実際に作業しながら(ときには)エラーと戦って進めるシリーズです。
今回は、値を変換したり抽出したりするフィルターをいくつか試しました。
参考 https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
- 環境
- Ansible 2.9.16
動画
- 0:00 イントロダクション
- 4:11 抽出系
gt
のとこを「以上」と説明してしまいましたが、正しくは「より大きい」です。失礼しました。
- 13:11 変換系
- 13:53 結合系
- 15:05 正規表現系
- 16:29 パス操作系
- 17:57 ネットワーク系
- 22:22 その他
- 23:30 試行錯誤1 ansible-console
- 25:32 試行錯誤2 debugger
- 29:37 おわりに
■ やったこと
抽出系
条件にあったものを抽出。
--- - hosts: localhost gather_facts: no connection: local debugger: always vars: users: - name: yamada age: 42 - name: tanaka age: 26 - name: suzuki age: 32 - name: sato age: 27 tasks: - name: debug 1 debug: # select * from users where age > 30 のようなイメージ msg: "{{ users | selectattr('age', 'gt', 30) | list }}" # gt は > でも可
実行結果
ok: [localhost] => { "msg": [ { "age": 42, "name": "yamada" }, { "age": 32, "name": "suzuki" } ] }
様々な機能がある。今回は SQL でいうカラムの選択。
- name: debug 2 debug: # select name from users where age >= 30 のようなイメージ msg: "{{ users | selectattr('age', 'gt', 30) | map(attribute='name') | list }}"
実行結果
ok: [localhost] => { "msg": [ "yamada", "suzuki" ] }
以下は説明のみ
json_query
: jmethpath を利用した複雑なクエリー
変換系
説明のみ
結合系
説明のみ
combine
: 変数のマージ
正規表現系
正規表現を使用した置換。後方参照利用できる。
- name: regex debug: msg: "{{ 'foobar' | regex_replace('^f.*o(.*)$', '\\1') }}"
実行結果
ok: [localhost] => { "msg": "bar" }
パス操作系
説明のみ
ネットワーク系
TextFSM テンプレートを利用して、ネットワーク機器の show コマンドの実行結果を構造化データにパースする。
--- - hosts: ios gather_facts: false tasks: - name: show ios_command: commands: - show interfaces register: res - name: debug debug: msg: "{{ res.stdout[0] | parse_cli_textfsm(path_template) }}" vars: path_template: "/home/admin/envs/a29/lib/python3.6/site-packages/ntc_templates/templates/cisco_ios_show_interfaces.textfsm"
実行結果
ok: [ios01] => { "msg": [ { "ABORT": "", "ADDRESS": "5254.00xx.xxxx", "BANDWIDTH": "1000000 Kbit", "BIA": "5254.00xx.xxxx", "CRC": "0", "DELAY": "10 usec", "DESCRIPTION": "", "DUPLEX": "Auto Duplex", "ENCAPSULATION": "ARPA", "HARDWARE_TYPE": "iGbE", "INPUT_ERRORS": "0", "INPUT_PACKETS": "854394", "INPUT_RATE": "0", "INTERFACE": "GigabitEthernet0/0", "IP_ADDRESS": "192.168.1.11/24", "LAST_INPUT": "00:00:00", "LAST_OUTPUT": "00:00:00", "LAST_OUTPUT_HANG": "never", "LINK_STATUS": "up", "MEDIA_TYPE": "RJ45", "MTU": "1500", "OUTPUT_ERRORS": "0", "OUTPUT_PACKETS": "127122", "OUTPUT_RATE": "0", "PROTOCOL_STATUS": "up", "QUEUE_STRATEGY": "fifo", "SPEED": "Auto Speed" }, // ....(略)...
参考: show コマンド結果をパースする方法あれこれ(TextFSM / Genie Parser と Netmiko / Ansible の組み合わせ) - てくなべ (tekunabe)
その他
説明のみ
試行錯誤に便利
フィルターを色々試したい時に便利な方法。
ansible-console
対話的な操作。
(a29) [admin@gitlab stumble]$ ansible-console -i localhost, Welcome to the ansible console. Type help or ? to list commands. admin@all (1)[f:5]$ debug msg="{{ [1,2,3] | max }} " localhost | SUCCESS => { "msg": "3 " } admin@all (1)[f:5]$ debug msg="{{ [1,2,3] | min }} " localhost | SUCCESS => { "msg": "1 " }
参考: [Ansible] フィルターを手軽に試行錯誤したいときの ansible-console コマンドの使い方 - てくなべ (tekunabe)
Playbook Debugger
たとえば、Play に debugger: always
を指定すると、各タスク実行後にデバッガーが起動する。
--- - hosts: localhost gather_facts: no connection: local debugger: always # ここ
以下が、デバッガーが起動した状態。
[localhost] TASK: debug 1 (debug)>
task.args
で、タスクのオプションの書き換えができる。そのが r
で再実行できる。
[localhost] TASK: debug 1 (debug)> task.args['msg'] = "{{ users | selectattr('age', 'gt', 40) | list }}" [localhost] TASK: debug 1 (debug)> r ok: [localhost] => { "msg": [ { "age": 42, "name": "yamada" } ] }
おわりに
フィルターは数も多く、奥が深いです。
全ては覚えられないので、フィルター的なことをしたい場合は、Ansible や Jinja2 の公式ドキュメントを眺めて探しています。
Filters — Ansible Documentation
Jinja — Jinja Documentation (2.11.x)
Part30にむけて
ベータですが、Ansible 3.0.0b1 がリリースされたので、こちらを扱ってみます。
他、以下のネタを検討中です。気が向いたものをやります。 connpass申込時のアンケートでいただいたものも含めています。
- Katakoda Ansible 101
- connection: local ななにか
- Windows
- cli_parse モジュール(Part15 の続き)
- Ansible 2.10 関連
- Ansible 3.0.0 関連
- モジュールのテスト
- AWXとの共存を念頭に入れたDirectory構成