Reputation: 136231
Consider an Ansible inventory file similar to the following example:
[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
I would like to store some of the vars (like db_password
) in an Ansible vault, but not the entire file.
How can a vault-encrypted ansible file be imported into an unencrypted inventory file?
I have created an encrypted vars file and tried importing it with:
include: secrets
To which ansible-playbook
responded with:
ERROR: variables assigned to group must be in key=value form
Probably because it tried to parse the include
statement as a variable.
Upvotes: 87
Views: 118217
Reputation: 14438
Since Ansible 2.3 you can encrypt a Single Encrypted Variable. IMO, a walkthrough is needed as the doco's seem pretty terse.
Given an example of: mysql_password: password123
(within main.yml)
Run a command such as:
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:
mysql_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653236336462626566653063336164663966303231363934653561363964363833
3136626431626536303530376336343832656537303632313433360a626438346336353331
run playbook:
Ie, ansible-playbook -i hosts main.yml --ask-vault-pass
Verify via debug:
- debug:
msg: "mysql Pwd: {{ mysql_password }}"
Upvotes: 132
Reputation: 4734
If your issue is to have both unencrypted and encrypted vars files per group_hosts.
You can use this ansible feature : 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.
Update : The solution below is also good solution (since Ansible 2.3)
Upvotes: 63
Reputation: 237
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:
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.
To run a playbook that uses the encrypted variable just add the following 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:
ansible-playbook playbooks/myplaybook --ask-vault-pass
Upvotes: 22
Reputation: 301
You can do something similar to this.
Create an ansible.cfg
in your ansible project folder
[defaults]
vault_password_file = <path/to/your/password/file>
Create a playbook file (e.g. 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 }}'"`
Create a variable file (e.g. vars.yml
)
my_secure_variable: "X_my_secret_X"
Encrypt the variable file (from the ansible project location with the ansible.cfg
)
ansible-vault encrypt vars.yml
Run your playbook (from the ansible project location with the ansible.cfg
)
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
Upvotes: 8
Reputation: 18269
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.
$ 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:
[defaults]
hostfile = ./my_inventory/
and you should be set. Ansible will merge both files at run time.
Use ansible-vault encrypt my_inventory/inventory_crypted_vars
before committing and you're set.
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).
Upvotes: 4
Reputation: 7289
You can use group_vars (see 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:
---
db_server: foo.example.com
db_host: 5432
db_password: top secret password
This file can then be converted to an ansible vault.
Upvotes: 0