背景


我们使用Ansible来配置和管理Azure基础结构。目前,我们“手动”运行Ansible,即我们手动执行各种自动化任务的剧本。没有CI基础结构。
可能不相关,但是我们使用动态脚本azure_rm.py管理库存。
我们建议尽可能安全,即


不要将保险柜密码存储在~/.vault_pass或任何本地文件中
不要将Azure机密存储在~/.azure/credentials

不要在.bashrc中存储任何安全的内容。



在这种情况下,我很难提出一个连贯的策略来确保我的剧本可以在遵循上述准则的同时访问Azure机密。

问题

如何避免在文件上存储Ansible Vault和Azure凭据,同时又确保我的剧本可以访问它们?

我已经尝试过什么

到目前为止,我已经提出了一个包装器脚本,该包装器脚本


向用户询问保险柜密码
使用该脚本来解密Vaulted Shell脚本
求值该脚本,该脚本加载Azure环境变量进入环境;
在环境中运行剧本

那里有更好的解决方案(更优雅,更简单,更“ Ansible”)吗?

评论

在此工作流程中,最让您困扰的是什么?

@KonstantinSuvorov主要是要达到(至少对我而言)在合规性较高的企业中相当普遍的要求,我需要跳的圈数。

#1 楼

保管库密码

首先,您应该熟悉保管库密码文件可以是可执行脚本的事实。在这种情况下,Ansible将执行它并期望接收密码作为其输出。例如,您可以使用gpg-agentkeychain来存储您的实际密码,并在需要时将其解锁。在此博客文章中了解更多信息:https://benincosa.com/?p=3235

如果您有点偏执,可以在调用密码脚本时添加通知,如下所示:

#!/bin/bash
PARENT_PROCESS=$(ps -p $PPID -o args | tail -n 1)
osascript -e "display notification \"Vault password used by ${PARENT_PROCESS}\" with title \"Ansible\" sound name \"default\""
gpg --batch --use-agent --no-tty --decrypt key.gpg 2>/dev/null


此文件库密码脚本使用key.gpg作为实际文件库密钥,并且在使用脚本时还显示带有父进程名称的弹出通知(对于MacOS)。 Gpg-agent会缓存解锁密码一段时间,因此您无需在每次启动剧本时都输入密码。

只需在vault_password_file = ./vault_pass.sh中设置ansible.cfg即可。

环境

您说过您将azure_rm.py用作动态清单脚本。这意味着您必须先为环境变量设置凭据,然后才能启动ansible-playbook,以便它可以使用它们。您可以制作两个文件:

secure_env (使用保管库加密):

export AZURE_SECRET=xxx;export AZURE_SUBSCRIPTION_ID=xxx;


set_env(纯文本):

echo -n "Setting secure vars... "
eval $(ansible-vault view secure_env)
echo "done."


当您打开新的终端以执行自动化任务,您必须运行: 此时,bash评估set_envsecure_env(通过ansible-vault解密)。执行此命令后,您已为当前外壳定义了Azure凭据,因此您可以照常执行剧本:

source set_env


因此,使用这两种方法,可以存储key.gpgsecure_env在您的存储库中;然后在新终端中调用source set_env一次,输入一次gpg密码(以解锁将来对key.gpg的使用);然后根据需要多次拨打ansible-playbook,无需输入任何密码。

评论


感谢您的答复。让我在一周内尝试一下。

–Vish
18年4月8日在4:15

因此,与我原来的方法相比,主要优点是它使用GPG-带来了缓存优势-对吗?环境方法与我想到的方法类似。

–Vish
18年4月10日在4:59

从您的OP中了解到,每次运行剧本时都使用包装器。使用源方法,您可以在每个终端会话中设置一次环境,并且可以分别使用所有工具:ansible-playbook,清单脚本,azure cli,而没有任何包装。

–康斯坦丁·苏沃洛夫(Konstantin Suvorov)
18年4月10日在5:52

嗯,明白了。不好意思把这个交给我的团队。接受您的答复是更方便的解决方案。感谢您的研究和解释!另外,我喜欢您的博客:)

–Vish
18年4月11日,1:12

使用GPG(或macOS或Linux上的钥匙串)的主要好处是,每个团队成员都有自己的身份验证来解锁他们唯一的私钥。然后,此密钥用于解锁Ansible Vault密码,这是一个共享密钥。如果有人仍然离开团队,则必须旋转所有秘密,包括Ansible Vault密码,但至少GPG /钥匙串密码不必更改。

– RichVel
19年1月30日在7:18

#2 楼

请阅读https://docs.ansible.com/ansible/2.4/vault.html
,因为Ansible 2.4可以使用--vault-id @prompt

使用ansible-vault加密文件:

ansible-vault encrypt /path/to/encrypted/file


运行剧本,结果将是:

fatal: [localhost]: FAILED! => {"msg": "A vault password or secret must be
specified to decrypt /path/to/encrypted/file"}


有多个选项可以解密文件,包括@prompt

ansible-playbook some-playbook --vault-id @prompt


会提示:

Vault password (default):


输入保险库密码后,剧本应该会成功。

评论


阅读页面看起来确实有一个解决方案,但是无法仅使用链接就知道了。您能详细说明一下吗?

–Vish
18年4月6日在1:24

谢谢您的阐述。我确实需要使用较旧的--ask-vault-pass选项,要求用户提供保险库密码。而且我不明白用--vault-id替换它会如何回答更好的工作流程这个更大的问题。

–Vish
18年4月7日在3:44

当您向我介绍链接时,我确实看到了一个有趣的选项:ansible-playbook --vault-id my-vault-password.py。我以为您可能在使用python脚本方面有解决方案:)我也在对此进行一些思考。

–Vish
18-4-7在3:45