Ansible:如何在单独的保险库文件中加密库存文件中的某些变量?

时间:2021-08-23 18:25:53

The settings

Consider an Ansible inventory file similar to the following example:

考虑类似于以下示例的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

The problem

I would like to store some of the vars (like db_password) in an Ansible vault, but not the entire file.

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

How can a vault-encrypted ansible file be imported into an unencrypted inventory file?

如何将保险库加密的ansible文件导入未加密的库存文件?

What I've tried

I have created an encrypted vars file and tried importing it with:

我创建了一个加密的vars文件,并尝试使用以下命令导入它:

include: secrets

To which ansible-playbook responded with:

ansible-playbook回复:

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

Probably because it tried to parse the include statement as a variable.

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

6 个解决方案

#1


If your issue is to have both unencrypted and encrypted vars files per group_hosts.

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

You can use this ansible feature : http://docs.ansible.com/ansible/playbooks_best_practices.html#best-practices-for-variables-and-vaults

您可以使用此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 will read automatically vault.yml as encrypted yaml file.

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

Update : The solution below is also good solution (since Ansible 2.3)

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

#2


Since Ansible 2.3 you can encrypt a Single Encrypted Variable. IMO, a walkthrough is needed as the doco's seem pretty terse.

从Ansible 2.3开始,您可以加密单个加密变量。 IMO,需要一个演练,因为doco看起来很简洁。

Given an example of: mysql_password: password123 (within main.yml)

给出一个例子:mysql_password:password123(在main.yml中)

Run a command such as:

运行如下命令:

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

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

This will produce:

这将产生:

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

paste this into your main.yml:

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

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

run playbook:

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

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

Verify via debug:

通过调试验证:

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

#3


At this time with Ansible 2.3 it's possible to have in a plain yaml both encrypted and unencrypted variables. The format of the variables encrypted is like this:

在Ansible 2.3的这个时候,可以在一个简单的yaml中包含加密和未加密的变量。加密变量的格式如下:

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

You can encrypt the variable using a password or a password file with the statement:

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

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

This statement returns the text shown in dbPasswd variable in the yaml above.

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

To run a playbook that uses the encrypted variable just add the following var:

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

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

Or you can do the same with --ask-vault-pass which ask you for the password when executing the playbook:

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

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

#4


You can do something similar to this.

你可以做类似的事情。

  1. Create a password file (a plain text file with your password on a single line)
  2. 创建一个密码文件(一行包含您的密码的纯文本文件)

  3. Create an ansible.cfg in your ansible project folder

    在ansible项目文件夹中创建一个ansible.cfg

    [defaults]
    vault_password_file = <path/to/your/password/file>
    
  4. Create a playbook file (e.g. playbook.yml)

    创建一个剧本文件(例如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 }}'"`
    
  5. Create a variable file (e.g. vars.yml)

    创建一个变量文件(例如vars.yml)

    my_secure_variable: "X_my_secret_X"
    
  6. Encrypt the variable file (from the ansible project location with the ansible.cfg)

    加密变量文件(使用ansible.cfg从ansible项目位置加密)

    ansible-vault encrypt vars.yml
    
  7. Run your playbook (from the ansible project location with the ansible.cfg)

    运行你的剧本(使用ansible.cfg从ansible项目位置)

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

You should get output similar to:

你应该得到类似于的输出:

$ 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

#5


It depends on your workflow. You can use a group_vars file as per Sebastian Stigler suggestion or if you want to use an inventory file, you can just add another "ini-like" file in an inventory directory and encrypt it.

这取决于您的工作流程。您可以根据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

Then, use -i my_inventory/ in your command line, or create a local ansible.cfg containing:

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

[defaults]
hostfile = ./my_inventory/

and you should be set. Ansible will merge both files at run time.

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

Use ansible-vault encrypt my_inventory/inventory_crypted_vars before committing and you're set.

在提交之前使用ansible-vault加密my_inventory / inventory_crypted_vars并进行设置。

You probably want a pre-commit hook to ensure that you're not committing unencrypted version of the file. For instance a pre-commit hook like this would do the trick (adjust FILES_PATTERN accordingly).

您可能需要预提交挂钩以确保您没有提交文件的未加密版本。例如,像这样的预提交钩子可以做到这一点(相应地调整FILES_PATTERN)。

