LoginSignup
2
2

More than 1 year has passed since last update.

Hashicorp Vault に保存した機密情報を Ansible で使用する

Last updated at Posted at 2021-07-29

はじめに

Ansible を使用して VM インスタンスなどをセットアップする際に、ユーザー名とパスワード、TLS クライアント証明書、API キーなどの機密情報を扱うケースは多くあるかと思います。機密情報を Ansible Playbook と一緒にバージョン管理することは避けたいですし、Ansible 実行時に手動で用意するのも面倒です。このような背景を受けて、この記事では Vault Module を使用して Hashicorp Vault に保存した機密情報を Ansible で使用する方法を紹介します。

Vault Module とは

Vault Module は Ansible コミュニティでメンテナンスされているサードパーティー製の Module で、こちらを使用することで Ansible 実行時に Vault から機密情報を取得することができます。

インストール方法

ansible-galaxy コマンドで Vault Module をインストールします。

$ ansible-galaxy collection install community.hashi_vault

Vault Module は hvac という Python ライブラリに依存しているので、そちらもインストールします。

# Ansible が使用する Python インタープリターを特定
$ ansible -m debug -a 'var=ansible_python_interpreter' localhost
[WARNING]: No inventory was parsed, only implicit localhost is available
localhost | SUCCESS => {
    "ansible_python_interpreter": "/usr/local/Cellar/ansible/4.0.0/libexec/bin/python3.9"
}

# 使用される Python インタープリターで hvac をインストール
$ /usr/local/Cellar/ansible/4.0.0/libexec/bin/python3.9 -m pip install hvac

使用例

公式ドキュメントの例ではワンライナーなものが紹介されていますが、メンテナンス性が悪いと感じたので、ここではメンテナンス性を考慮して改良したものを紹介しています。以下の例は、認証方式として Token を使用するものになっているので、実行ホストで vault login が完了している前提(Token Helper により ~/.vault-token に認証トークンがキャッシュされている)となることに注意してください。

- name: read secrets from vault
  set_fact:
    mysql_root_password: >-
      {{ lookup(
        'community.hashi_vault.hashi_vault',
        ' url=' + vault_addr +
        ' ca_cert=' + vault_cacert +
        ' secret=/path/to/mysql-secrets:root-password'
      ) }}
    client_cert: >-
      {{ lookup(
        'community.hashi_vault.hashi_vault',
        ' url=' + vault_addr +
        ' ca_cert=' + vault_cacert +
        ' secret=/path/to/tls-client-secrets:client.pem'
      ) }}
    client_key: >-
      {{ lookup(
        'community.hashi_vault.hashi_vault',
        ' url=' + vault_addr +
        ' ca_cert=' + vault_cacert +
        ' secret=/path/to/tls-client-secrets:client-key.pem'
      ) }}
  vars:
    vault_addr: https://your-vault:8200
    vault_cacert: /path/to/cacert.pem

上記のタスクで Vault から取得した機密情報は以下のように使用できます。

# ファイル内の文字列として使用する場合はテンプレートファイル内で {{ mysql_root_password }} を定義すること
- name: copy configuration file
  template:
    src: templates/server.conf
    dest: /path/to/server.conf

# ファイルとして使用する場合は Copy Module の content パラメーターを使用すること
- name: copy client cert
  copy:
    content: "{{ client_cert }}"
    dest: /path/to/client.pem

- name: copy client key
  copy:
    content: "{{ client_key }}"
    dest: /path/to/client-key.pem

使用例としてシンプルなものを紹介しましたが、公式ドキュメントでは他にも様々なユースケース毎の設定例が紹介されていますので、そちらも併せて参照するのが良いかと思います。

補足

Vault Module を macOS で使用する際に以下のエラーが出力されることがあります。

objc[43838]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[43838]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.

これは ansible/ansible#31869 で報告されているとおり macOS 起因の問題なので、ワークアラウンドとして紹介されている以下の環境変数を宣言して再実行する必要があります。

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

さいごに

今回は Vault Module を使用して Hashicorp Vault に保存した機密情報を Ansible で使用する方法を紹介しました。Vault Module はとても便利なので、Ansible での機密情報の扱いに課題を抱えている方々の参考になれば幸いです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2