Ansible Vaultを利用して秘密情報を暗号化する
今日はAnsible VaultというAnsibleの暗号化ツールの紹介です。
Ansible Vault
Ansibleは各種設定をYAML形式で記載していきます。YAMLは単なるテキスト情報ですので、そのファイルを開く権限さえ持っていれば誰でもそこに記載された情報を確認することができます。ですが、例えばプロジェクト内でAnsibleのPlaybookを共有する時に、SSHの秘密鍵やDBへの接続情報などの秘密情報は、プロジェクトメンバー全員が知る必要はないはずです。
そういった時にAnsible Vaultを使うと、ファイルの内容が暗号化され、ファイルを開いただけでは内容を確認することができなくなります。公開すべきでない情報に関してはAnsible Vaultを利用して暗号化しておきましょう。
早速試してみます。
導入
Ansible Vaultは、Ansibleをインストールすると一緒に導入されるansible-vault
コマンドを利用して行います。
流れとしては以下の通りです。簡単ですね。
- YAMLファイルをansible-vault
コマンドを使って編集する。
- その時にパスワードを設定することで、そのパスワードを利用してファイル内容を暗号化する
- ansible-playbook
コマンドを実行する時にそのパスワードを与えることでファイル内容を復号化し、通常のAnsible Playbookとして利用できるようにする。
それでは早速試してみます。今回は例として、Ansibleで以下の設定を行うPlaybookを作成します。
- OSユーザ、グループの作成
- SSH秘密鍵の配置
OSユーザとグループの作成には、それぞれAnsibleのuser
モジュールとgroup
モジュールを利用します。秘密鍵の配置にはauthorized_key
モジュールが利用できます。
- user - Manage user accounts — Ansible Documentation
- group - Add or remove groups — Ansible Documentation
- authorized_key - Adds or removes an SSH authorized key — Ansible Documentation
作成対象のユーザと、そのユーザに割り当てるSSHの公開鍵を、Ansibleで利用する変数を定義するgroup_vars/all
に記載します。今回はこのファイルをAnsible Vaultでの暗号化対象にします。
記載する内容は以下の通りです。(SSH公開鍵はブログのためにダミーとして作成したものです)
users: userA: authorized_key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC85yp9hJ8RfclyE1mgQT4rHtDuNIiWQDdaYzmwIJImr9LUycGm4OGjGoxQZ49xHZNisVNbyuWtaGkZ0hy1cLwuH6HkcYu8eMY9NZr5ZuSF7zRDY/vilM2j1Cw8hQ8tajvDfIXwFEhPS78mSCe3lamazbhyEghcUoBq/YGoVnE1SN3mNs0YaogJ5lHH8hdF8Ji+X3nHBnmvsiX+ROj1dL0b/qvHba9vZ3+6KCcbVWvqHbn8L0bbHZShygKobr6eAszOy4j0AgvuYi6naN66RybeRFkYFij6bQHlNKDh692vkKLVAuOrFbqXs0eTCo1SIc0K7xpPyk0A7pIh4YD0BHs9 userA_key' userB: authorized_key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0NgZhWXfpQPhLrIFPXL3kdJlsI+NOvbHltacQ4kgACbhg1CSjt4EOhxIOv8vXzRql0ylCxNWGF4z/LOx0pB4F7XQzJcso6xMpAZY5AmM3nEQyxWqL1t+90VykHjOLiGF+SWdNGD9vwC48wCLpJZCVC2QXVuZxTXdoC6inxAMAwDJmbRJq9Oe9zOiMXDjrT65nHamggL27J0YoVJRYX+Eh9Q9E4CO268ljTxDHjVJgs6EUruf1sW3uT63LOcm3b/DVwhz7Hm+xEIKUnmiweGHNYL7QsACOo0VjpQLES6UUPc/vktpZoxarI9Vqm+IdRGyaiQeiRwadg0u4h8Jrl7K5 userB_key'
さて、この内容をansible-vault
コマンドを利用して記入します。
$ mkdir group_vars $ ansible-vault create group_vars/all Vault password: # パスワードを入力 Confirm Vault password: # もう一度入力 # 編集画面が開くので、上記のYAML内容を記載して、保存して終了
完了です。ファイルの中身を覗いてみます。
$ head -n 5 group_vars/all $ANSIBLE_VAULT;1.1;AES256 34313733373565323464366131636462366637366335636464643138643536313831643261316561 3662303832336239663365363465396532633734393730320a366337396234363935323933376265 33376361383838383761343134663032643066626466386336383133306636646664616437303465 6632626363333862380a636236383333333166333965633034303863663162323231636438376130
ファイルの内容が暗号化されていることが確認できました。このファイルの内容を再度編集する場合には
ansible-vault edit group_vars/all
コマンドでOKです。
実行するPlaybookの内容は以下の通りです。
- hosts: all sudo: yes tasks: - name: be sure group is created group: > name={{ item.key }} state=present with_dict: "{{ users }}" - name: be sure user is created user: > name={{ item.key }} group={{ item.key }} state=present with_dict: "{{ users }}" - name: be sure correct authorized_keys are registered authorized_key: > user={{ item.key }} key="{{ item.value.authorized_key }}" with_dict: "{{ users }}"
AnsibleのLoop用関数であるwith_dict
を利用して、group_vars/all
に記載されたユーザぶんだけユーザ・グループの作成とSSH公開鍵の登録を実施しています。
- Loops — Ansible Documentation
実行
ではPlaybookを実行します。上述の通り、実行時に暗号化した際のpasswordを入力することが求められます。passwordの指定方法は2種類あります。
- --ask-vault-pass
オプションを付ける: 対話式にパスワードを入力する
- --vault-password-file
オプションを付ける: パスワードの記載されたファイルを指定する
今回は--ask-vault-pass
方式で実行します。
$ ansible-playbook -i hosts main.yml --ask-vault-pass Vault password: # 作成した際のパスワードを入力。 PLAY [all] ******************************************************************** GATHERING FACTS *************************************************************** ok: [xx.yy.xx.yy] TASK: [be sure group is created] **************************************** ok: [xx.yy.xx.yy] => (item={'key': 'userB', 'value': {'authorized_key': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0NgZhWXfpQPhLrIFPXL3kdJlsI+NOvbHltacQ4kgACbhg1CSjt4EOhxIOv8vXzRql0ylCxNWGF4z/LOx0pB4F7XQzJcso6xMpAZY5AmM3nEQyxWqL1t+90VykHjOLiGF+SWdNGD9vwC48wCLpJZCVC2QXVuZxTXdoC6inxAMAwDJmbRJq9Oe9zOiMXDjrT65nHamggL27J0YoVJRYX+Eh9Q9E4CO268ljTxDHjVJgs6EUruf1sW3uT63LOcm3b/DVwhz7Hm+xEIKUnmiweGHNYL7QsACOo0VjpQLES6UUPc/vktpZoxarI9Vqm+IdRGyaiQeiRwadg0u4h8Jrl7K5 userB_key'}}) ok: [xx.yy.xx.yy] => (item={'key': 'userA', 'value': {'authorized_key': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC85yp9hJ8RfclyE1mgQT4rHtDuNIiWQDdaYzmwIJImr9LUycGm4OGjGoxQZ49xHZNisVNbyuWtaGkZ0hy1cLwuH6HkcYu8eMY9NZr5ZuSF7zRDY/vilM2j1Cw8hQ8tajvDfIXwFEhPS78mSCe3lamazbhyEghcUoBq/YGoVnE1SN3mNs0YaogJ5lHH8hdF8Ji+X3nHBnmvsiX+ROj1dL0b/qvHba9vZ3+6KCcbVWvqHbn8L0bbHZShygKobr6eAszOy4j0AgvuYi6naN66RybeRFkYFij6bQHlNKDh692vkKLVAuOrFbqXs0eTCo1SIc0K7xpPyk0A7pIh4YD0BHs9 userA_key'}}) <中略...> PLAY RECAP ******************************************************************** xx.yy.xx.yy : ok=4 changed=2 unreachable=0 failed=0
実行が確認できました。
注意点
実行して気になったのは、パスワード化した秘密鍵が標準出力に書かれてしまっていることです。できればこれを非表示にしたかったのですが、やり方を見つけることができませんでした。
6/18 05:30追記: コメントにてご指摘をいただきました。 変数の標準出力への書き込みを抑制するには、各タスクやPlaybookにno_log: Trueを記載すればOKです。 - Frequently Asked Questions — Ansible Documentation
ansible-playbook
実行時の2つのパスワード指定方法があることを紹介しました。当然ですが--vault-password-file
オプションを利用する場合、パスワードファイルはバージョン管理などに載せて誰でも閲覧可能な状態にするのはやめましょう。そうしないと暗号化している意味がなくなってしまいます。
また、今回は変数ファイルを暗号化しましたが、実はPlaybook自体をAnsible Vaultを利用して暗号化することもできるようです。場合によっては利用することもあるでしょうか。
まとめ
Ansibleを利用して秘密情報を扱う時に利用できるansible-vault
を紹介しました。Ansible本体と同様に導入は非常に簡単ですので、平文で保存されたままのパスワードなどがある場合は置き換えてみてはいかがでしょうか。