はじめに
前回の記事で、HashiCorp Vault の kv シークレットエンジンを使ってシークレットの登録をしました。
今回は、そのシークレットを Ansible から取得して表示したり、機器への接続パスワードに利用することを試します。
Ansible の community.hashi_vault.hashi_vault
ルックアッププラグインを利用します。
少し紛らわしいかもしれませんが、Ansible Vaultとは直接は関係ありません。
- 環境
- Vault v1.10.0
- ansible 5.6.0 (ansible-core 2.12.4)
community.hashi_vault
コレクション 2.4.0
hashi_vault
ルックアッププラグインは、もともとは community.general
コレクションにありましたが、2.0.0 で削除されました
Vault 側の準備
Ansible の前にまず Vault 側の準備です。
vault -dev
でサーバーを起動済みの状態から始めます。今回は Vault サーバーもAnsible も同じサーバーという構成です。
シークレットの確認
前回からのおさらいになりますが secret/mypassword
の中に password
というキーで、パスワード p@ssw0rd
が登録されています。これを後で Ansible から取得します。
$ vault kv get secret/mypassword
===== Secret Path =====
secret/data/mypassword
======= Metadata =======
Key Value
--- -----
created_time 2022-04-07T13:34:41.03484313Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
====== Data ======
Key Value
--- -----
password p@ssw0rd
ポリシーの追加
シークレットの読み込みだけできるポリシーを追加します。ここでは read-secret
という名前にします。
$ vault policy write read-secret - << EOF
path "secret/data/*" {
capabilities = ["read"]
}
EOF
Success! Uploaded policy: read-secret
ポリシーのリストを確認すると read-secret
が表示されます。
$ vault policy list
default
read-secret
root
内容も確認します。意図通りになっています。
$ vault policy read read-secret
path "secret/data/*" {
capabilities = ["read"]
}
参考
Policies | Vault | HashiCorp Developer
先ほど作成したポリシー read-secret
に対するトークンを生成します。
$ vault token create -policy=read-secret
Key Value
--- -----
token hvs.dummyyyyyyyyyy
token_duration 768h
token_renewable true
token_policies ["default" "read-secret"]
identity_policies []
policies ["default" "read-secret"]
ここではダミーの値に伏せていますが、token
に表示された値を後で使います。
参考
Authentication | Vault | HashiCorp Developer
Vault 側の準備はここまでです。
Ansible 側の準備
今度は Ansible 側の準備です。
hvac のインストール
ドキュメントの Requirementsにあるとおり、HashiCorp Vault API クライアントのPython パッケージ hvac
が必要です。コントロールノード(Ansibleをインストールしたノード)に pip でインストールします。
pip install hvac
お試し1: 取得したシークレットを表示する
実用性はありませんが、とりあえず確認のため、取得したシークレットを表示するだけの Playbook を作成します。
---
- hosts: localhost
gather_facts: false
tasks:
- name: debug vault secret
debug:
msg: "{{ lookup('community.hashi_vault.hashi_vault', 'secret=secret/data/mypassword:password') }}"
secret
のところで、取得したいシークレットのパスを指定します。password
の値がほしいので、 :password
も含めて指定します。
この他の代表的な設定要素として Vault サーバーへの接続先URLとトークンがあります。これらをルックアッププラグイン呼び出しのオプションで指定すると、複数箇所で呼び出すとき場合に毎回指定が必要になり冗長です。そのため、今回はURLとトークンは環境変数で指定します。トークンには Vault 側の準備で read-secret
ポリシーに対して生成したものを指定します。
$ export ANSIBLE_HASHI_VAULT_TOKEN=hvs.dummyyyyyyyyyy
$ export ANSIBLE_HASHI_VAULT_ADDR=http://localhost:8200
なお、環境変数以外にはファイルに記載しておく方法もあります。詳細は、community.hashi_vault.hashi_vault
ルックアッププラグインのドキュメントの url
と token
を参照してください。
Playbook 実行
Playbook を実行します。
$ ansible-playbook -i localhost, debug_vault.yml
PLAY [localhost] ****************************************************************************************************
TASK [debug vault secret] *******************************************************************************************
ok: [localhost] => {
"msg": "p@ssw0rd"
}
PLAY RECAP **********************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
p@ssw0rd
が表示できたため、無事に Vault からシークレットを取得できたことが確認できました。
お試し2: 取得したシークレットを機器接続パスワードとして利用する。
今度は少し実用的な例です。(URLとトークンの環境変数は設定したままです)
Vault のシークレットから取得した値を、Cisco IOS への接続パスワードとして利用します。
インベントリファイルに ios
というグループの定義がされている状態で、group_vars/ios.yml
に以下のように定義します。
---
ansible_network_os: cisco.ios.ios
ansible_connection: ansible.netcommon.network_cli
ansible_user: admin
ansible_password: "{{ lookup('community.hashi_vault.hashi_vault', 'secret=secret/data/mypassword:password') }}"
ansible_password
変数に対して、Vault から取得した値を利用するように指定します。
Playbook 自体は以下のものを利用します。無事に接続、認証できたことを確認できればいいので、show コマンドを実行して表示するだけです。
---
- hosts: ios
gather_facts: false
tasks:
- name: exec show commands
cisco.ios.ios_command:
commands:
- show running-config
register: res_show_commands
- name: debug show commands
ansible.builtin.debug:
msg: "{{ res_show_commands.stdout_lines[0] }}"
Playbook を実行します。
$ ansible-playbook -i inventory ios_show.yml
PLAY [ios] **********************************************************************************************************
TASK [exec show commands] *******************************************************************************************
ok: [ios01]
TASK [debug show commands] ******************************************************************************************
ok: [ios01] => {
"msg": [
"Building configuration...",
"",
" ",
"Current configuration : 4076 bytes",
"!",
"! Last configuration change at 10:07:41 UTC Wed Apr 6 2022",
"!",
"version 15.9",
...(略)...
PLAY RECAP **********************************************************************************************************
ios01 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
無事に Playbook を実行できます。
おわりに
お試しレベルですが、Ansible から HashiCorp Vault のシークレットの値を取得する動作を確認しました。
簡単に連携できたなと思いました。