使用 Ansible 时,使用在 Hashicorp Vault 中存储的机密信息
首先
使用Ansible设置VM实例等时,经常需要处理用户名称和密码、TLS客户端证书、API密钥等机密信息。我们不希望将机密信息与Ansible Playbook一同进行版本控制,也不愿意在执行Ansible时手动准备。在这种背景下,本文将介绍使用Vault模块将存储在Hashicorp Vault中的机密信息在Ansible中使用的方法。
Vault模块是什么?
Vault 模块是由 Ansible 社区维护的第三方模块,使用它可以在 Ansible 执行时从 Vault 中获取机密信息。
安装方法
使用 ansible-galaxy 命令安装 Vault 模块。
$ ansible-galaxy collection install community.hashi_vault
由于Vault模块依赖于名为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
使用范例
在官方文件的示例中介绍了一行代码,但我觉得可维护性不好,所以在这里介绍了改进后的代码,考虑到了维护性。下面的示例是使用令牌作为身份验证方式的,所以请注意在执行主机上已完成vault登录(假设认证令牌已缓存在~/.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
我已经介绍了一个简单的使用示例,但是在官方文档中还介绍了其他各种用例的设定示例,所以我建议您也参考一下官方文档。
填補
在使用 macOS 上的 Vault 模块时,可能会出现以下错误输出。
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.
这是因为 macOS 引起的问题,正如 ansible/ansible#31869 所报告的那样,所以您需要声明以下环境变量作为解决方法,然后重新运行。
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
最后
这次我们介绍了使用 Vault 模块将保存在 Hashicorp Vault 中的机密信息在 Ansible 中使用的方法。Vault 模块非常方便,希望能为在 Ansible 中处理机密信息方面遇到问题的朋友们提供参考。