A Comprehensive Guide to Ansible Vault for Beginners.

Amit Gujar
5 min readSep 16, 2023

In my previous tutorial, we learned how to set up Ansible on our control node and perform bare deployments by writing playbooks and inventory files. Now we will take a step forward in our Ansible journey and introduce the Ansible-Vault.

Photo by Brock Wegner on Unsplash

What is an Ansible vault?

This tool allows you to securely store sensitive information in an encrypted format like any other vault. In today’s blog post, we will discuss the details of this vault and perform several operations such as encryption and decryption.

Note: Before reading this blog, I recommend reading my previous one Introduction to Ansible.

What will you learn:

  1. Create encrypted variable files for playbooks.
  2. Perform operations on encrypted files.
  3. Link encrypted files in playbooks.

Requirements:

  1. Refer to my last blog.

Let’s Start 🤩:

Step 1: Set your ansible editor if you don’t want to use Vim. Add the following line in your .bashrc.

export EDITOR=nano

The main interface for managing encrypted content within Ansible is the "ansible-vault" command. It can encrypt, view, edit, or decrypt data.

Step 2: Create your first encrypted file.

ansible-vault create file.txt

Step 3: View the contents of the encrypted file.

cat file.yml

Step 4: Edit the encrypted file. You will get a prompt to enter the password in order to edit. Once editing is done the will get encrypted again.

ansible-vault edit file.yml

Step 5: To view the file content temporarily, use this command.

ansible-vault view file.yml

Step 6: You can also change the password of an encrypted file using the rekey command.

ansible-vault rekey file.yml

Step 7: You can also encrypt existing files using the encrypt command

ansible-vault encrypt another_file.txt

Step 8: Decrypt an encrypted file permanently.

ansible-vault decrypt another_file.txt

Step 9: Avoid the hassle of entering the password every time. Create a file named password.txt/py and type your password in it. Make sure to mention this file in .gitignore.

ansible-vault view file.yml --vault-password-file=password.py

Step 10: Simplify this by adding the ANSIBLE_VAULT_PASSWORD_FILE variable to the .bashrc file. This automatically catches the password file, eliminating the need for the --vault-password-file flag.

export ANSIBLE_VAULT_PASSWORD_FILE=~/myPlaybooks/vault/password.py

Implementing Vault in Playbook:

As we move forward, it's important to note that what we've learned so far may not be something you'll use frequently. However, there is one task that you'll likely perform more often - providing secret values within a playbook. To demonstrate this, we'll be using the vm_linux.yml playbook from our previous blog.

Step 1: Create a folder, and create a file named values.yml. This file will contain our all variables.

Step 2: Encrypt this file

Note: I have already added the password file path to the .bashrc file. You may need to perform this step.

Step 3: To make necessary changes, please edit the vm_linux.yaml file by indicating the exact location of the encrypted file that contains our variables.

- name: Creating a VM in Azure
hosts: localhost
vars_files:
- vault/values.yml

tasks:
# creating a resource group
- name: Creating a resource group
azure.azcollection.azure_rm_resourcegroup:
name: "{{ resource_name }}"
location: "{{ location }}"
tags:
Exp: "2"

# creating a virtual network
- name: Creating virtual network
azure.azcollection.azure_rm_virtualnetwork:
name: "{{ virtual_network_name }}"
resource_group: "{{ resource_name }}"
location: "{{ location }}"
address_prefixes_cidr:
- "10.0.0.0/16"
# creating a subnet
- name: Adding subnet
azure.azcollection.azure_rm_subnet:
name: "{{ subnet_name }}"
resource_group: "{{ resource_name }}"
virtual_network: "{{ virtual_network_name }}"
address_prefix_cidr: "10.0.1.0/24"
# creating a public ip
- name: Creating public ip
azure.azcollection.azure_rm_publicipaddress:
name: "{{ public_ip_name }}"
resource_group: "{{ resource_name }}"
allocation_method: Static
register: output_public_ip

# creating a network security group
- name: Creating NSG
azure.azcollection.azure_rm_securitygroup:
name: "{{ nsg_name }}"
resource_group: "{{ resource_name }}"
rules:
- name: 'Allow_SSH'
protocol: Tcp
destination_port_range: 22
access: Allow
priority: 100
direction: Inbound
- name: 'Allow_web_traffic'
protocol: Tcp
destination_port_range:
- 80
- 443
access: Allow
priority: 101
direction: Inbound

# creating a network interface
- name: Creating NIC with public ip
azure.azcollection.azure_rm_networkinterface:
name: "{{ nic_name }}"
resource_group: "{{ resource_name }}"
virtual_network: "{{ virtual_network_name }}"
subnet_name: "{{ subnet_name }}"
security_group: "{{ nsg_name }}"
ip_configurations:
- name: deafult
public_ip_address_name: "{{ public_ip_name }}"
primary: true

# creating virtual machines
- name: Finally creating a VM
azure.azcollection.azure_rm_virtualmachine:
name: vm-ansiblemanaged
resource_group: "{{ resource_name }}"
vm_size: Standard_B1s
admin_username: amit
ssh_password_enabled: false
ssh_public_keys:
- path: /home/amit/.ssh/authorized_keys
key_data: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
network_interfaces:
- name: "{{ nic_name }}"
image:
offer: 0001-com-ubuntu-server-jammy
publisher: Canonical
sku: '22_04-lts'
version: latest

# connection string
- name: Connect to machine using this string
ansible.builtin.debug:
msg: "ssh amit@{{ output_public_ip.state.ip_address }}"

Our playbook is now more organized and clean. Let's execute it to verify if it works as expected.

ansible-playbook vm_linux.yaml

Wrapping up 😎:

In this tutorial, Ansible Vault and its fundamental functionalities were explained. The tutorial covered various operations that can be performed on Ansible Vault and how to incorporate encrypted files into the playbook.

--

--