我的目标是使用具有多个 ID 的
ansible-vault
(例如 dev
和 prod
)并从 macOS 钥匙串检索正确的密码(对于 dev
或 prod
)。
我尝试了很多配置组合,但最有希望的似乎是我在这里描述的。不幸的是,就像我尝试过的其他所有方法一样,这不起作用。
我有一个名为
vault-keyring-client.py
的脚本,从 Github 获取,它是可执行的并存储为 ~/.vault/vault-keyring-client.py
。
此外,我将环境变量
ANSIBLE_VAULT_PASSWORD_FILE
设置为这个完整路径。
macOS 钥匙串包含两个“通用密码”条目,一个用于
dev
,另一个用于 prod
。
现在,我希望以下命令能够工作,这意味着输出通过
STDIN
输入的任何内容的加密字符串:
ansible-vault encrypt_string --vault-id dev
我也尝试过非常相似的命令
ansible-vault encrypt_string --vault-id dev --encrypt-vault-id dev
更清楚地表明我正在尝试做什么;结果是一样的:
我收到错误声明
vault-keyring-client could not find key="default" for user="<my-username>" via backend="macOS Keyring"
根据我的理解
ansible-vault
应该调用提到的脚本(因为它是在ANSIBLE_VAULT_PASSWORD_FILE
中设置的)并向其传递参数--vault-id dev
(因为这是我在CLI上给它的)。这样,脚本应该返回它在钥匙串中找到的密码。
所以我的问题是: 当我明确表示我想要
ansible-vault
时,为什么default
要在钥匙串中寻找名为dev
的密钥(密码)?
更完整的输出/错误如下所示:
[WARNING]: Error getting vault password file (None): The vault password file <cwd>/mgm/dev was not found
[WARNING]: Error in vault password file loading (default): Vault password client script ~/.vault/vault-keyring-client.py did not find a secret for vault-id=default: b'vault-keyring-client could not find key="default" for user="<my-username>" via backend="macOS Keyring"\n'
ERROR! Vault password client script ~/.vault/vault-keyring-client.py did not find a secret for vault-id=default: b'vault-keyring-client could not find key="default" for user="<my-username>" via backend="macOS Keyring"\n'
ansible-vault
似乎正在当前工作目录中寻找名为 dev
的(密码)文件(并正确检测到该文件不存在),但随后停止尊重 dev
ID 并继续寻找名为 的内容default
...
我知道并非所有希望都破灭了,因为以下命令实际上确实有效:
ansible-vault encrypt_string --vault-id dev@~/.vault/vault-keyring-client.py
打字只是拗口,我不明白为什么这会产生影响......
顺便说一句:我正在使用 ansible 版本
2.14.5
。
你的问题是你使用的是环境变量
ANSIBLE_VAULT_PASSWORD_FILE
,它声明了一个默认密码(不使用vault-id来表示这么快......),而不是ANSIBLE_VAULT_IDENTITY_LIST
,它是专门用于使用多个ID的.
只需取消先前的设置并将最新的设置为正确的 ID 列表及其各自的密码文件即可。由于您使用的是脚本,因此它将接收 ID 并能够使用正确的密码进行回复。所以你基本上为每个 id 使用相同的文件:
unset ANSIBLE_VAULT_PASSWORD_FILE
export ANSIBLE_VAULT_IDENTITY_LIST="dev@${HOME}/.vault/vault-keyring-client.py,\
staging@${HOME}/.vault/vault-keyring-client.py,\
prod@${HOME}/.vault/vault-keyring-client.py"
我之前使用过
vault-keyring-client.py
脚本,并且发现很烦人,因为我必须位于项目的根目录才能使其工作。
自从项目起源以来,我编写了这个包,它也可以在 PyPI 上使用
https://github.com/jakob1379/vault-keyring-client
这使得合并脚本的过程更加简单。
引用指南:
该脚本旨在与 Ansible 配合使用,无需为每个主机手动输入
become_pass
,从而使您的剧本更加高效。请按照以下步骤进行设置:
创建条目: 首先,使用
vault-keyring-client --set --vault-id my_vault_id
创建一个条目。
配置 Ansible: 要使 Ansible 自动尝试存储在密钥环中的密码,请将以下内容添加到您的
.envrc
或手动获取您的 .env
文件:
export ANSIBLE_VAULT_IDENTITY_LIST="my_vault_id@$(poetry run which vault-keyring-client),my_other_vault_id@$(poetry run which vault-keyring-client)"
创建安全保管库: 在存储库外部创建一个保管库文件以避免意外提交。将其存放在安全的位置,例如,
~/.become_passwords
。将键值对构造为 become_pass_<hostname>: "mytopsecret_host_password"
。使用以下方法加密文件:
ansible-vault encrypt --encrypt-vault-id my_vault_id <path_to_vault>
更新剧本: 将以下配置添加到您的 playbook 以使用存储的密码:
- name: Playbook that does not require manual sudo passwords
hosts: amazing_host
become: true
vars:
ansible_become_password: "{{ lookup('vars', 'become_pass_' + inventory_hostname) }}"
vars_files:
- ~/.become_passwords.yml
roles:
- users
当您运行剧本时,Ansible 将按顺序尝试
VAULT_IDENTITY_LIST
中的所有密钥,并使用正确的密钥解锁 ~/.become_passwords
,将密码与主机名匹配。