Red Hat Certified Engineer (RHCE) #10 Ansible Vault: 秘密の管理

読了 8分

#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
# 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 で行います。

viewで内容を確認
ansible-vault view group_vars/db/secret.yml
# Vault password:
# db_root_password: "S3cr3t!root"
# db_app_password: "App#2026pw"

値を直すときは edit を使います。復号した一時的な内容をエディターで開き、保存すると再び暗号化します。

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 successful

rekey: パスワードの変更 #

vault パスワードを交換するときは rekey で現在のパスワードを入力したあと、新しいパスワードを設定します。

vaultパスワードの変更
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のディレクトリ構成
group_vars/
  db/
    vars.yml      # 平文: db_user、db_port など
    vault.yml     # 暗号化: vault_db_password など

暗号化ファイルの中では、変数名に vault_ 接頭辞を付ける慣習がよくあります。

group_vars/db/vault.yml
# group_vars/db/vault.yml (ansible-vault edit で見た平文)
vault_db_password: "S3cr3t!root"

平文ファイルでは、その vault 変数を一般的な名前に結びつけます。こうすればプレイブックは普通の変数名だけを参照し、実際の秘密は暗号化ファイルにのみ存在します。

group_vars/db/vars.yml
# group_vars/db/vars.yml
db_user: appuser
db_port: 3306
db_password: "{{ vault_db_password }}"

プレイブックでは平文の変数のようにそのまま使います。

site.yml
# site.yml
- name: Configure database
  hosts: db
  tasks:
    - name: Set DB root password
      ansible.builtin.debug:
        msg: "connecting with {{ db_user }} / {{ db_password }}"

実行の時点で vault パスワードを渡してはじめて変数が復号されます。

vaultパスワード入力で実行
ansible-playbook site.yml --ask-vault-pass
# Vault password:

実行時にパスワードを渡す方法 #

暗号化変数を使うプレイブックは、vault パスワードなしでは実行されません。パスワードを渡す方式は 2 つあります。

–ask-vault-pass: 対話入力 #

実行するときにパスワードを直接入力します。人が見守りながら 1 回回すときに適しています。

対話式で実行
ansible-playbook site.yml --ask-vault-pass

ansible-navigator で実行するときも同じオプションを使います。

ansible-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_pass

ansible.cfg に登録しておけば、オプションなしでも常にそのファイルを使うようになります。

ansible.cfg
# ansible.cfg
[defaults]
vault_password_file = ~/.vault_pass

ansible-vault のサブコマンドも同じオプションを受け取るので、パスワードファイルがあれば viewedit も非対話で動作します。

パスワードファイルでview
ansible-vault view group_vars/db/vault.yml --vault-password-file ~/.vault_pass

encrypt_string: 単一変数のインライン暗号化 #

変数ファイル全体ではなく 1 つの値だけ を暗号化したいときは encrypt_string を使います。出力として出た暗号文ブロックを平文 YAML ファイルにそのまま貼り付けられます。

encrypt_stringで暗号化
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
# group_vars/db/vars.yml
db_user: appuser
db_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          39613266313764336239...

パスワードを標準入力で受け取らせれば、パイプラインでも使えます。

非対話のencrypt_string
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 ラベル@ソース 形式で複数を同時に渡します。

複数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.cfgvault_password_file に登録するか、オプションで渡します。--ask-vault-pass は対話なので、自動化の要求には合いません。
  • 暗号化対象の分離。秘密は vault.yml に、平文は vars.yml に置き、平文から vault_ 変数を参照する構造が標準です。採点時に秘密が平文で残っていると減点です。
  • 単一の値は encrypt_string。ファイル全体を暗号化するなとか、1 変数だけ隠せという要求には、encrypt_string の出力を平文ファイルにインラインで貼ります。
  • play に vault 変数があればパスワードなしでは失敗ansible-vault view で内容を先に確認し、実行オプションにパスワードの提供が抜けていないか点検します。

まとめ #

この記事で押さえたこと:

  • Ansible Vault は変数ファイルや単一変数を AES256 で暗号化してディスクに安全に保管します。
  • サブコマンド。createeditviewencryptdecryptrekey で暗号化ファイルを扱います。
  • 標準パターン。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 を作成して適用せよ」というタイプまで、直接作りながら整理します。

X