Red Hat Certified Engineer (RHCE) #10 Ansible Vault: 秘密の管理
#9 Tag と条件分岐 では task を選択的に実行し、条件と繰り返しで流れを制御しました。今回はプレイブックが扱う 秘密の値 を安全に保管する方法です。データベースのパスワード、API トークン、ユーザーの初期パスワードのような値を平文で inventory や変数ファイルに置くと、git リポジトリや試験の採点環境にそのまま露出します。Ansible はこれを防ぐために Ansible Vault という暗号化メカニズムを提供します。
Vault は変数ファイル全体、または単一変数 1 つを AES256 で暗号化しておき、プレイブック実行の時点でのみパスワードで復号して使います。RHCE 試験では「秘密変数を vault で暗号化してプレイブックで使え」「パスワードファイルを置いて非対話で実行されるようにせよ」が定番の問題なので、ansible-vault のサブコマンドと実行オプションを手に覚えさせます。
Vault が解く問題 #
プレイブックは変数で動作が分かれます。その変数の中には、誰にも見せてはならない値が混じっています。
- データベースの接続パスワード
- 外部サービスの API キーとトークン
- ユーザーアカウントの初期パスワード
- TLS 秘密鍵のような認証資料
こうした値を group_vars/db/vars.yml に平文で書いておくと、ファイルを読む誰もが秘密を知ってしまいます。Vault は ファイルを暗号化された状態でディスクに置き、プレイブック実行時に渡した vault パスワードでのみ復号するので、git にコミットしても内容は露わになりません。
暗号化されたファイルは 1 行目が $ANSIBLE_VAULT;1.1;AES256 で始まり、その下に 16 進数の塊が続きます。Ansible は変数ファイルをロードするとき、このヘッダーを見て自動的に復号を試みます。
ansible-vault サブコマンド #
ansible-vault は次のサブコマンドで暗号化ファイルを扱います。この 6 つが試験で使うすべてです。
| コマンド | 動作 |
|---|---|
ansible-vault create <ファイル> | 新しい暗号化ファイルを作りエディターで開く |
ansible-vault edit <ファイル> | 暗号化ファイルを復号してエディターで開き、保存時に再暗号化する |
ansible-vault view <ファイル> | 暗号化ファイルの内容を画面に復号して見せる |
ansible-vault encrypt <ファイル> | 既存の平文ファイルを暗号化する |
ansible-vault decrypt <ファイル> | 暗号化ファイルを平文に戻す |
ansible-vault rekey <ファイル> | vault パスワードを新しいパスワードに変更する |
create: 新しい暗号化ファイルを作る #
最初から暗号化された変数ファイルを作るときは create を使います。パスワードを 2 回入力したあと、$EDITOR で指定されたエディターが開きます。
ansible-vault create group_vars/db/secret.yml
# New Vault password:
# Confirm New Vault password:エディターの中では普通の YAML として書きます。
# group_vars/db/secret.yml (エディターの中で見える平文)
db_root_password: "S3cr3t!root"
db_app_password: "App#2026pw"保存して抜けると、ディスクには暗号化された形で記録されます。
cat group_vars/db/secret.yml
# $ANSIBLE_VAULT;1.1;AES256
# 39613266313764336239...view と edit: 見ると修正 #
暗号化ファイルは cat で見ると 16 進数しか出ないので、内容の確認は view で行います。
ansible-vault view group_vars/db/secret.yml
# Vault password:
# db_root_password: "S3cr3t!root"
# db_app_password: "App#2026pw"値を直すときは edit を使います。復号した一時的な内容をエディターで開き、保存すると再び暗号化します。
ansible-vault edit group_vars/db/secret.yml
# Vault password:encrypt と decrypt: 既存ファイルの変換 #
すでに平文で書いておいた変数ファイルがあるなら、encrypt で一度に暗号化します。
ansible-vault encrypt group_vars/web/secret.yml
# Vault password:
# Encryption successful逆に暗号化を解いて平文に戻すときは decrypt を使います。
ansible-vault decrypt group_vars/web/secret.yml
# Vault password:
# Decryption successfulrekey: パスワードの変更 #
vault パスワードを交換するときは rekey で現在のパスワードを入力したあと、新しいパスワードを設定します。
ansible-vault rekey group_vars/db/secret.yml
# Vault password:
# New Vault password:
# Confirm New Vault password:
# Rekey successful変数ファイルを暗号化して使う #
実務と試験の標準パターンは グループ変数を 2 つに分ける 方式です。公開してもよい値は vars.yml に、秘密の値は vault.yml に置きます。
group_vars/
db/
vars.yml # 平文: db_user、db_port など
vault.yml # 暗号化: vault_db_password など暗号化ファイルの中では、変数名に vault_ 接頭辞を付ける慣習がよくあります。
# group_vars/db/vault.yml (ansible-vault edit で見た平文)
vault_db_password: "S3cr3t!root"平文ファイルでは、その vault 変数を一般的な名前に結びつけます。こうすればプレイブックは普通の変数名だけを参照し、実際の秘密は暗号化ファイルにのみ存在します。
# group_vars/db/vars.yml
db_user: appuser
db_port: 3306
db_password: "{{ vault_db_password }}"プレイブックでは平文の変数のようにそのまま使います。
# site.yml
- name: Configure database
hosts: db
tasks:
- name: Set DB root password
ansible.builtin.debug:
msg: "connecting with {{ db_user }} / {{ db_password }}"実行の時点で vault パスワードを渡してはじめて変数が復号されます。
ansible-playbook site.yml --ask-vault-pass
# Vault password:実行時にパスワードを渡す方法 #
暗号化変数を使うプレイブックは、vault パスワードなしでは実行されません。パスワードを渡す方式は 2 つあります。
–ask-vault-pass: 対話入力 #
実行するときにパスワードを直接入力します。人が見守りながら 1 回回すときに適しています。
ansible-playbook site.yml --ask-vault-passansible-navigator で実行するときも同じオプションを使います。
ansible-navigator run site.yml -m stdout --ask-vault-pass–vault-password-file: パスワードファイルで自動化 #
パスワードをファイルに 1 行で書いておき、そのファイルのパスを渡すと、入力なしで自動的に復号されます。cron や無人実行、そして試験で「非対話で実行されるようにせよ」という要求に使う方式です。
echo 'mypassword' > ~/.vault_pass
chmod 600 ~/.vault_pass
ansible-playbook site.yml --vault-password-file ~/.vault_passansible.cfg に登録しておけば、オプションなしでも常にそのファイルを使うようになります。
# ansible.cfg
[defaults]
vault_password_file = ~/.vault_passansible-vault のサブコマンドも同じオプションを受け取るので、パスワードファイルがあれば view や edit も非対話で動作します。
ansible-vault view group_vars/db/vault.yml --vault-password-file ~/.vault_passencrypt_string: 単一変数のインライン暗号化 #
変数ファイル全体ではなく 1 つの値だけ を暗号化したいときは encrypt_string を使います。出力として出た暗号文ブロックを平文 YAML ファイルにそのまま貼り付けられます。
ansible-vault encrypt_string 'S3cr3t!root' --name 'db_password'
# Vault password:
# db_password: !vault |
# $ANSIBLE_VAULT;1.1;AES256
# 39613266313764336239...この出力を平文の vars.yml に貼り付けると、ファイル自体は平文でも、その変数 1 つだけが暗号化された状態になります。
# group_vars/db/vars.yml
db_user: appuser
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
39613266313764336239...パスワードを標準入力で受け取らせれば、パイプラインでも使えます。
ansible-vault encrypt_string --vault-password-file ~/.vault_pass \
'App#2026pw' --name 'db_app_password'!vault タグが付いた値は Ansible が変数を評価するときに自動的に復号するので、プレイブックでは {{ db_password }} のように普通に参照します。
vault id: パスワードを複数に #
互いに異なる vault パスワードで暗号化したファイルを 1 つのプレイブックで一緒に使うときは、vault id でラベルを付けて区別します。--vault-id ラベル@ソース 形式で複数を同時に渡します。
ansible-playbook site.yml \
--vault-id dev@~/.vault_dev --vault-id prod@prompt暗号化するときも同じラベルを指定すれば、復号時にどのパスワードを使うかを Ansible がラベルでマッチングします。
ansible-vault encrypt --vault-id prod@~/.vault_prod group_vars/db/vault.yml試験のポイント #
- パスワードファイルの権限。
--vault-password-fileで使うファイルは平文のパスワードを入れるので、chmod 600で本人だけが読めるようにロックしておきます。権限が緩いと秘密の露出リスクがそのまま残ります。 - –vault-password-file で非対話実行。試験で「パスワードの入力なしで実行されるようにせよ」が出たら、パスワードファイルを作って
ansible.cfgのvault_password_fileに登録するか、オプションで渡します。--ask-vault-passは対話なので、自動化の要求には合いません。 - 暗号化対象の分離。秘密は
vault.ymlに、平文はvars.ymlに置き、平文からvault_変数を参照する構造が標準です。採点時に秘密が平文で残っていると減点です。 - 単一の値は encrypt_string。ファイル全体を暗号化するなとか、1 変数だけ隠せという要求には、
encrypt_stringの出力を平文ファイルにインラインで貼ります。 - play に vault 変数があればパスワードなしでは失敗。
ansible-vault viewで内容を先に確認し、実行オプションにパスワードの提供が抜けていないか点検します。
まとめ #
この記事で押さえたこと:
- Ansible Vault は変数ファイルや単一変数を AES256 で暗号化してディスクに安全に保管します。
- サブコマンド。
create・edit・view・encrypt・decrypt・rekeyで暗号化ファイルを扱います。 - 標準パターン。
group_vars/<グループ>/vault.ymlに秘密を入れ、平文のvars.ymlからvault_変数を参照します。 - 実行時のパスワード提供。
--ask-vault-passは対話、--vault-password-fileは非対話の自動化用で、ansible.cfgにも登録できます。 encrypt_stringで単一の値をインライン暗号化し、--vault-idで複数のパスワードをラベルで区別します。
次へ — Role の作成と使用 #
秘密まで安全に扱う方法を押さえました。ここからプレイブックを再利用可能な単位にまとめる role に進みます。
#11 Role の作成と使用 では、role のディレクトリ構造 (tasks/handlers/templates/vars/defaults)、ansible-galaxy init で骨格を作る方法、プレイブックから role を呼び出す方式、そして試験でよく出る「与えられた要件どおりに role を作成して適用せよ」というタイプまで、直接作りながら整理します。