Winter Sale - up to 36% OFF

How to Use Ansible Vault in Playbook? Secure Your Configuration

How to Use Ansible Vault in Playbook? Secure Your Configuration
Published on Jan 16, 2025 Updated on Jan 17, 2025

Ansible Vault is an Ansible feature that provides a secure mechanism to store highly confidential credentials such as API keys, usernames, passwords, tokens, database settings, server configuration parameters, SSL certificates, etc inside infrastructure code.

As a system administrator or a DevOps engineer, you deal with sensitive information while working with application deployment and infrastructure orchestration. Ansible offers the ansible-vault as a practical built-in command-line tool to safely store and manage highly sensitive variables in Playbooks.

Due to the symmetric encryption provided by the AES256 algorithm, Ansible Vault uses the same user-provided password for encrypting and decrypting arbitrary strings and/or files. The Ansible Playbook command-line tool can run encrypted Ansible Playbooks if the user provides a password through an interactive prompt or a password text file.

Through this tutorial, you will learn how to properly safeguard your secret variables inside Ansible Playbooks. Considering that you might be new to Ansible Vault, you will learn the fundamentals and some basic operations with practical illustrations.

After having grasped the basic knowledge of how to encrypt, view, update, and decrypt your files with Ansible Vault, in the final step, you will learn about the best practices used in the professional community to store sensitive variables inside Ansible Playbooks.

#What is Ansible Vault used for?

Ansible Vault is used for encrypting entire files, arbitrary variables, and even separating the variables from the Ansible Playbook through a vault file. Although encryption on the variable level makes your Ansible infrastructure code readable compared to file-level encryption, Ansible Vault does not provide the ability to update your encryption key in this case.

Shipped by default with Ansible, Ansible Vault is an efficient and useful choice for system administrators and DevOps engineers looking for an out-of-the-box solution to securely store sensitive data in their Ansible Playbooks.

By using Ansible Vault system administrators follow the secure by-design principles. Making use of the Ansible Vault mechanism you make sure the sensitive data inside your Ansible Playbooks is safe at rest and you also guarantee that no secrets are exposed to source control.

Ansible Vault can also be used to:

  • decrypt an encrypted file with ansible-vault
  • view the contents of an encrypted file in plaintext on the terminal console
  • and edit the contents of an encrypted file
  • change the encryption/decryption key
  • encrypt an already existing file

There are many commands present in the command-line tool provided by Ansible Vault. Some of the most used are listed below.

  • create is used to create a new encrypted file with a password provided by the user
  • decrypt can be used to turn the encrypted file into a plaintext file
  • edit is used to decrypt the encrypted file and update it inside a text editor, then the file is automatically encrypted back again with the same password
  • view can be used to see the contents of the encrypted file as plaintext on the console
  • rekey asks the user for the old password, and if the correct one is provided, it asks to update the encryption/decryption key
  • encrypt_string is used to encrypt an arbitrary string, mostly used to encrypt the values of arbitrary variables inside Ansible Playbooks

Each one of the above commands has general and specific flags. For this tutorial, a basic knowledge of the most used commands shared above is enough, but in case you want to dive deep into the flags of each ansible-vault command just type the following command on the Linux terminal console.

man ansible-vault

#Prerequisites

Apart from having Ansible installed and configured on your system basic knowledge of Ansible Playbooks is required. At least you should know what a variable is in the context of Ansible, and how a task is declared inside the YAML file.

To effectively teach our readers how to use Ansible Vault this article makes use of an Ansible Playbook file that connects to a MySQL database server on the remote and performs simple sql queries. The results of the SQL query are then displayed on the console.

---

- name: mysql db operations
  hosts: db

  tasks:
    - name: simple query to test db
      community.mysql.mysql_query:
        login_db: test
        login_user: webmaster
        login_password: master13!!
        query: show tables
      register: mysql_result 

    - name: output query results
      debug:
        msg: "{{ item }}"
      loop: "{{ mysql_result.query_result }}"
---

The above Ansible Playbook makes use of the built-in community.mysql.mysql_query module to log into the MySQL database test and retrieve the existing tables. There are many parameters available to use in the module and as you can see from the above example some of them do store sensitive data.

The Ansible Playbook code shared above also registers the result of the executed sql query inside the variable mysql_result and then with the help of another task displays its content on the console for the user to see.

To make use of the community.mysql.mysql_query module the PyMySQL package should be present on the target machines. PyMySQL is a pure Python package that can be used as a client for MySQL databases. Compatible with both Python 2.7 and Python 3.x, this library supports SSL connections and provides an easy-to-use high-level API.

To install PyMySQL in Debian-based distributions, type:

sudo apt-get install python3-pymysql

To install PyMySQL in RHEL/CentOS/Fedora, type:

