Ansibleでのパスワードの取り扱い
概要
Ansibleを使っていて、
- sambaのユーザパスワード
- BASIC認証のパスワード
など、パスワードを管理して使いたい場合が時たまあると思います。
そんな時にいつも使っている方法を紹介します。
パスワード管理方法
1. Ansible Vaultで暗号化する
基本的にパスワードの類はAnsible Vaultで暗号化して使用します。
ansible_sudo_pass:
として SUDOパスワードを入れておくと、SUDOパスワードの省略ができて便利です。
private.ymlにパスワード類を記載し、Ansible Vaultで暗号化する
### sudoパスワードとsambaのパスワードを記載
% vim private.yml
+ ---
+ ansible_sudo_pass: sudo_password
+ samba_user: samba
+ samba_pass: smb_password
### private.ymlを暗号化 (暗号化用パスワードを入力)
% ansible-vault encrypt private.yml
Vault password:
Confirm Vault password:
Encryption successful
暗号化してるとはいえ、パスワードをgitに上げるわけにはいかないので、.gitignore
に記載しておきます。
private.ymlはgitで管理しない
### .gitignoreで除外
% vim .gitignore
...
+ private.yml
...
2. 外部変数として読み込む
private.yml
に定義した変数を、実行時に --extra-vars
で読み込みます。
--ask-vault-pass
オプションを付けて実行するとVaultのパスワードを聞かれるので、先程暗号化時に設定したパスワードを入力します。
private.ymlをextra_varsとして読み込む
### --extra-varsで private.yml 内の変数を渡す
% ansible-playbook -i hosts setup-smb.yml --extra-vars="@private.yml" --ask-vault-pass
Vault password:
playbook内では通常のように変数として記入しておきます。
playbook内で変数の使用
...
- name: sambaユーザの追加
shell: echo -e "{{ samba_pass }}\n{{ samba_pass }}\n" | pdbedit -t -a {{ samba_user }}
...
3. private.ymlが存在しない場合の処理を記載
このままでも個人で使うには十分ですが、private.yml
を配置せずにplaybookを使用するとエラーが発生してしまいます。
これを避けるためには2通りの方法が考えられます。
role内のdefaults/main.ymlにデフォルトパスワードを定義する
roleを使用している場合、defaults
内にデフォルトパスワードを定義しておくことで、private.yml
が与えられなかった場合でもplaybookを実行することが可能になります。
### パスワードのデフォルト値を設定
% cat /role/samba/defaults/main.yml
..
samba_user: samba
smb_pass: default_password
...
(※ defaults
は優先順位が最も低い、--extra-vars
は一番強い)
参考: Variable Precedence: Where Should I Put A Variable?
デフォルトパスワードでインストールすることはそうそう無いのと、弱いパスワードでインストールされるのを防ぐという観点でいうとこの方法はあまり良くないかも知れません。
プロンプトでの入力
Ansibleには、ユーザの入力をプロンプトで受け付ける機能があります。
ここでは、パスワードとして使用する変数がnull
の場合にプロンプトで入力するように設定しておきます。
### プロンプトを使用したplaybook
% cat setup-smb.yml
---
- hosts smb
vars_prompt:
- name: samba_pass # 変数名
prompt: Samba password # プロンプト時に表示されるテキスト
private: yes # 入力値を画面に表示しない
confirm: yes # 2回入力で打ち間違いを防止する
when: samba_pass == null # nullの場合に尋ねる
roles:
- { role: samba, sudo: yes }
### extra-varsを渡さない場合
% ansible-playbook -i hosts setup-smb.yml -K
SUDO password:
Samba password:
confirm Samba password:
...
### extra-varsを渡した場合
% ansible-playbook -i hosts setup-smb.yml --extra-vars="@private.yml" --ask-vault-pass
Vault password:
...
パスワードとして使用する変数が多い場合、実行時のプロンプトが多すぎて入力が面倒くさいという欠点があります。
とりあえず、これによってprivate.yml
を作成していない場合でもplaybookを実行することができます。
4. その他
この方法を使っているとパスワードの初期セットアップや、実行時のオプションがややこしくなってくるので、README
にちゃんと記載するか、実行用のシェルスクリプトを用意するようにしています。
また、構築用のスクリプトと設定アップデート用のスクリプトを分けて
% tree samba -L 1
samba
├── README.md
├── private.yml
├── roles
├── hosts
├── update-smb.yml # 設定アップデート用のplaybook, パスワードを必要としない
└── setup-smb.yml # 構築用のplaybook, パスワードを必要とする
こんな感じにするのもありです。
構築はそんなに使用頻度高くない(はず‥)なので
まとめ
まとめると、
- Ansible Vaultでファイルを暗号化
-
--extra-vars
で実行時に渡す - (※ オプション) デフォルトパスワードか、プロンプトを仕掛ける
という感じです。
個人的には
- デフォルトパスワードをアップロードしなくて済む
- デフォルトパスワードでインストールされることを防げる
- プロンプトがめんどくさい場合はprivate.ymlを設定する
という理由でプロンプトを設定して使っています。
--
この記事は、以前に書いた下記のブログ二つをまとめたものになります。
http://jimaoka.hatenablog.jp/entry/ansible-vault
http://jimaoka.hatenablog.jp/entry/ansible-passwd