【问题标题】:Ansible: How to encrypt some variables in an inventory file in a separate vault file?Ansible:如何在单独的 Vault 文件中加密库存文件中的一些变量?
【发布时间】:2015-05-13 08:04:06
【问题描述】:

设置

考虑一个类似于以下示例的Ansible inventory file

[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

问题

我想将一些变量(如 db_password)存储在 Ansible vault 中,但不是整个文件。

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

我尝试过的

我创建了一个加密的 vars 文件并尝试将其导入:

include: secrets

ansible-playbook 回复:

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

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

【问题讨论】:

标签: encryption ansible ansible-playbook ansible-vault


【解决方案1】:

从 Ansible 2.3 开始,您可以加密 Single Encrypted Variable。 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 }}"

【讨论】:

  • 截至 2018 年 8 月,这应被视为上述问题的正确答案。
  • 有没有一种方法可以一次解密所有保险库值,而无需复制/粘贴每个加密字符串并运行 encrypt_string 的反向操作?
  • 那是什么类型的格式?那是换行符吗?有关系吗?
  • @jouell 是的,这些只是带有空格的缩进换行符。但似乎无所谓。我猜 yaml 支持什么
  • playbook 提交到 git 时,这个解决方案是否有效?
【解决方案2】:

如果您的问题是每个 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 文件。

更新:below 的解决方案也是很好的解决方案(从 Ansible 2.3 开始)

【讨论】:

  • 意思是san_diego是一个目录,而不是一个文件?
  • 没错,你可以使用san_diego.yml或者san_diego/vars.yml,都是一样的。
  • 您正在寻找这个答案! @AdamMatan 请将其标记为正确。
  • 站点最佳实践建议将文件命名为varsvault,不带.yml 后缀。无论如何vault.yml 看起来很奇怪,因为它是一个加密文件而不是 YAML 文件。
  • 我认为这是一个比下面的解决方案更好的解决方案,因为文件级加密更容易实现密钥轮换。在所有情况下,了解文件级加密与可变级加密的优缺点并明智地选择。
【解决方案3】:

此时使用 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 执行相同的操作,它会在执行 playbook 时询问您的密码:

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

【讨论】:

  • 我认为你也应该提到--ask-vault-pass,而不仅仅是--vault-password-file
  • 是的,你是对的,谢谢!我们只使用 --vault-password-file 因为我们使用 Jenkins 以自动方式运行 playbook,并且使用带有密码的文件而不是通过管道或提示传递密码更简单。我将您的选项添加到帖子中。
  • 感谢您实际回答问题!
  • 感谢您的解决方案!我不知道这是一个选择。我又挖了一点,读完后用了这个。这是我后来写的稍微详细一点的博客文章,以防有人想要一个更完整的例子,对于 SO -> coding-stream-of-consciousness.com/2019/05/08/….
【解决方案4】:

你可以做类似的事情。

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

    [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.cfg的ansible项目位置)

    ansible-vault encrypt vars.yml
    
  6. 运行您的剧本(从带有 ansible.cfg 的 ansible 项目位置)

    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 根本没有被 vaulted。您也可以使用 vars: 关键字直接在 playbook 中嵌入 var。
  • 换句话说,这并没有回答“如何加密一些变量”的问题。
  • @RobinDaugherty 你有什么见解可以帮助澄清你的陈述吗?否则,为了响应您的声明,您将键/值对放在您希望“保管”的明文文件中。当您运行 Ansible 保险库时,它会将该文件转换为加密的密钥存储。更多信息,也许是 RTFM:docs.ansible.com/ansible/latest/user_guide/…。存储后,您可以像访问其他任何变量一样访问该变量,但在静止时它是加密的。
【解决方案5】:

这取决于您的工作流程。您可以按照 Sebastian Stigler 的建议使用 group_vars 文件,或者如果您想使用库存文件,您可以在库存目录中添加另一个“类似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 就可以了。

您可能需要一个预提交挂钩来确保您不会提交文件的未加密版本。例如a pre-commit hook like this 就可以解决问题(相应地调整FILES_PATTERN)。

【讨论】:

    【解决方案6】:

    您可以使用 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 Vault。

    【讨论】:

    • 这种方法的问题在于,变量既不能从其他剧本访问,也不能在使用-i 参数指定另一个库存文件时更改。
    • 你也可以把这个文件放到全局配置目录/etc/ansible/group_vars,而不是playbook里的./group_vars目录(见我回答中的链接)。
    • 不回答文件中的一些变量被加密而一些没有被加密的问题。
    • 如果您阅读了您可以看到的所有其他答案,则不可能在单个文件中执行此操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    • 2019-02-09
    • 2019-01-02
    相关资源
    最近更新 更多