Ansible Vault — Decrypting Multiple Passwords

Introduction

With Ansible Vault since Ansible 2.4, even if some files are encrypted with password A, some files with password B, and so on, they can be decrypted with a single command.

Official documentation for encrypt_string to create encrypted variables to embed in yaml, Vault Ids and Multiple Vault Passwords, Providing Vault Passwords

  • From 2.4, you can use the old --vault-password-file option, but you can replace it with the--vault-id option instead.
  • The --vault-id option has more functions than the --vault-password-file option, but for the time being, if you specify a file with the password like the --vault-password-file option, --vault Behaves the same as the password-file option.
  • Since the --vault-id option can be used multiple times when decrypting, the playbook can be executed even if there are multiple files encrypted with different passwords.

Compare Vault

Ansible 2.3

Traditionally, the --vault-password-file option was used to specify a file containing passwords for Ansible Vault encryption and decryption.

For example, if you want to create a new file and use an editor to describe the contents of the encrypted file

root@vagrant:/home/vagrant# ansible-vault create --vault-password-file file_with_password.txt new_file_to_encrypt.txt

And if you want to encrypt an existing unencrypted file,

root@vagrant:/home/vagrant# ansible-vault create --vault-password-file file_with_password.txt existing_file_to_encrypt.txt

If you want to create an encrypted file directly from standard input,

root@vagrant:/home/vagrant# echo -n'(name): (some-value)' | ansible-vault encrypt --vault-password-file file_with_password.txt --output new_file_to_encrypt.txt
Encryption successful

The --vault-password-file option was also used when processing that requires decryption such as ansible-vault decrypt or view is performed, or when an encrypted file is used in ansible-playbook or the like.

Also, if you do not use the --vault-password-file option, the ansible-vault command will automatically ask for the password, and for ansible-playbook etc., if you add the -ask-vault-pass option, the password will be executed at runtime. I asked.

Setting the value of the vault_password_file in the [defaults] section of the configuration file ansible.cfg instead of the --vault-password-file option, or setting the value of the environment variable

ANSIBLE_VAULT_PASSWORD_FILE had the same effect.

Ansible 2.4

In ansible 2.4, a new option called --vault-id has been added, while those that were previously available can still be used. The same result can be obtained by replacing the --vault-password-file option with the --vault-id option.

Here file two written a password for verification

  • echo -n "P@ssword_123" > vault_pass1
  • echo -n "P@ssw0rd_321" > vault_pass2

A command to create an encrypted file directly from the standard input mentioned above

root@vagrant:/home/vagrant# echo -n'name: some-value' | ansible-vault encrypt --vault-password-file vault_pass1 --output multi_pass.yaml
Encryption successful

Works well with --vault-password-file instead of --vault-id as shown below.

root@vagrant:/home/vagrant# echo -n'name: some-value' | ansible-vault encrypt --vault-id vault_pass1 --output multi_pass.yaml
Encryption successful

The contents of the encrypted file multi_pass.yaml are as follows.

root@vagrant:/home/vagrant# cat multi_pass.yaml
$ANSIBLE_VAULT;1.1;AES256
30343764396266386632656531323436633130366163316462366663303664383965303235346638
6366316233363965633434366437663661366163393337610a643035313436323066326433376662
63646234393636623366653239316434653138363766376432336339346436363862343235366363
3265313435633863350a323761386163376534386533613032323636623535623262636265323361
32613530316434653333363566623235363834383965643162336131376430623235

We can run

  • ansible-vault view — vault-password-file vault_pass1 multi_pass.yaml
  • ansible-vault view — vault-id vault_pass1 multi_pass.yaml

Then we can see the decrypted version of this file 😀

Then, what is the difference from the past due to the addition of the --vault-id option? There are three key points.

1. Labels

First, the --vault-id option can be labeled by specifying “label@password file” as the value.

In other words, the label label2 is set in the encrypted file multi_pass2.yaml by executing the following.

root@vagrant:/home/vagrant# echo -n'name: some-value' | ansible-vault encrypt --vault-id label2@vault_pass1 --output multi_pass2.yaml
Encryption successful

The contents of multi_pass2.yaml are as follows.

root@vagrant:/home/vagrant# cat multi_pass2.yaml
$ANSIBLE_VAULT;1.2;AES256;label2
63663765356563386635306330363663316239363330623662333636636239393531383631323333
6261386561633739616234306631343934656333373931300a353836303838383336613436663664
31376230626439616433333534346463303939306531383830643666303761326561313838383662
3536396335616138610a333739393839333862663436353638636534366662623138653031636231
35666265623733636338333562393633333861363963313661636532643832333839

The difference from the unlabeled multi_pass.yaml is 1.1 if there is no label after $ ANSIBLE_VAULT; in the header part, and 1.2 if there is. This is the version number of the Ansible Vault format. You can also see that ;label2 is added after AES256. This is the label.