sudo dnf install python3-pymysql

Ansible Vault is configured by default to use the Vim text editor. The beginner user may find it hard and alienating to edit files with the help of the Vim utility. To change the Ansible Vault’s text editor to nano, open your ~/.bashrc file.

nano  ~/.bashrc

Add the following line.

export EDITOR=nano

Hit Ctrl O to write the changes to the file and then Ctrl X to quit nano.

Then restart the ~/.bashrc file with the following command for the changes to take place on your system.

source ~/.bashrc

After the above command has been executed successfully to verify that the default text editor used by Ansible Vault has been changed from Vim to nano, type:

echo $EDITOR

Note: Feel free to choose the text editor you prefer. With Vim being an advanced text editor, we recommend configuring Ansible Vault to use nano.

As for the directory structure of Ansible Playbooks this tutorial stores the code examples inside a directory called playbooks in the home directory.

Run your deployments in a scalable and cost-effective open cloud infrastructure. Cherry Servers' secure virtual private servers offer automatic scaling, flexible pricing, and 24/7 technical support. Our pre-defined Ansible module helps you automate the installation and configuration.

#How to use Ansible Vault in Ansible Playbook

Ansible Vault offers the ansible-vault command-line tool that can be used to encrypt, decrypt, view, edit, and update entire files and/or specific strings part of your Ansible Playbooks.

#Step 1: How to create a new encrypted file with Ansible Vault

To avoid committing private and sensitive data like API keys as plaintext in the source code repository, use the ansible-vault utility to store the variables inside an encrypted file.

To create a new encrypted file with Ansible Vault, type:

ansible-vault create ansible/vars/private_keys

The above command asks for the vault password. This is the password used by Ansible Vault to encrypt and decrypt the file. Type a strong one and confirm it. Ansible Vault creates the directories and subdirectories in the path provided if they don’t exist on the filesystem.

how to create an encrypted file with ansible vault

Then with the nano text editor or your favorite one, write your private keys like below.

api_key: "your_api_string_here"

Vim users can save the file with: wq! Enter. In case you configured Ansible Vault to use the nano text editor just hit Ctrl O to write the changes to the file and then Ctrl X to quit. Once you have saved the changes to the file and quit, to access the stored content, the Ansible Vault asks for the password with which you encrypted the file.

Note: Ansible Vault uses the Vim text editor by default. You learned in the Prerequisites section how to configure Ansible Vault to use the nano text editor.

#Step 2: How to view the encrypted file with Ansible Vault

To view the contents of the file you just encrypted using Ansible Vault, type:

cat ansible/vars/private_keys

You can see in the figure below that the whole file is now encrypted.

encrypted file with ansible vault

To view the contents of the ansible/vars/private_keys encrypted file as plain text, type:

ansible-vault view ansible/vars/private_keys

Ansible Vault prompts for a password. Type the password you used to encrypt the file, and the content will be displayed as plaintext on the console.

The above command doesn’t make any changes to the file or the encryption key. It just displays the content of the encrypted file as plaintext in case the password provided is correct. In the end, the original file remains encrypted.

#Step 3: How to encrypt an existing file with Ansible Vault

To create a new file, type:

echo 'how to use ansible vault with ansible playbooks' > tutorial_vault

To encrypt an existing file with Ansible Vault, type:

ansible-vault encrypt tutorial_vault

Provide a password for the file and confirm it. The figure below shows the encryption of the file was successful.

 how to encrypt an existing file with ansible vault

To verify that the whole file is encrypted, type:

cat tutorial_vault

#Step 4: How to edit an encrypted file with Ansible Vault

To edit an existing encrypted file with Ansible Vault, type:

ansible-vault edit tutorial_vault

The command prompts you for the vault password. Upon providing it, you can access the file in plain text inside an editor. From here, you can make any changes you want to the file. Once you save it, the file is automatically encrypted again.

The Ansible Vault’s edit command provides the user with the possibility to update their sensitive variables stored inside an encrypted file and avoid the struggle of having to recreate everything from scratch.

#Step 5: How to change the password of an Ansible Vault encrypted file

To change the vault password of an encrypted file, type:

ansible-vault  rekey tutorial_vault

The command asks you for the old password to ensure you have the encryption key. Provide it, then enter the new password and confirm it.

 how to change the password of an encrypted file with ansible vault

#Step 6: How to decrypt an encrypted file with Ansible Vault

To decrypt the encrypted file with Ansible Vault, type:

ansible-vault decrypt tutorial_vault

Provide your vault’s password to decrypt the file. You will see the message ‘Decryption successful’ confirming the decryption.

 how to decrypt a file with ansible vault

From here, you can access the file in plain text.

decrypted file with ansible vault

