Mastering Ansible Vault: Secure Password Management and Encryption Techniques
This guide explains how to avoid interactive password prompts in Ansible by using Vault encryption, covering creation of encrypted files, Vault IDs, multiple password sources, string encryption, editing, rekeying, and best‑practice recommendations for managing sensitive data in playbooks.
When managing target nodes, some operations require a password, but prompting for interactive input during automation with Ansible is undesirable.
Common non‑interactive approaches include writing sensitive data to files, using environment variables, command‑line options, or expect‑style tools, each with drawbacks.
Ansible provides a safer and more convenient solution: Vault encryption, which uses the AES256 algorithm.
12.1 Getting Started: Creating an Encrypted File
Ansible uses the
ansible-vaultcommand for encryption tasks. The
createsub‑command creates a new encrypted file.
<code>$ ansible-vault --help
positional arguments:
{create,decrypt,edit,view,encrypt,encrypt_string,rekey}
create 创建新的文件并加密
decrypt 解密已加密的文件
edit 编辑已加密文件的内容
view 查看已加密文件的内容
encrypt 加密已存在的未加密文件
encrypt_string 加密一段字符串
rekey 修改已加密文件的Vault ID和凭据密码
</code>Example: create a file
passwd_prompt.ymland add a password variable.
<code>$ ansible-vault create --vault-id @prompt passwd_prompt.yml
New vault password (default): # prompt user
Confirm new vault password (default): # prompt user
---
mypasswd: 123456
</code>The
--vault-id @promptoption makes
ansible-vault createask interactively for the credential password that protects the file.
12.2 Vault ID and Credential Password Provisioning
The
--vault-idoption can be used in three forms:
prompt – interactive prompt for the credential password.
filename – read the password from a plain file (e.g.,
a.txt).
script – execute a script and read the password from its stdout (e.g.,
a.sh).
Example of three different sources:
<code>$ ansible-vault create --vault-id id1@prompt first_encrypted.yml
$ ansible-vault create --vault-id [email protected] second_encrypted.yml
$ ansible-vault create --vault-id [email protected] third_encrypted.yml
</code>If the Vault ID is omitted, the default ID is used.
12.3 Encrypting an Existing File
To encrypt an existing plain file, use
ansible-vault encryptwith the same options as
create.
<code>$ cat plain.yml
---
plain_passwd: 123456
port: 2312
$ ansible-vault encrypt --vault-id [email protected] plain.yml
Encryption successful
$ cat plain.yml
$ANSIBLE_VAULT;1.2;AES256;id1
336130623037643739633938313061336431
...</code>Multiple files can be encrypted at once with a shared Vault ID.
<code>$ ansible-vault encrypt --vault-id [email protected] foo.yml bar.yml baz.yml
</code>12.4 Meaning of the Encryption Header
Every encrypted file starts with a header line such as:
<code>$ANSIBLE_VAULT;1.2;AES256;id1
</code>The fields are:
$ANSIBLE_VAULT – fixed identifier.
Version (1.1, 1.2, …) – indicates the Vault format.
Algorithm – currently only AES256.
Vault ID – present only if a custom ID was used.
You can extract the Vault ID with:
<code>$ awk -F';' 'NR==1{print $4}' encrypted.yml
id2
</code>12.5 Decrypting an Encrypted File
Use
ansible-vault decryptwith the appropriate Vault ID.
<code>$ ansible-vault decrypt --vault-id [email protected] plain.yml
Decryption successful
---
plain_passwd: 123456
port: 2312
</code>Multiple files can be decrypted in a single command.
<code>$ ansible-vault decrypt --vault-id [email protected] foo.yml bar.yml baz.yml
</code>12.6 Changing Vault ID and Credential Password
Use
ansible-vault rekeyto modify the Vault ID, the credential password, or both.
<code>$ ansible-vault rekey --vault-id [email protected] \
--new-vault-id [email protected] \
first_encrypted.yml
Rekey successful
</code>You can also change only the ID or only the password by keeping one part of
label@sourceunchanged.
<code># Keep ID, change password
$ ansible-vault rekey --vault-id [email protected] \
--new-vault-id [email protected] \
first_encrypted.yml
# Change ID, keep password
$ ansible-vault rekey --vault-id [email protected] \
--new-vault-id [email protected] \
first_encrypted.yml
</code>12.7 Editing the Content of an Encrypted File
Use
ansible-vault editto open the file in the default editor, edit the plaintext, and have it re‑encrypted automatically.
<code>$ ansible-vault edit --vault-id [email protected] first_encrypted.yml
</code>Alternatively, decrypt, modify, and re‑encrypt in a non‑interactive way:
<code>$ ansible-vault decrypt xxx
$ sed -i 's/old/new/' xxx
$ ansible-vault encrypt xxx
</code>12.8 Using Vault‑Encrypted Files in ansible‑playbook Tasks
Playbooks can reference encrypted variable files via
vars_files. Example playbook:
<code>---
- hosts: localhost
gather_facts: no
vars_files:
- first_passwd.yml
- second_passwd.yml
tasks:
- name: debug var in first_passwd
debug:
var: passwd1
- name: debug var in second_passwd
debug:
var: passwd2
</code>Encrypt the variable files with different Vault IDs and run the playbook with both IDs:
<code>$ ansible-playbook --vault-id [email protected] --vault-id [email protected] test.yml
TASK [debug var in first_passwd] *********************
ok: [localhost] => {"passwd1": "passwd in first_passwd"}
TASK [debug var in second_passwd] ********************
ok: [localhost] => {"passwd2": "passwd in second_passwd"}
</code>12.9 Encrypting a String and Embedding it in a YAML File
Use
ansible-vault encrypt_stringto encrypt a literal and optionally assign a name.
<code>$ ansible-vault encrypt_string --vault-id [email protected] 'hello' --name 'mysql_pass'
mysql_pass: !vault |
$ANSIBLE_VAULT;1.2;AES256;id1
39623437656130313338613033383464376437...
Encryption successful
</code>The encrypted block can be copied directly into a YAML file.
<code>---
mysql_port: 3306
mysql_user: root
mysql_pass: !vault |
$ANSIBLE_VAULT;1.2;AES256;id1
39623437656130313338613033383464376437...
mysql_host: 192.168.200.27
</code>When reading from stdin, use
--stdin-nameinstead of
--stdin --name.
<code>$ ansible-vault encrypt_string --vault-id [email protected] --stdin-name 'mysql_pass' <<<"hello"
mysql_pass: !vault |
$ANSIBLE_VAULT;1.2;AES256;id1
35386538393939633862626361323735306...
Encryption successful
</code>12.10 Speeding Up Encryption/Decryption
Install the
cryptographyPython package to improve performance when handling many files.
<code>pip install cryptography
</code>12.11 Vault Encryption Best Practices
Encrypt only files that contain sensitive data, not large configuration files. Use a separate variable file for each secret and reference it with a
vault_‑prefixed variable in the main file.
<code># main.yml
---
mysql_port: 3306
mysql_user: root
mysql_pass: "{{ vault_mysql_pass }}"
mysql_host: 192.168.200.27
# vault_mysql_pass.yml (encrypted)
---
vault_mysql_pass: "abcdef"
</code> <code>$ ansible-vault encrypt --vault-id [email protected] mysql_pass.yml
</code>Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.