Currently the label is meaningful if you set:

  • vault_id_match = True in the [defaults] section of the configuration file ansible.cfg
  • ANSIBLE_VAULT_ID_MATCH = True in the environment variable, default value is set to False

If this setting is False, the label will be ignored, but if True, only those that match the combination of the label specified in the --vault-id option during decryption and the password written in the file will be decrypted.

2. Decryption with multiple passwords

You can specify the --vault-id option multiple times when decrypting.

For verification, please create an inventory file hosts_inventory with the following contents.

root@vagrant:/home/vagrant# cat hosts_inventory
multi_pass[1:3]

Then create a playbook playbook.yaml with the following contents.

Create new encrypted file multi_pass3.yaml using the second file with the password.

root@vagrant:/home/vagrant# echo -n'name: some-value' | ansible-vault encrypt --vault-id label3@vault_pass2 --output multi_pass3.yaml
Encryption successful

Execute this playbook with ANSIBLE_VAULT_ID_MATCH = False, specify the --vault-id option twice and do as follows.

root@vagrant:/home/vagrant# ansible-playbook -i hosts_inventory --vault-id vault_pass1 --vault-id vault_pass2 playbook.yamlPLAY [all] *****************************************************************************************************************************************************TASK [debug] ***************************************************************************************************************************************************
ok: [multi_pass1] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [multi_pass2] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [multi_pass3] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [192.168.123.123] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
PLAY RECAP *****************************************************************************************************************************************************
192.168.123.123 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

It can also be executed by replacing one or both --vault-id options with the --vault-password-file option.

root@vagrant:/home/vagrant# echo -n'name: some-value' | ansible-vault encrypt --vault-password-file vault_pass1 --output multi_pass2.yaml
Encryption successful

root@vagrant:/home/vagrant# echo -n'name: some-value' | ansible-vault encrypt --vault-password-file vault_pass2 --output multi_pass3.yaml
Encryption successful

If we run this playbook with ANSIBLE_VAULT_ID_MATCH = True then

  • multi_pass.yaml is unlabeled
  • multi_pass2.yaml is labeled with label2
  • multi_pass3.yml is labeled with label3

Therefore, you need to use the --vault-id option three times to run the playbook:

root@vagrant:/home/vagrant# ansible-playbook -i hosts_inventory --vault-id vault_pass1 --vault-id label2@vault_pass1 --vault-id label3@vault_pass2 playbook.yaml
PLAY [all] *****************************************************************************************************************************************************
TASK [debug] ***************************************************************************************************************************************************
ok: [multi_pass1] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [multi_pass2] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [multi_pass3] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [192.168.123.123] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
PLAY RECAP *****************************************************************************************************************************************************
192.168.123.123 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

We can also executed this playbook with --vault-password-file option.

root@vagrant:/home/vagrant# ansible-playbook -i hosts_inventory --vault-password-file vault_pass1 --vault-id label2@vault_pass1 --vault-id label3@vault_pass2 playbook.yamlPLAY [all] *****************************************************************************************************************************************************TASK [debug] ***************************************************************************************************************************************************
ok: [multi_pass1] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [multi_pass2] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [multi_pass3] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [192.168.123.123] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
PLAY RECAP *****************************************************************************************************************************************************
192.168.123.123 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

If the label of multi_pass3.yaml is also label2, and if ANSIBLE_VAULT_ID_MATCH = False is set when playbook was executed, then the label will be ignored and it will be the same as the original.

Basically you don’t have to set only one password for each label, you can encrypt with multiple passwords even if the labels are the same, and after all, decryption is the label specified by the --vault-id option.

It will be works only for those that match both the and password so remember you need to specify the --vault-id option as many times as the label and password combination that needs to be decrypted.

3. ask-vault-pass

When You use ansible-vault decrypt, ansible-vault view, ansible-playbook and if you specify the value prompt instead of the file with password of --vault-id, at runtime You will be asked for a password and it has the same effect as the -ask-vault-pass .

When you execute, you should be prompted to provide password after execution as shown below.

root@vagrant:/home/vagrant# ansible-playbook -i hosts_inventory --vault-password-file vault_pass1 --vault-id label2@vault_pass1 --vault-id label2@prompt playbook.yaml
Vault password (label2):
PLAY [all] *****************************************************************************************************************************************************TASK [debug] ***************************************************************************************************************************************************
ok: [multi_pass1] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [multi_pass2] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [multi_pass3] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
ok: [192.168.123.123] => {
"example_key": "VARIABLE IS NOT DEFINED!"
}
PLAY RECAP *****************************************************************************************************************************************************
192.168.123.123 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass2 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
multi_pass3 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

 by the author.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store