#Step 7: How to run an Ansible Playbook with encrypted variables

Variables are used inside tasks in the Ansible Playbook. They’re stored as plaintext by default, like in a computer programming script or module. Ansible Vault can also encrypt arbitrary variables. To encrypt the value of a specific variable, type:

ansible-vault encrypt_string  secret_password_string

In the above command, the secret_password_string should be replaced with the plaintext string that you want to encrypt. In other words, with the value of the variable you are interested in encrypting.

Then copy the encrypted string from the console and embed it inside your Ansible Playbook as below.

---

- name: mysql db operations
  hosts: db

  tasks:
    - name: simple query to test db
      community.mysql.mysql_query:
        login_db: test
        login_user: webmaster
        login_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256         
        3561313238316464313237316135613432373435663262363533306661626238396664666162393035613532      62653662613035656564626332313762353939320a34353365623430336133373961333633623365616437366161363130386239        3465623566356439343435633835313030396331663263316339386166313332650a3035313336646263646366356363346435333264323865313563616466386334 
        query: show tables
      register: mysql_result 

    - name: output query results
      debug:
        msg: "{{ item }}"
      loop: "{{ mysql_result.query_result }}"

---

In the above Ansible Playbook, the password for the database connection is arbitrarily encrypted. You can do the same thing for any variable that holds sensitive information.

For instance, it is a good security practice also to encrypt the values for login_dband login_user as they hold data that can be leveraged by cyber criminals to brute force the password of the MySQL database management system.

To run the above Ansible Playbook, you need to decrypt the arbitrary encrypted variables on the fly. To do so, type:

ansible-playbook    playbooks/mysql_playbook.yml --ask-vault-pass

The –ask-vault-pass option tells Ansible Vault to prompt for the password to decrypt the encrypted data.

Apart from the hassle of having to embed long encrypted strings in your Ansible Playbooks, the encryption of arbitrary variables has the following disadvantages:

  • the code inside the Ansible Playbook is not humanly readable nor customizable
  • in case of changes to the value of the variable or variables, it is required to encrypt the new values with ansible-vault and update them on the Ansible Playbook file
  • it is not practical and efficient to run the ansible-vault encrypt_string command every time you need to encrypt the value of a new variable
  • real-world Ansible Playbooks use hundreds of variables and encrypting each one of them is impractical
  • it is time-consuming

#Step 8: How to properly encrypt sensitive variables inside an Ansible Playbook

The best approach when dealing with sensitive data in Ansible Playbooks is to store the variables and their values inside a separate file called a vault. Then, you can reference encrypted variables by their name inside your Ansible Playbooks with the help of the Jinja2 templating language.

Ansible uses Jinja2 to write templates for Playbooks. Due to its dynamic and expressive nature, system administrators can write complex templates with a few lines of Jinja2 code. The following is an illustration of a reference to a variable inside an Ansible Playbook file.

"{{ api_key }}"

If you have done some web development in frameworks like Flask and/or Django the above syntax should be familiar to you. Keep in mind that the above expression helps to access variables inside our Ansible Playbooks without them being declared there.

There are three main sensitive variables in my Ansible Playbook.

  • login_db specifies the database to log into
  • login_user specifies the username of the database owner
  • login_password specifies the password of the database owner

Create a subdirectory for the variables of your group of hosts inside your current working directory.

mkdir db_vars

Note: Make sure to name your directory according to your group of hosts. Mine is named db_vars because it stores the variables for the database hosts.

Place your sensitive variables along with their values as plaintext inside a file named vars in the directory you created.

login_db: "test"
login_user: "webmaster"
login_password: "master13!!"

Copy the contents of the plaintext file storing the variables to a file named vault inside the same directory.

cp   db_vars/vars   db_vars/vault

Prefix each one of the variable names inside the db_vars/vault file with the vault_ string as shown below.

vault_login_db: "test"
vault_login_user: "webmaster"
vault_login_password: "master13!!"

Update the vars file to access the encrypted variables from the vault file with the help of the Jinja2 templating language expressions.

The updated content of the db_vars/vars file is shown below.

login_db: "{{ vault_login_db }}"
login_user: "{{ vault_login_user }}"
login_password: "{{ vault_login_password }}" 

To encrypt the db_vars/vault file with Ansible Vault, type:

ansible-vault encrypt db_vars/vault

Type the password for encrypting the file and confirm it when asked by the above command.

There is no sensitive data exposed anymore. The database credentials are stored and encrypted inside the db_vars/vault file.

Verify the content of the db_vars/vault shown in the figure below.

how to properly encrypt sensitive data inside Ansible Playbooks

To reference the encrypted variables inside your Ansible Playbook, first load both the db_vars/vars and db_vars/vault files with the help of the vars_files syntax, as shown below.


