[Ansible] PlaybookのYAML構文を理解する
はじめに
Ansibleを調べ始めたけど、YAML形式がよく分からんという方向けの内容です。
具体的にはハイフンやインデントが何を意味するか見ていきます。
私自身Pythonにあまり詳しくないこともあり、正しくない表現があるかもしれません。
あくまでもイメージを掴むためのものとしてご覧ください。
使われるデータ型(変数の形式)
まずはAnsibleで使用されるデータ型とその表現方法をざっくり整理します。
AnsibleはPythonで実装されているため詳細はPythonのデータ型を調べてみてください。
各データ型のYAMLでの表現
いきなりですが、各データ型をYAMLで表現します。 コメントと併せてご覧ください。
var6についてはイメージ図と併せて見れば分かりやすいかと思います。
var1: 1 # int型:単一要素(整数)を格納 var2: "2" # string型:単一要素(文字列)を格納 var3: true # boolean型:単一要素(真偽値)を格納 var4: # list型:複数要素を格納。各要素にはindexが割り当たる - "apple" - "fruit" - 100 var5: # dictionary型:複数要素を格納。key: valueのセットとなる name: "apple" type: "fruit" cost: 100 var6: # list型の中にdictionary型を階層的に定義したパターン - name: "apple" type: "fruit" cost: 100 - name: "melon" type: "fruit" cost: 500
イメージ図
ポイント
下記のあたりを抑えておく。
個人的には最後の点に混乱させられました。
- list型は各要素を1行ずつハイフンで定義する(全要素を1行で表現する形式も有る)
- dictionary型は1行ずつkey: valueで定義する(全要素を1行で表現する形式も有る)
- list型は定義順に各要素へ0始まりの番号(index)が割り当たる
- dictionary型には各要素の順番の概念がない
- ある変数の配下であることはインデントで表現する
- ただし例のとおりlistの各要素はインデントを下げなくても問題ない
Playbookの読み解き
以上の内容を踏まえ、ここからはPlaybookのサンプルを読み解いてみます。
実施したい作業
用意したplaybook
上図の作業をPlaybookで表現するとこうなります。
モジュールの内容等は主題から外れるのであまり気にせず、全体の形を見てください。
--- - hosts: rt1 gather_facts: false tasks: - name: execute vyos_command: commands: show version retries: 1 register: response - name: print debug: msg: "{{ response }}" - hosts: rt2 gather_facts: false tasks: - name: execute vyos_command: commands: "{{ cmd_list }}" vars: cmd_list: - show version - show interface
Playbookをイメージ図にしてみる
どうしてこんな構成になったのか、今一つピンと来ないかもしれません。
そこでイメージ図を起こしてみました。長くなってしまいましたが、大きな単位からPlaybookと1つ1つ紐づけて眺めてみてください。
全体として最初に図示した作業内容と似た形になっていることが分かります。
ここで気になること
ひとまず以上のように表現できましたが、さて、このうち Playbookとしては
どこをどういじると影響が有る、または無いのでしょうか。
データ型の一覧で抑えたうちの下記内容が重要になります。
- list型は定義順に各要素へ0始まりの番号(インデックス)が割り当たる
- dictionary型には各要素の順番の概念がない
- ある変数の配下であることはインデントで表現する
これらを踏まえ幾つか確認してみましょう。
やると影響が有ること
Playbookをいじってみます。見やすくするためrt2は省略です。
list型の要素の順番を入れ替える
- hosts: rt1 gather_facts: false tasks: - name: print debug: msg: "{{ response }}" - name: execute vyos_command: commands: show version retries: 1 register: response
tasksのリストの順番を入れ替えました。
影響として、結果出力とコマンド実行の動作順序が逆転してしまいます。
これはその時点で存在しない変数 response を参照するためエラーになります。
TASK [print] ********************************************************************************************************************* fatal: [rt1]: FAILED! => msg: |- The task includes an option with an undefined variable. The error was: 'response' is undefined The error appears to be in '/home/ansible/test/test.yml': line 5, column 7, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: tasks: - name: print ^ here
階層をずらす
- hosts: rt1 gather_facts: false tasks: - name: execute vyos_command: commands: show version retries: 1 register: response - name: print debug: msg: "{{ response }}"
debug: のインデントを上げました。
影響として、debugがlistから飛び出ています。
これは不正な構文のためエラーとなります。
ERROR! 'debug' is not a valid attribute for a Play The error appears to be in '/home/ansible/test/test.yml': line 2, column 3, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: --- - hosts: rt1 ^ here
やっても影響が無いこと
今度は動作に影響が無いパターンです。こちらもrt2は省略しています。
list型以外の要素の並び順を入れ替える
- gather_facts: false tasks: - name: execute register: response vyos_command: retries: 1 commands: show version - debug: msg: "{{ response }}" name: print hosts: rt1
大分ぐちゃぐちゃにしましたが、Playbookの動作には意外と影響ありません。
※ 実行結果は参考として本記事の最後へ掲載
それぞれの階層にある要素や、listの各Index配下の順序に変動が無いためです。
とはいえ非常に読み難いためこのような書き方は全く推奨されません。
所感
自分が最初に戸惑った内容を纏めてみました。
上手く伝わって、Ansible理解の足掛かりになれば幸いです。
参考:正常動作時の出力
Playbook
--- - gather_facts: false tasks: - name: execute register: response vyos_command: retries: 1 commands: show version - debug: msg: "{{ response }}" name: print hosts: rt1 - hosts: rt2 gather_facts: false tasks: - name: execute vyos_command: commands: "{{ cmd_list }}" vars: cmd_list: - show version - show interface
実行結果
# ansible-playbook -i inventory.ini test.yml PLAY [rt1] *********************************************************************************************************************** TASK [execute] ******************************************************************************************************************* ok: [rt1] TASK [print] ********************************************************************************************************************* ok: [rt1] => msg: changed: false failed: false stdout: - |- Version: VyOS 1.4-rolling-202112280317 Release train: sagitta Built by: autobuild@vyos.net Built on: Tue 28 Dec 2021 03:17 UTC Build UUID: 00fbb68a-9364-48c0-9039-d2a0ec19e39f Build commit ID: 4ccdaf58fc7b9b Architecture: x86_64 Boot via: installed image System type: KVM guest Hardware vendor: innotek GmbH Hardware model: VirtualBox Hardware S/N: 0 Hardware UUID: 8bd5d9c0-edf3-654f-8d43-b41f82681b81 Copyright: VyOS maintainers and contributors stdout_lines: - - 'Version: VyOS 1.4-rolling-202112280317' - 'Release train: sagitta' - '' - 'Built by: autobuild@vyos.net' - 'Built on: Tue 28 Dec 2021 03:17 UTC' - 'Build UUID: 00fbb68a-9364-48c0-9039-d2a0ec19e39f' - 'Build commit ID: 4ccdaf58fc7b9b' - '' - 'Architecture: x86_64' - 'Boot via: installed image' - 'System type: KVM guest' - '' - 'Hardware vendor: innotek GmbH' - 'Hardware model: VirtualBox' - 'Hardware S/N: 0' - 'Hardware UUID: 8bd5d9c0-edf3-654f-8d43-b41f82681b81' - '' - 'Copyright: VyOS maintainers and contributors' PLAY [rt2] *********************************************************************************************************************** TASK [execute] ******************************************************************************************************************* ok: [rt2] PLAY RECAP *********************************************************************************************************************** rt1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 rt2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 #