Ansible Vaultで機密情報を管理する方法

AnsibleのPlaybookで、パスワード等の機密情報を記載したい場合があります。テンプレートファイルを見れば、パスワードが丸わかりとなってしまうため、これを暗号化して利用する方法が用意されており、それが Ansible Vault となります。

公式ドキュメントはこちら。

Ansible Vault

例えば

PostgreSQLでは、インストール時に postgres というDBユーザが自動的に作成されます。SuperUserというポスグレ内で最高権限を持ったDBユーザなのですが、自動作成時にはパスワードが未設定の状態となっています。パスワード未設定でも問題ないですが、これにパスワードを設定したいとなった場合、AnsibleではPostgreSQL用のモジュールがいくつか用意されており、 postgresql_user というDBのユーザ(ロール)を操作してくれるモジュールを利用します。

Ansible - postgresql_user

具体的にはこんな感じでテンプレートを書きます。 postgres というロールを用意して、その中でplaybookを書いています。

roles/postgresql/tasks/main.yml

- name: DBユーザpostgresのパスワード設定
  postgresql_user:
    name: postgres
    password: "{{ dbuser_password_postgres }}"
    login_unix_socket: /var/run/postgresql
    state: present
  become: true
  become_user: postgres

roles/postgresql/vars/main.yml

dbuser_password_postgres: Passw0rd

Ansible Vaultの使い方

上の roles/postgresql/vars/main.yml を暗号化できればいいので、ここでAnsible Vaultが出てきます。

Ansible Vaultは、Ansibleインストール時に同時に入っているはずですので、追加でインストールは不要です。以下がコマンドヘルプ画面。

$ ansible-vault --help
Usage: ansible-vault [create|decrypt|edit|encrypt|encrypt_string|rekey|view] [options] [vaultfile.yml]

vaultfile.yml に暗号化したいファイルを指定して、あとは create なり encrypt なり edit なりができます。コマンド実行時にパスワードが求められるので、それが該当ファイルに対するAnsible Vaultのパスワードとなります。

encrypt した後のファイルを開いてみると、以下のように暗号化されています。

$ANSIBLE_VAULT;1.1;AES256
61336463333032346564303739633665386333353832613565383366663938626531366237336138
6634646461343866643666343937623130613162643834390a386635626238656332363265626232
34616432656532303436343165356362356337666564633166386539373864353265616265623030
6463643633636434650a613631663739373336663564353539623333363137356330633638353162
38633236316534383561353631643933643235313031633331323930663137383865653966666530
38353738626363333732303263393638326334363361303732663932643931663136323064323737
30616430336337616531376538653736616439353034336161613230383733363132633935346232
32646135393934356564

playbookの実行

Ansible Vaultしたファイルを含むplaybookを実行するには、パスワードを記述したファイルを用意して、playbookコマンド実行時に --vault-id オプションで、そのファイルを指定してあげます。

こんなファイルを用意して、

roles/postgres/vault_password

password-for-vault

playbook実行時に指定してあげる。

$ ansible-playbook --vault-id roles/postgres/vault_password site.yml

パスワードファイルからパスワードを読み取って実行してくれます。

コマンド実行時にオプションを常時指定する以外にも、ANSIBLE_CONFIGファイルに、以下の通り記載することで、デフォルトで読み取ってくれるようなります。

ansible.cfg

[defaults]
vault_password_file = roles/postgres/vault_password

ロールでの使い方

これまでの利用方法では、変数ファイル roles/postgresql/vars/main.yml がすべて暗号化されることになります。機密情報のみ暗号化できれば良いのですから、そういった場合、変数ファイルを複数用意して、機密情報を記載したファイルのみAnsible Vaultしてあげれば良さそうです。

つまり、こんな感じに、ファイルを分けてあげればいいと。

roles/postgresql/vars/main.yml

dbuser_password_postgres: "{{ vault_dbuser_password_postgres }}"

roles/postgresql/vars/vault.yml

vault_dbuser_password_postgres: Passw0rd

Ansibelのロールで利用できる変数は、 vars/main.yml ファイルのみであるという条件があり、複数のファイルから変数を取得できないため、明示的にこの変数ファイルを取り込む処理をメイン処理部分のyamlに記載してあげる必要があります。

以下を追加してあげる。

roles/postgresql/tasks/main.yml

- include_vars: vault.yml
  no_log: true

no_log パラメータを付与することで、取り込んだ変数ファイルを標準出力に出力しなくなります。

Ansible - include_vars

Ansible - no_log

ロールでの上手い利用方法がよく分からなかったのですが、以下のブログが参考になりました。ありがとうございました。

AnsibleのVaultで暗号化されたファイルを管理する際のベストプラクティス