---
- name: mysql db operations
  hosts: db
  vars_files:
   - "../db_vars/vars"
   - "../db_vars/vault"

  tasks:
    - name: simple query to test db
      community.mysql.mysql_query:
        login_db: "{{login_db}}"
        login_user: "{{login_user}}"
        login_password: "{{login_password}}"
        query: show tables
      register: mysql_result 

    - name: output query results
      debug:
        msg: "{{item}}"
      loop: "{{ mysql_result.query_result }}"

---

The var_files syntax helps to store the variables inside files separate from Ansible Playbooks and call them with the help of the Jinja2 templating language. Following this workflow, you can easily keep your playbooks in source control and even share them with others without the risk of leaking sensitive data or having your infrastructure compromised.

Note: Make sure to provide the absolute path of each one of the files inside the var_files section. My Ansible Playbook files are stored inside the playbooks subdirectory so I had to prefix the path with the ../ string to move to the root of the directory.

As you can see in the above Ansible Playbook the encrypted variables are accessed with the help of Ansible's Jinja 2 implementation directly from the vars file.

login_db: "{{ login_db }}"
login_user: "{{ login_user }}"
login_password: "{{ login_password}}"

Our Ansible Playbook doesn’t store any sensitive data, and it has no idea about the content of the variables being called inside it. The sensitive variables and their values are stored inside a separate file that is encrypted with Ansible Vault.

When changes occur to the database credentials in the future, you can easily edit the db_vars/vault file with the ansible-vault edit command, as shown below.

ansible-vault edit db_vars/vault

The above command prompts for the decryption key. Once you finish editing the file, Ansible Vault puts it back in the encrypted state. In one single update, you made all the changes required for the proper functioning of your Ansible Playbook. Since the sensitive variables aren’t declared but just referenced inside your Ansible Playbook, they will be updated with new values on their future calls.

To run the Ansible Playbook, type:

ansible-playbook playbooks/mysql_playbook.yml --ask-vault-pass

Type the password and let the Ansible Playbook run.

Ansible Vault also can decrypt through a password file. Create an empty text file inside your home directory and place the vault key as plaintext in there. Make sure to keep this master key away from the prying eye.

You can use the echo command to store your vault password as plaintext inside a file.

echo 'mysecretpassword@11'  > ~/ansible/vault_pass.txt

Just make sure to replace the string inside the single quotation marks with your vault password.

To specify the file which stores the vault key to Ansible Vault make use of the --vault-pass-file option shown below.

ansible-playbook playbooks/mysql_playbook.yml --vault-pass-file ~/ansible/vault_pass.txt

The result of the above command is shown in the figure below.

how to secure MySQL database credentials in Ansible Playbook  with Ansible Vault

To avoid retyping the location of the vault password file every time you need to run your Ansible Playbook, it’s possible to specify its location inside the ansible.cfg configuration file. The location of the ansible.cfg configuration file is in the /etc/ansible subdirectory. With the help of the nano text editor, open it.

sudo nano /etc/ansible/ansible.cfg

Add the following line.

vault_password_file  =  ~/ansible/vault_pass.txt

No, you can run your Ansible Playbook without directly providing a password file on the console since it is already configured inside the /etc/ansible/ansible.cfg file.

ansible-playbook playbooks/mysql_playbook.yml 

Also read: How Does 'When' Condition Work in Ansible

#Final thoughts

Ansible Vault provides the necessary utilities to safely store sensitive data inside your Ansible Playbooks. Equipped with the knowledge of the Ansible-vault tool through illustrative examples, you can now securely deploy your Ansible infrastructure code projects.

Cloud VPS - Cheaper Each Month

Start with $9.99 and pay $0.5 less until your price reaches $6 / month.

Share this article

Related Articles

Published on Jul 26, 2022 Updated on Feb 6, 2024

How To Use Variables in Ansible Playbooks

Learn how to define and reference Ansible variables in playbooks, inventories or on the command line.

Read More
Published on Jul 27, 2022 Updated on Feb 6, 2024

How To Define and Use Handlers in Ansible Playbooks

Ansible handlers allow specific tasks to run only when the state of a system changes. Learn how to define and use handlers in your Ansible playbooks.

Read More
Published on Sep 16, 2024 Updated on Sep 16, 2024

How Does When Condition Work in Ansible

Learn how the when condition works in Ansible to control task execution based on variables, facts, and conditions. Optimize your playbooks with this detailed guide.

Read More
We use cookies to ensure seamless user experience for our website. Required cookies - technical, functional and analytical - are set automatically. Please accept the use of targeted cookies to ensure the best marketing experience for your user journey. You may revoke your consent at any time through our Cookie Policy.
build: 0eb4b60e5.875