There is an ever-growing demand of automation in the world of IT infrastructure management and Ansible has proven to be one of the most powerful automation solutions out there.
But there’s one issue that a lot of users bring up – To enable password-less authentication, Ansible requires public SSH key from the controller node to be copied to all the target nodes. Thus, making the whole environment vulnerable if any unauthorized person gets their hands on the controller node.
Ansible does come with a flag called “—ask-pass”, which prompts the user for password of the target node, but if the user is running a playbook on multiple target nodes, it tries that password on all the nodes. So, unless the user has same credentials for all the target nodes (which is not very secure), this won’t work!
There’s a better solution to this problem - One can leverage Ansible Vault
What is Ansible Vault
It is a feature of Ansible that allows the users to encrypt sensitive data such as passwords, keys or any other important data that is required to run Ansible plays but should not be publicly visible. This data gets automatically decrypted at run-time, if the correct key is provided.
Ansible Vault uses AES256 algorithm to provide symmetric encryption, using a user-provided password.
Using Ansible Vault, users can perform these operations:
- Encrypt/Decrypt a file
- Encryption:
ansible-vault encrypt <filename>
- Decryption:
ansible-vault decrypt <filename>
- View the encrypted file without breaking the encryption
- View:
ansible-vault view <filename>
- Edit the encrypted file
- Edit:
ansible-vault edit <filename>
- Create a new encrypted file
- Create:
ansible-vault create <filename>
- Generate or reset the encrypted key
- Generate/reset:
ansible-vault rekey <filename>
Ansible Vault to enable secure connection without copying SSH keys
There are multiple ways in which the user can incorporate Ansible Vault in their environment, but following is one of the most straight-forward ways.
Here’s how to do it!
Creating the Inventory
The inventory needs to be created in a particular way, to use this method.
This should be the directory structure of Inventory:

Let’s look at the individual files for more clarity.
Inventory/main.yml
---
grp1:
hosts: ---------------------- hosts in grp1 group
testmachine1
testmachine2
grp2:
hosts: ---------------------- hosts in grp2 group
testmachine3
testmachine4
Inventory/group_vars/grp2/main.yml
---
ansible_user: "{{ credentials[inventory_hostname].user | d('default_user') }}" ----- to map username
ansible_password: "{{ credentials[inventory_hostname].password | d('default_password') }}" ----- to map password
Inventory/group_vars/grp2/credentials.yml
---
credentials:
testmachine3:
user: root ------- username for testmachine3
password: testpassword3 ------- password for testmachine3
testmachine4:
user: root ------- username for testmachine4
password: testpassword4 ------- password for testmachine4
User can use this Inventory with Ansible as it is, but, keeping username and password in plain text is not a very good idea, from the security front.
So, let’s encrypt the files!
Encrypting the credential file
To encrypt the file containing credentials, user needs to run the following command:
ansible-vault encrypt <filename>
In this case:
ansible-vault encrypt inventory/group_vars/grp2/credentials.yml
It will prompt for a password, once done, it will encrypt the file.
Now, if the user tries to access the file without the password, something like following will be seen:

The file containing credentials has been encrypted!
And it won’t be accessible to anyone who does not know the password of Ansible Vault. Thus, providing an additional layer of security.
What’s more?
User can even encrypt credentials segregated based on groups (In this case grp1 and grp2) in different Vaults with different passwords, so, access can be managed among different groups using the same LPAR.
Running the playbook with encrypted files
Now that the file containing credentials has been encrypted, without the password of vault, user won’t be able to run any playbook on the targets present in the inventory.
Let’s try to run the following test playbook:
---
- name: Generic test playbook
hosts: "{{host_name}}"
gather_facts: false
vars:
host_name: grp2
tasks:
- name: Run date command
shell: "date"
changed_when: false
Trying to run without providing password:

In this case, as the credentials.yml file is encrypted and is something that is required for running the playbook, Ansible expects a password during run-time so that it can access the contents of the encrypted file and run the playbook as per the expectations.
To provide password of vault during run-time, user needs to use “—ask-vault-pass” with the ansible-playbook command.
Note: As credentials of all the target nodes present in that group are already there in the credentials.yml file (in encrypted form), just the vault password for credentials.yml is required to run the playbooks on all the targets.
Running with the wrong password

If user provides wrong password during the run-time, the execution fails with the above message.
Running with the correct password

Running the ansible-playbook command with “—ask-vault-pass” and providing the correct password, It runs the playbook and performs the desired task.
Conclusion
In the modern times, security is a big concern for all the enterprises. Ansible Vault is a great feature that comes with Ansible, providing an additional layer of security in user's environment. And is something that the users should explore if it can be implemented in user's automation environment in some way.
I hope you enjoyed this blog, happy automation!
Ansible vault's documentation