なっく日報

技術やら生活やらのメモ

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

はじめに

Best Practices — Ansible Documentation

↑のAnsible公式ドキュメントのベストプラクティスの中の「Variables and Vaults」という項目に書いてあったことにプラスアルファした内容です。

ある程度わかっている人が検索してくることを想定しているので、ちょっと雑に書きますw

問題

AnsibleのVaultはパスワードとか秘密鍵みたいなセンシティブな情報が書かれたYAMLを暗号化できるので、非常に重宝する機能ですが、

password1: himitsu_daaaaaaaa
password2: secret_daaaaaaaa

みたいなYAMLを暗号化した結果が↓で

$ANSIBLE_VAULT;1.1;AES256
3333333333333333333333333333333333333333333333333333333333333333333333333333

変数名なんだっけ?となって管理しづらいという問題があります。

「ansible vault best practice」でググった

そこで、ググったところ、公式のベストプラクティスにたどり着きました。

A best practice approach for this is to start with a group_vars/ subdirectory named after the group. Inside of this subdirectory, create two files named vars and vault. Inside of the vars file, define all of the variables needed, including any sensitive ones. Next, copy all of the sensitive variables over to the vault file and prefix these variables with vault. You should adjust the variables in the vars file to point to the matching vault variables and ensure that the vault file is vault encrypted.

が、ちょっとわかりづらい。。

もうちょとググッてみたら

blog.noldor.info

な記事が。

要は

group_vars/stg.ymlを暗号化されているモノとそうでないモノで分ける

group_vars/stg.ymlみたいに定義していたモノは↓のようにディレクトリを掘って、ファイルを分けても自動的に読み込まれるそう。

  • group_vars/stg/vars.yml
  • group_vars/stg/vault.yml

暗号化されてないファイルから暗号化するファイルで定義された値を参照する

(暗号化されていない)vars.ymlで↓のように書いて

password1: {{ vault_password1 }}

(暗号化する)vault.ymlで↓のように定義してあげると。

vault_password1: himitsu_daaaaaaaa

これなら、grepもし易いし、どの変数が暗号化されているかも一目瞭然です。

※最後にansible-vault encrypt group_vars/stg/vault.ymlしてあげるのをお忘れなく

だが、roles/foo/vars/main.yml は・・・

じゃあ、おんなじ要領でと、roles配下で、roles/foo/vars/main.ymlとroles/foo/vars/vault.ymlでやろうとしたら嵌りました。

嵌った原因

roles/foo/vars/main.yml以外は自動的に変数として読み込んでくれないよう。

roles/foo/tasks/main.ymlで↓のようにinclude_varsを使って明示的にincludeしないと使えませんでした。

- include_vars: vault.yml
  no_log: true # ←これもつけた方がよいそう

これは

qiita.com

の記事を見て解決しました(ありがとうございました)

まとめ

多分、(同じように嵌っている|これから嵌る)方はいると思うので、少しでも参考になれば幸いです。

からの、おまけ

その1

秘密鍵とかの変数をtemplates/id_rsa.j2みたいなファイルを置いて、templateモジュール機能を使って配置している例を(社内で)何個かみかけたのですが、

- copy: >
    content="{{ foo_secret_key }}"
    dest=~/.ssh/id_rsa
    mode=0600

みたいにcopyモジュールのcontent指定でもいけます

その2

秘密鍵的な長い文字列を変数に設定するときはYAML|を使った記法が便利(改行をのこしたまま文字列の値として扱ってくれる)

vault_secret_key: |
  -----BEGIN RSA PRIVATE KEY-----
  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  -----END RSA PRIVATE KEY-----