そう気づいた瞬間、ぞっとした経験はないでしょうか。Ansibleはサーバーを自動設定できる便利なツールですが、DBのパスワードやAPIキーをplaybookにベタ書きしてしまうと、Gitにコミットした瞬間に認証情報が漏洩するリスクが生まれます。
この記事では、Ansibleに標準搭載されている Ansible Vault を使って、パスワードや秘密鍵などのシークレット情報を安全に暗号化・管理する方法を解説します。vault-passwordファイルによるパスワードレス実行、変数ファイルの部分暗号化、group_varsとの分離設計、CI/CD連携まで実践的な手順をカバーします。
この記事のポイント
・ansible-vault encrypt でファイルをAES256で丸ごと暗号化してGitに安全にコミットできる
・vault_password_fileで対話入力なし・自動実行が可能になる
・vars.ymlとvault.ymlを分けると変数名を平文で検索しながら値だけ暗号化できる
・vault-idで本番・開発のVaultパスワードを環境ごとに分離できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
Ansible Vaultとは何か
Ansible Vaultは、playbookやインベントリファイルに含まれる機密情報を AES256で暗号化 するAnsible標準機能です。ansible-coreに含まれているので、追加インストールは不要です。「変数ファイルにパスワードを書いてGitにpushしてしまった」という事故は意外と多く発生します。しかも問題は単に「見られる」だけではありません。Gitの履歴に一度でも入ると、ブランチを削除しても
git log や git reflog でたどれてしまいます。GitHubにpushした後でリポジトリをプライベートに変えても、Gitオブジェクト自体は残ります。こうした問題を設計段階で防ぐのがAnsible Vaultです。暗号化の対象は主に次の3種類です。
・変数ファイル全体(vars/secrets.yml を丸ごと暗号化)
・変数の値だけ(
!vault | タグで1変数だけ暗号化)・任意のファイル(SSL証明書の秘密鍵ファイルなど)
よく混同されますが、Vaultはあくまで「保管時の暗号化」です。playbookが実行されるとき、Ansibleはメモリ上でのみ復号します。ディスクには常に暗号化された状態で残ります。
# 動作確認環境 # Control Node: RHEL 9.4 / Rocky Linux 9.4 # Managed Node: Rocky Linux 9.4(SSH接続可能なテスト用VM) # Ansible: ansible-core 2.16.x # 確認コマンド $ ansible --version ansible [core 2.16.9]
基本的な使い方|ファイルを暗号化する
1. 暗号化したいファイルを用意する
まず、DBパスワードなどの秘密情報を変数ファイルにまとめます。# vars/secrets.yml(暗号化前) db_password: "P@ssw0rd!secret" api_key: "sk-xxxxxxxxxxxxxxxxxxxx" smtp_password: "smtpSecret123"
2. ansible-vault encrypt でファイルを暗号化する
$ ansible-vault encrypt vars/secrets.yml New Vault password: Confirm New Vault password: Encryption successful
$ cat vars/secrets.yml $ANSIBLE_VAULT;1.1;AES256 39623163393264653535633630363832356335623564623163396161373766353831303635323665 6662353630336637316236663266626536343834636333370a306163326135393136616166646665 ...(以下省略)...
ansible-vault create を使うとエディタが開いてそのまま書き込めます。3. 暗号化ファイルを使ってplaybookを実行する
暗号化したファイルをplaybookから参照する場合、実行時に--ask-vault-pass または --vault-password-file が必要です。# パスワードを対話入力する場合 $ ansible-playbook -i inventory/hosts site.yml -e @vars/secrets.yml --ask-vault-pass # パスワードファイルを指定する場合(CI/CD向け) $ ansible-playbook -i inventory/hosts site.yml -e @vars/secrets.yml --vault-password-file ~/.vault_pass.txt
vault-password-fileで自動実行する
CI/CDパイプラインや cronからの自動実行では、対話入力ができません。そこで vault-password-file を使ってパスワードをファイルから読み込ませます。1. パスワードファイルを作成する
# パスワードファイルを作成(改行なしで書く) $ echo -n 'YourVaultPassword' > ~/.vault_pass.txt # 権限を本人のみ読み取り可能にする $ chmod 600 ~/.vault_pass.txt # 確認 $ ls -la ~/.vault_pass.txt -rw------- 1 ansible ansible 17 Jun 30 10:00 /home/ansible/.vault_pass.txt
2. ansible.cfg に設定して毎回の指定を省略する
プロジェクトルートのansible.cfg に書いておくと、実行のたびに --vault-password-file を付けなくて済みます。# ansible.cfg [defaults] inventory = inventory/hosts vault_password_file = ~/.vault_pass.txt
# ansible.cfg 設定後はオプションなしで実行できる $ ansible-playbook site.yml -e @vars/secrets.yml PLAY [web servers] ************************************************************ ... PLAY RECAP ************************************************************ 192.168.10.10 : ok=8 changed=3 unreachable=0 failed=0 skipped=0
.vault_pass.txt は絶対に .gitignore に追加してください。パスワードファイル自体がGitに入ってしまうと本末転倒です。# .gitignore に追加必須 ~/.vault_pass.txt .vault_pass.txt
3. GitHub ActionsでVaultパスワードを安全に渡す
GitHub ActionsではリポジトリのSecretsにVaultパスワードを登録し、実行時にファイルに書き出して使います。# .github/workflows/deploy.yml name: Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Ansible run: pip install ansible - name: Write vault password file run: echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > .vault_pass.txt - name: Run Playbook run: | ansible-playbook -i inventory/production site.yml --vault-password-file .vault_pass.txt - name: Remove vault password file if: always() run: rm -f .vault_pass.txt
secrets.ANSIBLE_VAULT_PASSWORD はGitHubのリポジトリ設定(Settings > Secrets and variables > Actions)に登録したシークレットです。パスワードファイルは if: always() で確実に削除します。変数ファイルの一部だけを暗号化する(inline vault)
ファイル全体を暗号化すると「どの変数が何のために使われているか」が分からなくなります。変数名は見せておいて、値だけ暗号化 する方法が!vault タグを使った inline vault です。1. 値だけを暗号化する
# 変数の「値」だけを暗号化(-n で改行なし) $ ansible-vault encrypt_string --stdin-name 'db_password' New Vault password: (入力) Confirm New Vault password: (入力) Reading plaintext input from stdin. (ctrl-d to end input) P@ssw0rd!secret ← 暗号化したい値を入力してCtrl+D db_password: !vault | $ANSIBLE_VAULT;1.1;AES256 38663930303137363666343663376237653233313238316231336137303666656231326430626630 3738323664613831316631336237643363383965313032350a643961333761666362616631633034 ... Encryption successful
2. vars/main.yml に埋め込む
出力されたdb_password: !vault | ブロックをそのまま変数ファイルに貼り付けます。# vars/main.yml(変数名は平文・値だけ暗号化) db_host: "db01.example.com" db_name: "app_production" db_user: "appuser" db_password: !vault | $ANSIBLE_VAULT;1.1;AES256 38663930303137363666343663376237653233313238316231336137303666656231326430626630 3738323664613831316631336237643363383965313032350a643961333761666362616631633034 ...
group_varsとVaultファイルの分離設計(推奨パターン)
変数ファイルを丸ごと暗号化すると、中の変数名をgrep で検索できなくなります。大きなプロジェクトで「この変数はどこで定義されているか」を追いかける際、暗号化ファイルが増えると手間が跳ね上がります。この問題を解消する定番パターンが、変数定義ファイル(vars.yml)と暗号化ファイル(vault.yml)を分ける 設計です。
1. ディレクトリ構成
# group_vars 配下を vars.yml + vault.yml の2ファイルに分ける group_vars/ ├── production/ │ ├── vars.yml # 平文の変数定義(Gitにコミットする) │ └── vault.yml # 暗号化済みの実値(Gitにコミットするが暗号化済み) └── staging/ ├── vars.yml └── vault.yml
2. vars.yml に変数名と参照先を書く
vars.yml には変数の「名前」と「vault変数への参照」だけを平文で書きます。# group_vars/production/vars.yml(平文・grep検索可能) db_host: "db01.example.internal" db_port: 5432 db_user: "appuser" db_password: "{{ vault_db_password }}" # vault.yml の値を参照 api_key: "{{ vault_api_key }}" smtp_password: "{{ vault_smtp_password }}"
3. vault.yml に実値を書いて暗号化する
vault.yml には実際の秘密情報を書き、vault_ プレフィックスを付けた変数名にします。# group_vars/production/vault.yml(暗号化前の平文内容) # このファイルを ansible-vault encrypt で暗号化してからGitにコミットする vault_db_password: "P@ssw0rd_Prod_2024" vault_api_key: "sk-xxxxxxxxxxxxxxxxxxxx" vault_smtp_password: "smtpSecret123"
# vault.yml を暗号化してからコミット $ ansible-vault encrypt group_vars/production/vault.yml New Vault password: Confirm New Vault password: Encryption successful # 暗号化済みを確認してから git add する $ head -1 group_vars/production/vault.yml $ANSIBLE_VAULT;1.1;AES256 ← 先頭行で暗号化済みを確認 $ git add group_vars/production/vault.yml $ git commit -m "Add encrypted production vault variables"
grep "db_password" group_vars/ を実行すれば vars.yml から変数名がすぐ見つかります。実際の値は vault.yml に隔離されているので平文では露出しません。Playbookは db_password という変数名で参照するだけでよく、Vault依存の書き方になりません。roleで使う場合は
vault_ロール名_変数名 のように2段のプレフィックスを付けると、複数roleが並んでいる環境での変数名衝突を防げます。暗号化ファイルの確認・編集
1. ansible-vault view で中身を確認する
# 復号して表示(ファイルは暗号化されたまま) $ ansible-vault view vars/secrets.yml db_password: "P@ssw0rd!secret" api_key: "sk-xxxxxxxxxxxxxxxxxxxx" smtp_password: "smtpSecret123"
2. ansible-vault edit で直接編集する
# デフォルトエディタ($EDITOR)が開く。保存時に自動再暗号化される $ ansible-vault edit vars/secrets.yml # エディタを指定する場合 $ EDITOR=vim ansible-vault edit vars/secrets.yml
3. ansible-vault rekey でパスワードを変更する
Vaultパスワードを定期ローテーションする際に使います。# パスワードを変更する $ ansible-vault rekey vars/secrets.yml Vault password: (現在のパスワード) New Vault password: (新しいパスワード) Confirm New Vault password: Rekey successful
複数Vaultパスワードの使い分け(vault-id)
開発・本番で同じVaultパスワードを使い回していると、開発者が本番のパスワードを知ることになります。--vault-id を使うとVaultファイルに「ラベル」を付けて環境ごとに異なるパスワードで管理できます。Ansible 2.4以降で導入された機能です。# 暗号化時に vault-id を指定 $ ansible-vault encrypt --vault-id dev@~/.vault_dev.txt vars/dev_secrets.yml $ ansible-vault encrypt --vault-id prod@~/.vault_prod.txt vars/prod_secrets.yml # 実行時に両方指定(複数の vault-id を渡せる) $ ansible-playbook site.yml --vault-id dev@~/.vault_dev.txt --vault-id prod@~/.vault_prod.txt
dev@ のパスワードだけ渡し、prod@ のパスワードは運用チームだけが知る、という運用が実現できます。本番環境用パスワードファイルをVaultサーバーやAWS Secrets Managerに保管し、開発用とは分離するパターンがよく使われます。CI/CDパイプラインも実行環境のラベルに対応するパスワードだけを渡せばよくなります。実際のplaybook構成例
Vaultを組み込んだrole構成の典型例を示します。# プロジェクト構成 project/ ├── ansible.cfg ← vault_password_file を設定 ├── inventory/ │ └── hosts ├── group_vars/ │ └── production/ │ ├── vars.yml ← 平文変数(公開可) │ └── vault.yml ← 暗号化(Gitコミット可) ├── vars/ │ └── secrets.yml ← 暗号化(既存構成の場合) ├── roles/ │ └── mysql/ │ ├── tasks/ │ │ └── main.yml │ └── templates/ │ └── my.cnf.j2 └── site.yml
# site.yml --- - name: Configure MySQL server hosts: db_servers vars_files: - group_vars/production/vars.yml - group_vars/production/vault.yml # Vault で暗号化済み roles: - mysql
# roles/mysql/templates/my.cnf.j2 [mysqld] bind-address = 127.0.0.1 # Vault から取得した変数を使用 # ディスクには暗号化済み・メモリ展開時だけ平文 password = {{ db_password }}
トラブルシュート|よくあるエラーと対処
「ERROR! Decryption failed」が出る
Vaultパスワードが間違っているか、パスワードファイルの末尾に余分な改行が入っている場合に発生します。# 改行なしでパスワードファイルを作成し直す $ printf 'YourVaultPassword' > ~/.vault_pass.txt # または $ echo -n 'YourVaultPassword' > ~/.vault_pass.txt # 改行が入っているか確認 $ xxd ~/.vault_pass.txt | tail -3 00000010: 6f72 6400 ord. ← 0a(改行コード)がなければOK
# ファイルがVault形式かどうかは先頭行で確認できる $ head -1 group_vars/production/vault.yml $ANSIBLE_VAULT;1.1;AES256 ← 暗号化済み # vault-id付きで復号できるか確認 $ ansible-vault view --vault-id prod@prompt group_vars/production/vault.yml Vault password (prod): (パスワード入力)
「WARNING: Ansible is in a world writable directory」が出る
ansible.cfgが置かれているディレクトリの権限が777になっていると出るセキュリティ警告です。# ディレクトリ権限を修正 $ chmod 755 /path/to/project
「vault_password_file does not exist」が出る
ansible.cfg に指定したパスのファイルがない状態です。# パスを絶対パスで確認 $ ls -la ~/.vault_pass.txt -rw------- 1 ansible ansible 17 Jun 30 10:00 /home/ansible/.vault_pass.txt # ansible.cfg のパスが正しいか確認 $ grep vault_password_file ansible.cfg vault_password_file = ~/.vault_pass.txt
「ansible.cfg の vault_password_file が効かない」
ansible.cfg の読み込み優先順は「カレントディレクトリ > ~/.ansible.cfg > /etc/ansible/ansible.cfg」です。意図しない設定ファイルが読まれていないか確認します。# どの ansible.cfg が読まれているか確認 $ ansible --version ansible [core 2.16.9] config file = /home/user/projects/ansible/ansible.cfg ← 読まれているファイル ... # ANSIBLE_CONFIG 環境変数で明示的に指定もできる $ export ANSIBLE_CONFIG=/path/to/ansible.cfg
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| ファイルを暗号化 | ansible-vault encrypt vars/secrets.yml |
| 新規暗号化ファイルを作成 | ansible-vault create vars/secrets.yml |
| 値だけを暗号化 | ansible-vault encrypt_string --stdin-name '変数名' |
| 中身を確認(ファイルは暗号化維持) | ansible-vault view vars/secrets.yml |
| 暗号化ファイルを編集 | ansible-vault edit vars/secrets.yml |
| Vaultパスワードを変更 | ansible-vault rekey vars/secrets.yml |
| ファイルを復号(元に戻す) | ansible-vault decrypt vars/secrets.yml |
| パスワードファイルを指定して実行 | ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt |
| 複数Vaultを使い分け | ansible-playbook site.yml --vault-id dev@~/.vault_dev.txt |
ansible-vault encrypt でsecrets.ymlを暗号化するところから始めて、慣れたら group_vars 配下を vars.yml と vault.yml に分ける設計に移行するのがおすすめです。チームが大きくなる前に vault-id で本番・開発を分離しておくと、権限管理が格段に楽になります。Ansibleの基本的なplaybookの書き方や実行方法については、ansible-playbookコマンドの使い方|インベントリ・playbook作成からLinuxサーバー自動化の実践例まで をあわせてご覧ください。
また、構成管理の全体設計については Ansibleのinventory・role・module設計|現場で崩れない構成管理の基礎 も参考にしてください。
Ansible Vaultを使ったシークレット管理を含め、Ansibleの実践スキルを体系的に習得したい方はぜひ詳細をご覧ください。
Ansible実践ハンズオンの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 次のページへ:AnsibleのJinja2テンプレートとhandler設計|設定ファイルの動的生成とサービス自動再起動の仕組み
- 前のページへ:AnsibleとシェルスクリプトSSHループの違い|構成管理に踏み出す判断
- この記事の属するカテゴリ:Ansibleへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます