Using encrypted variables and files
When you run a task or playbook that uses encrypted variables or files, you must provide the passwords to decrypt the variables or files. You can do this at the command line or by setting a default password source in a config option or an environment variable.
Passing a single password
If all the encrypted variables and files in your task or playbook need to use a single password, you can use the --ask-vault-pass
or --vault-password-file
cli options.
To prompt for the password:
ansible-playbook --ask-vault-pass site.yml
To retrieve the password from the /path/to/my/vault-password-file
file:
ansible-playbook --vault-password-file /path/to/my/vault-password-file site.yml
To get the password from the vault password client script my-vault-password-client.py
:
ansible-playbook --vault-password-file my-vault-password-client.py
Passing vault IDs
You can also use the --vault-id
option to pass a single password with its vault label. This approach is clearer when multiple vaults are used within a single inventory.
To prompt for the password for the ‘dev’ vault ID:
ansible-playbook --vault-id dev@prompt site.yml
To retrieve the password for the ‘dev’ vault ID from the dev-password
file:
ansible-playbook --vault-id dev@dev-password site.yml
To get the password for the ‘dev’ vault ID from the vault password client script my-vault-password-client.py
:
ansible-playbook --vault-id dev@my-vault-password-client.py
Passing multiple vault passwords
If your task or playbook requires multiple encrypted variables or files that you encrypted with different vault IDs, you must use the --vault-id
option, passing multiple --vault-id
options to specify the vault IDs (‘dev’, ‘prod’, ‘cloud’, ‘db’) and sources for the passwords (prompt, file, script). For example, to use a ‘dev’ password read from a file and to be prompted for the ‘prod’ password:
ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml
By default, the vault ID labels (dev, prod and so on) are only hints. Ansible attempts to decrypt vault content with each password. The password with the same label as the encrypted data will be tried first, after that, each vault secret will be tried in the order they were provided on the command line.
Where the encrypted data has no label, or the label does not match any of the provided labels, the passwords will be tried in the order they are specified. In the example above, the ‘dev’ password will be tried first, then the ‘prod’ password for cases where Ansible doesn’t know which vault ID is used to encrypt something.
Using --vault-id
without a vault ID
The --vault-id
option can also be used without specifying a vault-id. This behavior is equivalent to --ask-vault-pass
or --vault-password-file
so is rarely used.
For example, to use a password file dev-password
:
ansible-playbook --vault-id dev-password site.yml
To prompt for the password:
ansible-playbook --vault-id @prompt site.yml
To get the password from an executable script my-vault-password-client.py
:
ansible-playbook --vault-id my-vault-password-client.py
Configuring defaults for using encrypted content
Setting a default vault ID
If you use one vault ID more frequently than any other, you can set the config option DEFAULT_VAULT_IDENTITY_LIST to specify a default vault ID and password source. Ansible will use the default vault ID and source any time you do not specify --vault-id
. You can set multiple values for this option. Setting multiple values is equivalent to passing multiple --vault-id
cli options.
Setting a default password source
If you don’t want to provide the password file on the command line or if you use one vault password file more frequently than any other, you can set the DEFAULT_VAULT_PASSWORD_FILE config option or the ANSIBLE_VAULT_PASSWORD_FILE
environment variable to specify a default file to use. For example, if you set ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass.txt
, Ansible will automatically search for the password in that file. This is useful if, for example, you use Ansible from a continuous integration system such as Jenkins.
The file that you reference can be either a file containing the password (in plain text), or it can be a script (with executable permissions set) that returns the password.
When are encrypted files made visible?
In general, the content you encrypt with Ansible Vault remains encrypted after execution. However, there is one exception. If you pass an encrypted file as the src
argument to the copy, template, unarchive, script or assemble module, the file will not be encrypted on the target host (assuming you supply the correct vault password when you run the play). This behavior is intended and useful. You can encrypt a configuration file or template to avoid sharing the details of your configuration, but when you copy that configuration to servers in your environment, you want it to be decrypted so local users and processes can access it.
Format of files encrypted with Ansible Vault
Ansible Vault creates UTF-8 encoded txt files. The file format includes a newline terminated header. For example:
$ANSIBLE_VAULT;1.1;AES256
or
$ANSIBLE_VAULT;1.2;AES256;vault-id-label
The header contains up to four elements, separated by semi-colons (;
).
The format ID (
$ANSIBLE_VAULT
). Currently$ANSIBLE_VAULT
is the only valid format ID. The format ID identifies content that is encrypted with Ansible Vault (with vault.is_encrypted_file()).The vault format version (
1.X
). All supported versions of Ansible will currently default to ‘1.1’ or ‘1.2’ if a labeled vault ID is supplied. The ‘1.0’ format is supported for reading only (and will be converted automatically to the ‘1.1’ format on write). The format version is currently used as an exact string compare only (version numbers are not currently ‘compared’).The cipher algorithm used to encrypt the data (
AES256
). CurrentlyAES256
is the only supported cipher algorithm. Vault format 1.0 used ‘AES’, but the current code always uses ‘AES256’.The vault ID label used to encrypt the data (optional,
vault-id-label
) For example, if you encrypt a file with--vault-id dev@prompt
, the vault-id-label isdev
.
Note: In the future, the header could change. Fields after the format ID and format version depend on the format version. Future vault format versions may add more cipher algorithm options and/or additional fields.
The rest of the content of the file is the ‘vaulttext’. The vaulttext is a text-armored version of the encrypted ciphertext. Each line is 80 characters wide, except for the last line which may be shorter.
Ansible Vault payload format 1.1 - 1.2
The vaulttext is a concatenation of the ciphertext and a SHA256 digest with the result ‘hexlifyied’.
‘hexlify’ refers to the hexlify()
method of the Python Standard Library’s binascii module.
hexlify()’ed result of:
hexlify()’ed string of the salt, followed by a newline (
0x0a
)hexlify()’ed string of the encrypted HMAC, followed by a newline. The HMAC is:
a RFC2104 style HMAC
inputs are:
The AES256 encrypted ciphertext
A PBKDF2 key. This key, the cipher key, and the cipher IV are generated from:
the salt, in bytes
10000 iterations
SHA256() algorithm
the first 32 bytes are the cipher key
the second 32 bytes are the HMAC key
the remaining 16 bytes are the cipher IV
hexlify()’ed string of the ciphertext. The ciphertext is:
AES256 encrypted data. The data is encrypted using:
AES-CTR stream cipher
cipher key
IV
a 128-bit counter block seeded from an integer IV
the plaintext
the original plaintext
padding up to the AES256 blocksize. (The data used for padding is based on RFC5652)