Hello!
What if we need to create a user in the database and store their password securely in code? This can be done using ansible vault. Ansible vault allows you to encrypt both the entire file and individual variables.
Encrypted file
Let’s create a file that will contain our variables.
db_password: secure_password!
admin_password: super_securee_password!
We cannot simply leave this file because it stores passwords. But it can be encrypted using the ansible-vault encrypt VAR_FILE
command. You will need to enter a password that will be used for decryption.
$ ansible-vault encrypt 1.yml
New Vault password:
Confirm New Vault password:
Encryption successful
And the file itself will look like this and can be added to source control.
$ANSIBLE_VAULT;1.1;AES256
32393936363535383238323361373334376664613530346332336333653066366437336232313761
3638396339376462636630336161376161396637366338360a653962326431616266656463613966
32366130613763343937366363623864646263616664323231633662626333353331613537613733
3132393337346431660a613037333166626563306634346461303538383237376263373734626666
64623136336535323230303631313736376162363633626264346538646163363339643438396633
62653234373230323538616563306130353334333931616338363561346530633335346562363837
62656166613939303139653233346466393636666637353438376230393935336638363664303037
64313162363661396161
This file is a normal file with variables, but when running ansible-playbook
you need to pass a password for decryption. There are several ways to do it. First, with `–ask-vault-pass’ key, in this case, Ansible will ask for a password at startup. Accordingly, this option is not suitable for automatically starting Ansible, because the password must be entered every time.
Let’s use the following code for the test, where vars are our encrypted variables
---
- name: Run locally
hosts: localhost
connection: local
vars_files:
- vars.yml
tasks:
- name: Print var
debug:
msg: "{{ db_password }}"
$ ansible-playbook -i "localhost," main.yml --ask-vault-pass
Vault password:
PLAY [Run locally] *****************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************
ok: [localhost]
TASK [Print var] ******************************************************************************************************************
ok: [localhost] => {
"msg": "secure_password"
}
PLAY RECAP ************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The next option is using a file with a password. For this, a file is created in which the password will be stored and ansible is launched with the key --vault-password-file PATH_TO_FILE
$ ansible-playbook -i "localhost," main.yml --vault-password-file .vault_pass
PLAY [Run localy] *****************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************
ok: [localhost]
TASK [Print var] ******************************************************************************************************************
ok: [localhost] => {
"msg": "secure_password"
}
PLAY RECAP ************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
If you run it without these variables, you will get
ansible-playbook -i "localhost," main.yml
ERROR! Attempting to decrypt but no vault secrets found
Decrypt file
To edit the encrypted file, you can use the ansible-vault edit ENCRYPTED_FILE
command, enter the password and edit the file.
Change vault password
The password can be changed using the ansible-vault rekey VAULT_FILE
command
ansible-vault rekey vars.yml
Vault password:
New Vault password:
Confirm New Vault password:
Rekey successful
Encrypted variable
If you do not need to encrypt an entire file, but only one parameter, this can also be done using the `ansible-vault encrypt_string ‘TEXT_TO_ENCRYPT’ –name ‘VARIABLE_NAME’’ command.
ansible-vault encrypt_string 'secure' --name db_password
New Vault password:
Confirm New Vault password:
Encryption successful
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
32613335323933306136303139616131303039396139646332656337343532383034336439363739
3032376165376462653533633731626366613337356234340a353662343931366436643635383666
32313163373765333666623065373930616431333365656331376362316464363038636136346138
3033376563636437630a663533383336353434336566633935396137373737303662636432326433
3630
As a result, we get a parameter that can be added to other unencrypted variables. But as with an encrypted file, when you run ansible, you need to pass the password for decryption. If we encrypt several variables, they must have one password for decryption
app_port: 8080
db_user: postgres
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
32613335323933306136303139616131303039396139646332656337343532383034336439363739
3032376165376462653533633731626366613337356234340a353662343931366436643635383666
32313163373765333666623065373930616431333365656331376362316464363038636136346138
3033376563636437630a663533383336353434336566633935396137373737303662636432326433
3630
To not specify the password in the terminal when encrypting, you can also use a file with a password using the --vault-password-file
key.
ansible-vault encrypt_string --vault-password-file pass 'secure' --name db_password
Encryption successful
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
31623232663866376238643739353231323835646530326531333766623831363637396130363330
6139303362643962343432353765643639623339396134370a653236336433613064303530623933
34633765636536333935363833323537356134653333326562363435653437366639393136316336
6462363437633130330a366439653933353766326565623464353364626234623862666265643539
3338
For the test, we will use the following code:
---
- name: Run locally
hosts: localhost
connection: local
vars:
admin_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
31386261643538643135333865383233656435366161333865393232643035393265393963646331
6130636537343866653733623938363030333739313031300a393663356165343038656164323365
32303230376536306633633936303430396234343961393862323434663435626136313062663032
3661653564353539650a323733376635306562383263613738383934313931353062633266323762
34343231386139303737613538346430633336383165333065303532373738636661
tasks:
- name: Print var
debug:
msg: "{{ admin_password }}"
And I will get the result
$ ansible-playbook -i "localhost," main.yml --vault-password-file .vault_pass
PLAY [Run localy] *****************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************
ok: [localhost]
TASK [Print var] ******************************************************************************************************************
ok: [localhost] => {
"msg": "secure_admin_password"
}
PLAY RECAP ************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0