Secrets are managed in Ansible using a feature called “Vault.” A Vault contains encrypted data, allowing you to store sensitive information such as passwords, API keys, and other confidential data securely. Current stable version: Ansible-core 2.20.2 (released January 29, 2026)
To create a new encrypted data file called foo.yml with the test vault password sourced from the multi_password_file, you can use the following command:
ansible-vault create --vault-id test@multi_password_file foo.yml
This command will open your default text editor where you can input your data. After saving and exiting, the data will be encrypted.
To encrypt an existing file, use the ansible-vault encrypt command. This command can operate on multiple files simultaneously. For example:
ansible-vault encrypt foo.yml bar.yml baz.yml
You can also encrypt existing files with the project ID and be prompted for the password by running:
ansible-vault encrypt --vault-id project@prompt foo.yml bar.yml baz.yml
If you need to modify an encrypted file, use the ansible-vault edit command:
ansible-vault edit foo.yml
This command decrypts the file in memory, allowing you to edit it. Upon saving, it will be re-encrypted automatically.
To view an encrypted file without editing it:
ansible-vault view secret.yml
To change the password of an encrypted file:
ansible-vault rekey secret.yml
# Or to specify a new password file:
ansible-vault rekey --new-vault-id new_env@new_password_file secret.yml
You can create a .vault file in your working directory to store your vault passwords securely. You can generate a strong password using tools like openssl or pwgen:
openssl rand -hex 32 > .vault_password # Generates a 64-character hex password
# Or with pwgen:
pwgen 140 > .vault_password
To use this password file when running Ansible commands, specify it as follows:
ansible-playbook playbook.yml --vault-password-file .vault_password
Store the vault password in an environment variable:
export ANSIBLE_VAULT_PASSWORD_FILE=/path/to/.vault_password
ansible-playbook playbook.yml
Or for a specific vault ID:
export MY_VAULT_ID="@prompt"
ansible-playbook playbook.yml --vault-id dev@$MY_VAULT_ID
On systems with keyring support, you can store vault passwords securely:
ansible-vault create --vault-id dev@keyring.vault.SecretService.vault_password secret.yml
Ansible allows you to manage multiple vault IDs for different environments or projects. Each vault ID can point to a different password file, making it easy to switch contexts. For example:
# Encrypt files with different vault IDs
ansible-vault encrypt --vault-id dev@dev_password_file foo.yml
ansible-vault encrypt --vault-id prod@prod_password_file bar.yml
ansible-vault encrypt --vault-id staging@prompt baz.yml
You can then reference the appropriate vault ID when running your playbook:
# Use specific vault ID
ansible-playbook playbook.yml --vault-id dev@dev_password_file
# Use multiple vault IDs
ansible-playbook playbook.yml --vault-id dev@dev_password_file --vault-id prod@prod_password_file
# Prompt for specific vault ID
ansible-playbook playbook.yml --vault-id dev@prompt
You can configure default vault settings in your ansible.cfg file:
[defaults]
vault_password_file = /path/to/default_vault_password
# Or for multiple vault IDs:
# vault_identity_list = dev@/path/to/dev_vault,prod@/path/to/prod_vault
[vault]
# Default vault IDs to use
defaults = dev@~/.ansible/vault_dev_password,prod@~/.ansible/vault_prod_password
You can also encrypt individual values directly in your playbooks or inventory files:
ansible-vault encrypt_string --vault-id dev@prompt 'my_secret_password' --name 'database_password'
This generates an encrypted string that can be embedded in your files:
---
database_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
6639613932373230353036353437326564393133353064323935323264313131393539643633343839
383234303632643662386132653732303530363534373265643931333530643239353232643131
3139353964363334383938323430363264366238613265373230353036353437326564393133
35306432393532326431313139353964363334383938323430363264366238613265373230
35306432393532326431313139353964363334383938323430363264366238613265373230
Use Strong Passwords: Always generate strong, unique passwords for each vault ID. Use at least 32 characters or longer.
Separate Environments: Use different vault IDs and passwords for different environments (dev, staging, prod).
Version Control: Do not commit your vault password files to version control systems. Use .gitignore to exclude these files:
*.vault
*.vault_password
.vault_*
Access Control: Limit access to vault files and ensure only authorized users can access the passwords needed to decrypt them.
Regular Rotation: Regularly audit and rotate your vault passwords and encrypted content.
Backup Strategy: Regularly back up your vault password files in a secure manner to avoid loss of access to your encrypted data.
Principle of Least Privilege: Grant only the minimum necessary access to vault passwords based on roles and responsibilities.
Consistent Naming: Use consistent naming conventions for vault IDs (e.g., dev, staging, prod).
Documentation: Document which vault ID corresponds to which environment and who has access.
Testing: Test your vault configurations in non-production environments before applying to production.
Monitoring: Monitor access to vault password files and review access logs regularly.
Integration with Secret Management Systems: Consider integrating with enterprise secret management solutions like HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault for additional security layers.
You can include encrypted variables in your playbooks by referencing the encrypted files. Here’s an example of how to use them:
---
- name: Example Playbook with Vault
hosts: all
vars_files:
- secrets.yml # This file is encrypted
tasks:
- name: Print secret variable
debug:
var: secret_variable # This variable is defined in secrets.yml
- name: Use secret in a task
mysql_db:
name: "{{ db_name }}"
state: present
login_user: "{{ db_admin_user }}"
login_password: "{{ db_admin_password }}" # This is stored encrypted
Content of secrets.yml (before encryption):
---
# Database credentials
db_admin_user: admin
db_admin_password: supersecret_password
db_host: localhost
db_port: 3306
# API keys
api_key: abcdefghijklmnopqrstuvwxyz123456
aws_access_key: AKIAIOSFODNN7EXAMPLE
aws_secret_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
After encryption, the file will contain encrypted content that looks like:
$ANSIBLE_VAULT;1.1;AES256
626639336464306236653465336134353030373830663935363231376537346463323263653532363764303639646138663032633066363431393165626335303861373063636530623761613537363230323031623966653064313134393735373062636134356231613664663532663730646534636265346632303737666238653137663935386264333939303565306434313766353234663264643832663062383735333462363962313934306532346465373338336331646433636632643536393032346163306230363665303761383030663963666232396534653039336461343437333962663463646232646236336431393830353731383231623734666436306135373030663731356331633462366539646530643137646134313232363437623338306663306436393661393732343731623865613430306566306634303338306462633365613135666563323531303536303133373732353730343032383661626538353230363231343834363463336261336532646534353439363064613436346431633931666135353462306531313739323862663830393935393536373239383462336535353932343535663031636437313139646234613365346537633566306134346262333866653934613064313733366261363436386139393935393737383035356630356262613932343738613732313163626635313766663365303763373137393564613331373732373831626331636230623233646164353536643031646430333431383664393739663261353663636439643261396537343339646239646436613737383931666131363965323231323064643934663938396266666363303431306137663539306233613933343630353839393835306532343664343234653131346530613434323932626237383261336635633736363239353865363137643063643062383261313738306466393536353166666161313165623335313963306637626632646163303463643934306533336330646461363166303663336136353532316431306330646536336464666561336337363931376166633063653830393861393761306566386238363763353238306261363563353335316335336164346533316438376134393864646532396330653733646536313430376561336663343763316261396631383930646335383961633536306561313834393266663863363036376337303931373039663263623865313239363033303733353761653436353564666134373533396637353834313136383561336533383464363735373862366365613934376161316261303733303463333533313836646164633731613930343434366632313965336262393039353530623431373465313137306437633531303033613761633961313761646637623037396534663161333539613938393664633962313732623831323839613237353531643139336461363631633935623131666262343134396630626334323733643931623237353739376335633235333931646335316239306464396337303764306133376237653837663831313639613138336634396365313834383261346533396264626630323831393837336663313263393063323964353335366437313064306639323163303037323034383733303733663835376165353466396237353861343130313235646635613539323463643765653934343965393861653936393830666535393135366437353831353934353762663765643539333864616266653231376237316230363436373339383931653264346161373132343338353165323166353434313438346664393163653962663736393065623863376261336539356461376136666436633763363761633133386534396330666337663237306138633232303236353632353865323766666539646130366463366430303066373463363866643965646338396532666264383463623063383735383965643963306239353862353566663036366464633831613963313137313830373831616261313532346334663935366363306430633464353662323438623931333863353963363064306632666530313966363139396461303134313563383431626632386237376533636537666332363737373463306239363464623537386265313965653934666234343865333031333162613963653962653036396231376233376337313133333930363839393063333630396661636561376561623933363363393462333131396330616233653563663338363761653661343830313831323730633262646533653739336239633839336338333463333731376466
366662373039393133393834616536653536643566306563613732386338316430343763313065613732633464623837313761316635646134313066626138363132303161393236353065343261343566613761396539316161383565383865383866653138316632343233346135316465366561633664633662366639626133366530356531653862393762623737383835316134363532366634663739663132386134343430653034333438306536323965666661613335313861393964316338373061383135663663346530636265633935376461616337616639393864363530633331303936643734386163653565313963613438663639306261313839623261313238353137303936376233666463663261336137363966376564666263653037616239363232663463383337346335306335653735303565343061393734323134653265323536353962636464376266626438396235663535616538383035323133313438346164623965646464613736323639363535646262396533306462366136366262373536646233663966646664623831383838666266636236396438376332373133633533666533373030646266366131376335653264393235333533353866333232376463303537633236376136623639623465343763333036343765363631646531633838306361336234366266343437313766313530626266303964373232653865363735396338303363386564306533653933376639396532653162653931303865336434396265633931313066626237316530383430343232666331336264346530313963323765
For enhanced security, consider integrating Ansible Vault with external secret management systems:
Use the hashivault lookup plugin to retrieve secrets from HashiCorp Vault:
- name: Retrieve secret from HashiCorp Vault
set_fact:
api_token: "{{ lookup('hashivault', 'path/to/secret', 'key_name') }}"
Use the aws_secrets lookup plugin to retrieve secrets from AWS:
- name: Retrieve secret from AWS Secrets Manager
set_fact:
db_password: "{{ lookup('aws_secrets', 'my-database-secret') }}"
chmod 600)Any questions?
Feel free to contact us. Find all contact information on our contact page.