やりたいこと
Ansibleでgroup_varsなどで定義した変数についてタスクを作るときにフィルターを使おうとすると、テスト時に構文エラーがでたり、思うような結果にならなかったりして、タスクの修正→テストを繰り返すのが面倒くさいことがよくある。
なので、タスクを書く前に簡単にコマンドラインから変数・フィルターの書き方をテストして問題ないことを確認してからタスクを書きたい。
やり方
ansibleコマンドで-mオプションでdebugモジュールを指定し、-aオプションで"msg={{ 変数・フィルタ記述 }}"として1行コマンドで変数・フィルター結果を確認する。
実行環境
- Red Hat Enterprise Linux 8.3
- ansible 2.9.17
- python 3.6.8
hosts, 変数定義サンプル
all:
hosts:
APSV01:
APSV11:
APSV12:
DBSV01:
DBSV02:
host_dict:
APSV01:
type: ap
runtime_env: java
version: 1.8.0_172
APSV11:
type: ap
runtime_env: java
version: 1.8.0_202
APSV12:
type: ap
runtime_env: java
version: 1.8.0_202
DBSV01:
type: db
db_engine: PostgreSQL
version: "11.9"
DBSV02:
type: db
db_engine: MySQL
version: "5.7"
サーバが複数ある1つのシステム環境で、サーバ毎に違うパラメータを与えてタスクを実行するための変数定義というイメージ。
host_varsで定義するという手もあるが、一覧しにくかったり自サーバ以外の情報を変数からとってきたいときに不便だったりするので、group_varsにまとめて定義して運用しているような想定で。
実業務ではもっとぶわーっと書いているんだけど、サンプルということで。
フィルターテスト例
ansibleコマンドで実行ホストを指定し、-mオプションでdebugモジュールを呼び出し、-aでdebugモジュールのmsgパラメータにテストしたい変数・フィルター等を指定する。
まずは単純な例で
ansible APSV01 -m debug -a "msg={{ host_dict[inventory_hostname] }}"
APSV01 | SUCCESS => {
"msg": {
"runtime_env": "java",
"type": "ap",
"version": "1.8.0_172"
}
}
次は、何か特定条件にマッチするリストを取り扱いたい場合。
# dictionaryにdict2itemsフィルターをかけると、第一階層を"key"と"value"に分解したようなdictionaryのリストになる。
ansible localhost -m debug -a "msg={{ host_dict | dict2items |selectattr('value.type', '==', 'db') | list }}"
localhost | SUCCESS => {
"msg": [
{
"key": "DBSV01",
"value": {
"db_engine": "PostgreSQL",
"type": "db",
"version": "11.9"
}
},
{
"key": "DBSV02",
"value": {
"db_engine": "MySQL",
"type": "db",
"version": "5.7"
}
}
]
}
dictionary全体から、情報を検索・集約するような例
# dictionaryをループ処理するためにdict2itemsフィルターをかける
# runtime_envで検索するので、存在確認をしてからruntime_env == 'java'のものを抽出する
# mapでバージョン情報のリストを作り、uniqueで重複排除する
ansible localhost -m debug -a "msg={{ host_dict | dict2items |
selectattr('value.runtime_env', 'defined') | selectattr('value.runtime_env', '==', 'java') |
map(attribute='value.version')| unique | list }}"
localhost | SUCCESS => {
"msg": [
"1.8.0_172",
"1.8.0_202"
]
}
こんな感じで、フィルターを実際に実行して期待している結果が出ることを確認してからwith_itemsにコピペしてタスクをつくると、テストが楽になるよ。