前書き
ここのところAnsible Vaultを各種パスワードの保管場所にしている。
勝手にアプリをインストールできるような環境ならKeePassとか使うのだけど、Ansible Vaultでも保管したたくさんのパスワードを1つのマスタパスワードで取り出すくらいの役には立つ。
しかしansible-vault edit(あるいはview)で一々開いてコピペするのがそろそろ面倒になってきたのでワンライナーで取り出すようにしてみた。
下準備
Ansible Vaultから値を取り出して出力させるにはansibleコマンドを使うのが良い。
ansibleコマンドでAnsible Vaultを使うには、ansibleコマンドを実行するディレクトリにhost_varsディレクトリかgroup_varsディレクトリが必要になる。
ここではhost_varsディレクトリを作っておく。
$ mkdir host_vars
host_varsディレクトリの中にはansible-vault create
で作ったyamlファイルを配置する。
他から持ってきても良いし、新しく作っても良い。
配置するファイル名のxxxの部分はホスト名にしておけばそのホストに対して処理を行う際にキーの名前だけで値にアクセスできるが、今回の用途ではlocalhostが処理対象になるだけなので適当な名前で問題ない。
$ ansible-vault create host_vars/xxx.yml
中身はどんなキーでも良いし、いくつあっても構わない。
"host1": "password1"
"host2": "password2"
さっきのxxxと同じ文字列を書いたインベントリファイルを作る。
$ echo 'xxx' > hosts
ansible-vault create
の際に設定したパスワードだけを書いた適当な名前のファイルを作る。
$ echo 'password' > vault
このファイルはパーミッションを400にしておくとより良いだろう。
$ chmod 400 vault
ワンライナー
ここまで準備しておけば以下でAnsible Vaultに保管した適当な値を取り出して標準出力に出力することができる。
$ ansible localhost -i hosts --vault-password-file vault -o -m debug -a 'var=hostvars.xxx.host1' | head -n 1 | sed -r 's/^.+: "(.*)"}$/\1/'
軽く解説すると、
- 値を取り出すだけなので処理するホストはlocalhostで良い。
- --vault-password-fileオプションでAnsible Vaultのパスワードを書いたファイルを指定することでパスワード入力をしないで良いようにしている。
- -oは滅多に使わないオプションだが、出力結果を1行で表示するものである。
- 別のファイルや別のキーから値を取り出す場合はvar=hostvars.xxx.host1のxxx.host1の部分を書き換えれば良い。
- head -n 1しているのは後ろに余計な空白行がくっついているのでそれを削るためである。
- sedは出力から値の部分だけ取り出すものである。
利用例。sshpassを使ってパスワード認証でSSHログインする。
sshpass -p $(ansible localhost -i hosts --vault-password-file vault -o -m debug -a 'var=hostvars.xxx.host1' | head -n 1 | sed -r 's/^.+: "(.*)"}$/\1/') ssh user@hostname