Ansible:如何在单独的Vault文件中加密清单文件中的某些变量?


69

设定

考虑类似于以下示例的Ansible库存文件

[san_diego]
host1
host2

[san_francisco]
host3
host4

[west_coast]
san_diego
san_francisco

[west_coast:vars]
db_server=foo.example.com
db_host=5432
db_password=top secret password

问题

我想将一些var(如db_password)存储在Ansible保管库中,而不是整个文件。

如何将Vault加密的ansible文件导入未加密的清单文件中?

我尝试过的

我创建了一个加密的vars文件,并尝试通过以下方式导入它:

include: secrets

对此ansible-playbook回应:

ERROR: variables assigned to group must be in key=value form

可能是因为它试图将include语句解析为变量。


Answers:


57

如果您的问题是每个group_hosts都具有未加密和已加密的vars文件。

您可以使用此ansible功能:http : //docs.ansible.com/ansible/playbooks_best_practices.html#best-practices-for-variables-and-vaults

group_vars/ 
  san_diego/
    vars.yml  # unencrypted yaml file
    vault.yml # encrypted yaml file

Ansible将自动将vault.yml读取为加密的yaml文件。

更新:该解决方案如下也是很好的解决方案(因为Ansible 2.3)


意味着san_diego是目录而不是文件?
亚当·马坦

2
确实,您可以使用san_diego.yml或san_diego / vars.yml,这是相同的。
Antoine

您正在寻找这个答案!@AdamMatan请标记为正确。
拉兹

最佳实践建议不要使用后缀命名文件vars和。无论如何,b / c似乎是奇怪的,它是一个加密文件而不是YAML文件。vault.ymlvault.yml
kkurian

1
我认为这是比以下解决方案更好的解决方案,因为文件级加密更容易进行密钥轮换。在所有情况下,请了解文件级加密与可变级加密的优缺点,并明智地选择。
disklosr

105

从Ansible 2.3开始,您可以加密单个加密变量。IMO,由于Doco看起来很简洁,因此需要进行演练。

给出以下示例:(mysql_password: password123在main.yml中)

运行以下命令:

ansible-vault encrypt_string password123 --ask-vault-pass

这将产生:

    !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653236336462626566653063336164663966303231363934653561363964363833
3136626431626536303530376336343832656537303632313433360a626438346336353331
Encryption successful

将此粘贴到您的main.yml中:

mysql_password: !vault |
    $ANSIBLE_VAULT;1.1;AES256
    66386439653236336462626566653063336164663966303231363934653561363964363833
    3136626431626536303530376336343832656537303632313433360a626438346336353331

运行剧本:

ansible-playbook -i hosts main.yml --ask-vault-pass

通过调试验证:

- debug:
    msg: "mysql Pwd: {{ mysql_password }}"

7
截至2018年8月,这应被视为上述问题的正确答案。
ncrmro

2
有没有一种方法可以立即解密所有保管库值,而不必复制/粘贴每个加密的字符串并执行相反的crypto_string?
乔J

那是什么类型的格式?那是换行符吗?有关系吗?
jouell

@jouell是的,这些只是换行符,带有缩进空间。但这似乎无关紧要。我想
Yaml会

当剧本投入git时,此解决方案是否运作良好?
Martin Bjeldbak Madsen

15

目前,使用Ansible 2.3可以使用简单的Yaml同时包含加密和未加密的变量。加密的变量的格式如下:

dbServer: PlainDatabaseServer
dbName: PlainDatabaseName
dbUser: PlainUser
dbPasswd: !vault |
      $ANSIBLE_VAULT;1.1;AES256
      63633363616165656538656537323835343634633063386137353637646663333939623464666437
      6263383933656635316436313934366564316337623435350a386362613838373363393534383232
      39663162363066313431623466363763356466376538613532333731613538373431623239626330
      6463373238366630360a623566616535376339326431363465663431623462356238636333306663
      6439

您可以使用带有以下语句的密码或密码文件来加密变量:

ansible-vault encrypt_string "dummy" --vault-password-file pass-ansible.txt

该语句返回上述yaml中dbPasswd变量中显示的文本。

要运行使用加密变量的剧本,只需添加以下变量:

 ansible-playbook playbooks/myplaybook --vault-password-file pass-ansible.txt

或者,您也可以使用--ask-vault-pass进行相同操作,在执行剧本时要求您输入密码:

ansible-playbook playbooks/myplaybook --ask-vault-pass

1
我认为您还应该提到--ask-vault-pass,而不仅仅是--vault-password-file
ympostor

是的,您是对的,谢谢!我们只使用--vault-password-file,因为我们以自动方式与Jenkins一起运行剧本,并且使用带有密码的文件而不是通过管道或提示传递密码,对我们来说更简单。我将您的选项添加到帖子中。
V. Morate