#6


You can use group_vars (see http://docs.ansible.com/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable).

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

Create a subdirectory in your playbook named group_vars.
There you create a file named west_coast and put the following entries in it:

在您的Playbook中创建一个名为group_vars的子目录。在那里,您创建一个名为west_coast的文件,并在其中放入以下条目:

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

This file can then be converted to an ansible vault.

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

#1


If your issue is to have both unencrypted and encrypted vars files per group_hosts.

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

You can use this ansible feature : http://docs.ansible.com/ansible/playbooks_best_practices.html#best-practices-for-variables-and-vaults

您可以使用此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 will read automatically vault.yml as encrypted yaml file.

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

Update : The solution below is also good solution (since Ansible 2.3)

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

#2


Since Ansible 2.3 you can encrypt a Single Encrypted Variable. IMO, a walkthrough is needed as the doco's seem pretty terse.

从Ansible 2.3开始,您可以加密单个加密变量。 IMO,需要一个演练,因为doco看起来很简洁。

Given an example of: mysql_password: password123 (within main.yml)

给出一个例子:mysql_password:password123(在main.yml中)

Run a command such as:

运行如下命令:

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

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

This will produce:

这将产生:

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

paste this into your main.yml:

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

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

run playbook:

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

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

Verify via debug:

通过调试验证:

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

#3


At this time with Ansible 2.3 it's possible to have in a plain yaml both encrypted and unencrypted variables. The format of the variables encrypted is like this:

在Ansible 2.3的这个时候,可以在一个简单的yaml中包含加密和未加密的变量。加密变量的格式如下:

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

You can encrypt the variable using a password or a password file with the statement:

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

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

This statement returns the text shown in dbPasswd variable in the yaml above.

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

To run a playbook that uses the encrypted variable just add the following var:

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

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

Or you can do the same with --ask-vault-pass which ask you for the password when executing the playbook:

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

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

#4


You can do something similar to this.

你可以做类似的事情。

  1. Create a password file (a plain text file with your password on a single line)
  2. 创建一个密码文件(一行包含您的密码的纯文本文件)

  3. Create an ansible.cfg in your ansible project folder

    在ansible项目文件夹中创建一个ansible.cfg

    [defaults]
    vault_password_file = <path/to/your/password/file>
    
  4. Create a playbook file (e.g. playbook.yml)

    创建一个剧本文件(例如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 }}'"`
    
  5. Create a variable file (e.g. vars.yml)

    创建一个变量文件(例如vars.yml)

    my_secure_variable: "X_my_secret_X"
    
  6. Encrypt the variable file (from the ansible project location with the ansible.cfg)

    加密变量文件(使用ansible.cfg从ansible项目位置加密)

    ansible-vault encrypt vars.yml
    
  7. Run your playbook (from the ansible project location with the ansible.cfg)

    运行你的剧本(使用ansible.cfg从ansible项目位置)

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

You should get output similar to:

你应该得到类似于的输出:

$ 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

#5


It depends on your workflow. You can use a group_vars file as per Sebastian Stigler suggestion or if you want to use an inventory file, you can just add another "ini-like" file in an inventory directory and encrypt it.

这取决于您的工作流程。您可以根据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

Then, use -i my_inventory/ in your command line, or create a local ansible.cfg containing:

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

[defaults]
hostfile = ./my_inventory/

and you should be set. Ansible will merge both files at run time.

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

Use ansible-vault encrypt my_inventory/inventory_crypted_vars before committing and you're set.

在提交之前使用ansible-vault加密my_inventory / inventory_crypted_vars并进行设置。

You probably want a pre-commit hook to ensure that you're not committing unencrypted version of the file. For instance a pre-commit hook like this would do the trick (adjust FILES_PATTERN accordingly).

您可能需要预提交挂钩以确保您没有提交文件的未加密版本。例如,像这样的预提交钩子可以做到这一点(相应地调整FILES_PATTERN)。

#6


You can use group_vars (see http://docs.ansible.com/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable).

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

Create a subdirectory in your playbook named group_vars.
There you create a file named west_coast and put the following entries in it:

在您的Playbook中创建一个名为group_vars的子目录。在那里,您创建一个名为west_coast的文件,并在其中放入以下条目:

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

This file can then be converted to an ansible vault.

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