Operations 17 min read

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.

Raymond Ops
Raymond Ops
Raymond Ops
Mastering Ansible Vault: Secure Password Management and Encryption Techniques

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-vault

command for encryption tasks. The

create

sub‑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.yml

and 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 @prompt

option makes

ansible-vault create

ask interactively for the credential password that protects the file.

12.2 Vault ID and Credential Password Provisioning

The

--vault-id

option 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.

Vault ID diagram
Vault ID diagram

12.3 Encrypting an Existing File

To encrypt an existing plain file, use

ansible-vault encrypt

with 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 decrypt

with 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 rekey

to 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@source

unchanged.

<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 edit

to 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_string

to 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-name

instead 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

cryptography

Python 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>
AutomationDevOpsencryptionAnsibleVault
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.