感谢您实际回答问题!
Tobias '18

感谢您的解决方案!我不知道这是一个选择。我多挖了一点,阅读后用了。这是我之后写的一篇稍微冗长的博客文章,以防万一有人想要一个更完整的示例,而对于SO-> coding-stream-of-ogniness.com/2019/05/08/…来说太冗长了。
约翰·汉弗莱斯

5

您可以执行类似的操作。

  1. 创建密码文件(纯文本文件,密码在一行上)
  2. ansible.cfg在您的ansible项目文件夹中创建一个

    [defaults]
    vault_password_file = <path/to/your/password/file>
    
  3. 创建一个剧本文件(例如playbook.yml

     - name: my ansible playbook
       hosts: 127.0.0.1
       vars_files:
         - 'vars.yml'
       tasks:
         - name: print secure variable
           debug: msg="my secure variable '{{ my_secure_variable }}'"`
    
  4. 创建一个变量文件(例如vars.yml

    my_secure_variable: "X_my_secret_X"
    
  5. 加密变量文件(使用,从ansible项目位置进行加密ansible.cfg

    ansible-vault encrypt vars.yml
    
  6. 运行您的剧本(使用,从ansible项目位置开始ansible.cfg

    ansible-playbook -i "localhost," playbook.yml
    

您应该获得类似于以下内容的输出:

$ ansible-playbook playbook.yml -i 'localhost,'

PLAY [my ansible playbook] ****************************************************

GATHERING FACTS ***************************************************************

ok: [127.0.0.1]

TASK: [print secure variable] *************************************************

ok: [127.0.0.1] => {
    "msg": "my secure variable 'X_my_secret_X' "
}

PLAY RECAP ********************************************************************

127.0.0.1                  : ok=2    changed=0    unreachable=0    failed=0

非加密变量存储在哪里?
亚当·马坦

Ansible在变量位置和优先顺序方面相当灵活。请参阅docs.ansible.com/…。如果我们在前面的示例中进行扩展,我们可以(但不限于)执行以下操作: - name: my ansible playbook hosts: 127.0.0.1 vars_files: - 'vars.yml' - 'insecure.yml' - ... 其中insecure.yml是另一个yaml文件,其中的vars尚未被存储。您也可以使用vars:关键字将vars直接嵌入到剧本中。
奶奶

2
换句话说,这不能回答“如何加密某些变量”的问题。
罗宾·多尔蒂

@RobinDaugherty,您是否有一些见识可以帮助您阐明自己的观点?否则,为了响应您的陈述,请将键/值对放在您要“存储”的明文文件中。当您运行Ansible Vault时,它将文件转换为加密的密钥存储。有关更多信息,请在此处进行RTFM:docs.ansible.com/ansible/latest/user_guide/…。拱顶后,您可以像访问其他任何变量一样访问该变量,但是在静止状态下,该变量已加密。
奶奶

4

这取决于您的工作流程。您可以group_vars按照Sebastian Stigler的建议使用文件,或者如果您想使用清单文件,则可以在清单目录中添加另一个“类似ini的”文件并对其进行加密。

$ mkdir my_inventory/
$ cat >> hosts << EOF
[san_diego]
host1
host2

[san_francisco]
host3
host4

[west_coast]
san_diego
san_francisco
EOF

$ cat >> inventory_crypted_vars << EOF
[west_coast:vars]
db_server=foo.example.com
db_host=5432
db_password=top secret password
EOF

然后,-i my_inventory/在命令行中使用,或创建一个ansible.cfg包含以下内容的本地:

[defaults]
hostfile = ./my_inventory/

并且你应该被设置。Ansible将在运行时合并两个文件。

采用 ansible-vault encrypt my_inventory/inventory_crypted_vars提交之前便大功告成。

您可能需要一个预提交钩子,以确保您未提交该文件的未加密版本。例如,像这样的预提交钩子就可以解决问题(相应地进行调整FILES_PATTERN)。


0

您可以使用group_vars(请参阅http://docs.ansible.com/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable)。

在您的剧本中创建一个名为的子目录group_vars。在此处
创建一个名为的文件west_coast,并将以下条目放入其中:

---
db_server: foo.example.com
db_host: 5432
db_password: top secret password

然后可以将此文件转换为ansible保管库。


这种方法的问题在于,既不能从其他剧本访问变量,也不能在使用-i参数指定另一个清单文件时更改变量。
亚当·马坦

您还可以将此文件放到全局配置目录中,/etc/ansible/group_vars而不是./group_vars放在剧本中的目录中(请参阅我的答案中的链接)。
塞巴斯蒂安·斯蒂格勒

无法回答文件中某些var被加密而另一些未加密的问题。
ntwrkguru

如果您阅读了所有其他答案,您将看到,不可能在单个文件中执行此操作。
塞巴斯蒂安·斯蒂格勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.