前回の記事では Ansible Vault の基本的な機能を使って、以下の要件までを実現しました。
- 機密情報の変数(パスワードなど)を暗号化する
- ターゲットに配置する機密ファイル(秘密鍵など)を暗号化する
- Vault パスワードをスクリプトで管理する
しかし Vault パスワードが全環境で共通のため、開発メンバー全員が本番環境の機密情報も復号化できてしまいます。
そこで今回は、以下の要件を実現します。
- 開発 / 検証 / 本番環境で別々の Vault パスワードを使用する
参考: Ansible Vault — Ansible Documentation
- 確認環境:
- Ansible 2.10.7
- Ubuntu 20.04 / Debian 10 (buster)
環境ごとの Vault パスワードを設定する
前回: Vault パスワードが 1 つの場合
前回は以下のように唯一の Vault パスワードを設定したので、ansible-vault
ansible-playbook
などのコマンドが使用する Vault パスワードを指定する必要がありませんでした。
ANSIBLE_VAULT_PASSWORD_FILE="/workspace/.vault_pass.sh"
今回: Vault パスワードが複数の場合
しかし Vault パスワードが複数になると、どのパスワードを使って暗号化するかを指定したり、暗号化と同じパスワードを使って復号化する必要があります。
複数の Vault パスワードは以下のようにリストにして、環境変数 ANSIBLE_VAULT_IDENTITY_LIST に設定します。
ANSIBLE_VAULT_IDENTITY_LIST="dev@/workspace/vault_pass_dev.sh, stg@/workspace/vault_pass_stg.sh, prd@/workspace/vault_pass_prd.sh"
設定値は {ID 1}@{スクリプト 1}, {ID 2}@{スクリプト 2}, ...
のように、Vault ID と スクリプトのペアをいくつでも指定できます。
上記の例で設定したリストの内容は以下のとおりです
- 環境ごとに使用する Vault パスワードの ID を「dev」「stg」「prd」とする
- それぞれの Vault パスワードを出力するスクリプトは、
/workspace/vault_pass_{Vault ID}.sh
とする
この設定によって、任意の Vault ID に紐づくスクリプトを呼び出して Vault パスワードを取得することができます。
参考:
複数の vault パスワード — Ansible Vault — Ansible Documentation
Vault IDs in Ansible 2.4 - Red Hat Learning Community
Ansible Configuration Settings — Ansible Documentation
ここで環境変数を定義している *.env ファイルは、開発環境を Docker で構築する際に docker-compose.yml の env_file: に指定することを想定しています。
開発環境が Docker でない場合は ~/.bashrc などで環境変数を export するか、ansible.cfg で設定してください。
環境ごとに Vault ID を指定して暗号化する
コマンド ansible-vault encrypt
の --encrypt-vault-id
オプションを使えば、暗号化するファイルごとに Vault ID を指定することができます。
以下の例では、環境名(= Vault ID)と同名のディレクトリ内に配置された vault という名前の平文ファイルを暗号化します。
.
├── dev
│ └── group_vars
│ └── all
│ ├── vars
│ └── vault # 暗号化する
├── stg
│ └── group_vars
│ └── all
│ ├── vars
│ └── vault # 暗号化する
└── prd
└── group_vars
└── all
├── vars
└── vault # 暗号化する
変数ファイル vars と vault の関係は、前回の記事で紹介した公式ベストプラクティスのとおりです。
以下は環境と同名の Vault ID を --encrypt-vault-id
に指定して、各環境の vault ファイルを暗号化する例です。
for id in $(ls .); do
# 環境ごとのディレクトリ名と Vault ID は同じ(dev|stg|prd)
find ${id} -name "vault" -exec \
ansible-vault encrypt --encrypt-vault-id ${id} {} +
done
ansible-vault encrypt
コマンドは、ANSIBLE_VAULT_IDENTITY_LIST
で Vault ID に紐付けられたスクリプトを呼び出して、取得した Vault パスワードを使って指定のファイルを暗号化します。
暗号化前の vault ファイルをコミットしてしまわないように注意しましょう。
復号化に使用する Vault パスワード
各ファイルを復号化する時には、暗号化に使用したものと同じ Vault パスワードを使う必要があるのですが、ansible-vault edit
や ansible-playbook
などのコマンドでは Vault ID を指定する必要がありません。
実は暗号化されたファイルを見ると、
$ANSIBLE_VAULT;1.2;AES256;dev
34336462316665666231643965643533383165373964323663373036623034626237333361376231
6135346338376464643034376339323461316534323965370a346332343530626436663731333438
(略)
このように 1 行目の終わりに、暗号化に使用された Vault ID が記録されています。
ansible-vault
ansible-playbook
などのコマンドは、ファイルに記録された Vault ID と ANSIBLE_VAULT_IDENTITY_LIST
の定義から、暗号化に使用されたものと同じ Vault パスワードを取得して復号化してくれます。
したがって、Vault ID やパスワードを環境ごとに区別して取り扱うのは、最初に暗号化する時だけです。
以後はこれらの違いを気にしないで ansible-vault edit
や ansible-playbook
を実行することができます。
次回の課題
以上で Vault パスワードを環境ごとに別々にできたのですが、まだ Vault パスワードを管理するために PC 内のファイルや環境変数を使用する必要があります。
そこで次回は、Vault パスワードをクラウドに保存して、Vault パスワード取得用スクリプトもクラウドから取得する処理に改良します。
前回: いまさら Ansible Vault で変数とファイルを暗号化して、Vault パスワードをスクリプトで管理する - Qiita
次回: いまさら Ansible Vault (3): Vault パスワードを環境ごとの AWS アカウントの SSM パラメータストアで管理する - Qiita