それまで使う必要が無かったのですが、仕事で必要になって調べた際、時間を使ってしまったので、ブログ記事にして記録を残しておきます。基本、公式ドキュメントを読めばいい話なのですが、一応詰まった話なので供養。
ansibleを使用する際、普通なら必要になる変数はgroup varsやhost varsを記載しているファイルに値を書いておけばいいのですが、ansible実行時に値を書き換えたいときが発生すると ansible-playbookコマンドの -e
オプションを使って渡す必要が出てきます。
ansibleの公式ドキュメントのUsing VariablesのPassing variables on the command lineを読めば分かるとおり、以下のようにJSON形式の文字列を渡すことができます。
$ ansible-playbook release.yml --extra-vars '{"version":"1.23.45","other_variable":"foo"}' $ ansible-playbook arcade.yml --extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'
これにより複雑な形式の変数を渡すことができます。
私が仕事で困って調べるのに時間を使ってしまったのは、ネストしたJSONのkeyにあたる箇所の値を実行先ホストによって変えたい場合の渡し方でした。
うまく説明できているかは分かりませんが、以下のようなYAML形式のパラメータの parameter
にあたる部分を実行先ホストによって変更した値をコマンドラインからansible-playbookコマンドに渡したい場合の話です。
redash_db_upgrade_enabled: parameter: true
結果から書くと以下のようにbash変数を利用して、JSON形式の文字列を渡してやれば上手くいきました。同じことをYAML形式の文字列で渡すやり方で試してみても上手くいかなかったので、JSON形式の方がいいのかもしれません。*1
$ proj_name=default $ ansible-playbook playbook.yml -i hosts.ini -e "{'redash_db_upgrade_enabled': {'${proj_name}': true}}"
上記の例ではプロジェクト名が default
の時には redash_db_upgrade_enabled
で表現したい状態をオンにする(=それ以外のプロジェクトではオフのままにする)ということをしたくてやっているものです。
事前にbash変数で proj_name=default
とproj_nameの値を設定しておけば {'redash_db_upgrade_enabled': {'${proj_name}': true}}"
という書き方で {'redash_db_upgrade_enabled': {'default': true}}"
と渡したときと同じように働きました*2。
あまり複雑な形式の変数をコマンドライン経由でansibleに渡すのはアンチパターンだとは思いますが、もしgroup varsなどを使えない状況だったときには利用できるやり方かもしれません。