Ansible Vault with AWX

Adnan Okay
Turk Telekom Bulut Teknolojileri
8 min readJun 18, 2022

Hi there, In this article, I’m gonna show you how to use Ansible vault with our playbooks and variables. Ansible Vault is a strong tool that encrypts our important statements and passwords which we used in our projects. Firstly, I’m gonna show you the basic usage, and end of the article we will see how to use it with our AWX as well.

Let's start,

What is Ansible-Vault?

Ansible-vault is one of the Ansible tools that encrypt, decrypt and view your sensitive data, such as API keys and database passwords rather than in plain text files. With vault, you can

  • Encrypt a file
  • Decrypt a file
  • View an encrypted file without breaking the encryption
  • Edit an encrypted file
  • Create an encrypted file
  • Generate or reset the encrypted key

If you have any sensitive data where used in your playbooks or roles, you can keep them safely in the vault. For example, when you’re using Git, you’re pushing your content up to a remote server. If you don’t want your passwords and other sensitive data to be visible, you can vault them and put them in source control. Ansible Vault can be used with both ad‑hoc commands and playbooks, encrypting sensitive data. You can keep your data in files or as individual variables, and Vault will be able to encrypt both. Here is where you can use vault,

  • Inventory
  • Inventory host/group variables
  • vars/defaults in roles
  • tasks files
  • handler files

We will use the ansible-vault command to create, edit, rekey, decrypt and view files. Let's create a new encrypted file with the vault.

#ansible-vault create vault_file_name.yml
New Vault password
Confirm New Vault password

You can store your variables or any sensitive data that you want. I typed two variables

#cat vault_file_name.yml
dba_user_name: admin
dba_user_pass: password

If we need to update the file content,

#ansible-vault edit vault_file_name.yml

if you try to view the file content, you will only see some encrypted blocks

#cat vault_file_name.yml
$ANSIBLE_VAULT;1.1;AES256
32363332323131363330613236626436623834333066353563386431333664373039313733646466
3962396564376563393638383364373836343135613938300a313439653033663265653161626365
61636566396363623535623562353938383339326532313264663764633039306439373631346435
6363303034343332640a303965376565373164636137653363613833323135383964303337353034
65396235363266633630633336386434356439313431373835613138653361623763363363636635
3431323864626135646563343961316163313731663231353839

if you want to view the file content with your vault password,

# ansible-vault view  vault_file_name.yml 
Vault password:
dba_user_name: admin
dba_user_pass: password

to encrypt an existing file,

#ansible-vault encrypt requirements.yml 
New Vault password:
Confirm New Vault password:
Encryption successful

to decrypt an existing file

#ansible-vault decrypt requirements.yml 
Vault password:
Decryption successful

You might want to change your existing vault password,

#ansible-vault rekey vault_file_name.yml 
Vault password:
New Vault password:
Confirm New Vault password:
Rekey successful

Let’s see how we can use encrypted vault files within a playbook.

# cat playbook.yml 
---
- name: ansible-vault test playbook
hosts: all
vars_files:
- vault_file_name.yml
tasks:
- name: show vault encrypted variables
debug:
msg: "{{dba_user_name}}"

to output db_user_name variable with debug module, you need to provide 3 ways to your vault password with the ansible-playbook or ansible command,

  • The first way is by adding the ‑‑ask‑vault‑pass option to any Ansible or Ansible Playbook command.

Here is the result

#ansible-playbook playbook.yml  --ask-vault-pass --connection=local
Vault password:
PLAY [ansible-vault test playbook] **************************************************************************************
TASK [Gathering Facts] **************************************************************************************************ok: [localhost]
TASK [show vault encrypted variables] ***********************************************************************************ok: [localhost] => {
"msg": "admin"
}
PLAY RECAP **************************************************************************************************************localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  • The second way, If you don't want to prompt each time your password, you can store your password inside a file. But if you using git, make sure it doesn’t commit the password file by adding it to the git ignore file.

Here is the result.

#echo 'your_password' > .vaultpass#ansible-playbook playbook.yml  --vault-password-file .vaultpass --connection=localPLAY [ansible-vault test playbook] **************************************************************************************
TASK [Gathering Facts] **************************************************************************************************ok: [localhost]
TASK [show vault encrypted variables] ***********************************************************************************ok: [localhost] => {
"msg": "admin"
}
PLAY RECAP **************************************************************************************************************localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

If you don't want to type each time vault-password-file with the ansible-playbook command, You can put an entry in your ansible configuration file.

#cat ansible.cfg 
[defaults]
vault_password_file = .vaultpass
  • The third way, you can set an ANSIBLE_VAULT_PASSWORD_FILE environment variable in your .profile, or .bash_profile file
# cat ~/.bash_profile # .bash_profile# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programsPATH=$PATH:$HOME/binexport PATHexport ANSIBLE_VAULT_PASSWORD_FILE=/root/.vaultpass

source your .bash_profile for the changes

# source ~/.bash_profile# echo $ANSIBLE_VAULT_PASSWORD_FILE
/root/.vaultpass

Here is the result,

# ansible-playbook playbook.yml   --connection=localPLAY [ansible-vault test playbook] **************************************************************************************
TASK [Gathering Facts] **************************************************************************************************ok: [localhost]
TASK [show vault encrypted variables] ***********************************************************************************ok: [localhost] => {
"msg": "admin"
}
PLAY RECAP **************************************************************************************************************localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

PS: In the same way, you can store your vault password with export ANSIBLE_VAULT_PASSWORD=<password> environment variable as well

to encrypt a single variable

# ansible-vault encrypt_string --ask-vault-pass 'mysql_passowrd' --name 'mysql_password'
New Vault password:
Confirm New Vault password:
mysql_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
37386363396162363036303830623266613733336233353035386431393737326463663765303465 3231663062333131663530396637346532373365643966650a356632356136306464663237386237 61316431323932366165333435626565656561653939363866646262373239373639643161363737 3030653233646339380a3037653130343265383464616665616537353164373665346236653161306634
Encryption successful

You can copy the output to use as an encrypted variable in your projects.

Managing Multiple Passwords with Vault IDs

Let's assume that you have two different encrypted files in your project. For each file, you store a different vault password. To use the different vault passwords in the same project, you need to use Vault IDs.

PS: If you use the same vault password with all files, and variables within the project, you don't need to use Vault IDs

For example, you have an admin team and a dev team. Each of them is using their password to play playbooks. You can label Vault IDs like dev@prompt and admin@prompt.

Here are the options to use Vault ID

  • — vault-id label@source
  • — encrypt-vault-id label@source

The label will just remind you to use the correct password. The source can be a file, a prompt, or a script, depending on how you store and use your vault passwords.

Let's create a vault-id for the admin or dev team,

# ansible-vault create --vault-id admin@prompt  vault_admin_vars.yml
New vault password (admin):
Confirm new vault password (admin):
# cat vault_admin_vars.yml
team_admin: admin
# ansible-vault create --vault-id dev@prompt vault_dev_vars.yml
New vault password (dev):
Confirm new vault password (dev):
# cat vault_dev_vars.yml
team_dev: dev

Let's see how to use a playbook with multiple passwords

# cat playbook.yml 
---
- name: ansible-vault test playbook
hosts: all
vars_files:
- vault_admin_vars.yml
- vault_dev_vars.yml
tasks:
- name: show vault encrypted variables
debug:
msg: "{{team_admin}} and {{team_dev}}"

As you can see, I included all variables files in the playbook.

# ansible-playbook --vault-id admin@prompt --vault-id dev@prompt  playbook.yml --connection=local
Vault password (admin):
Vault password (dev):
PLAY [ansible-vault test playbook] **********************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************ok: [localhost]
TASK [show vault encrypted variables] *******************************************************************************************************ok: [localhost] => {
"msg": "admin and dev"
}
PLAY RECAP **********************************************************************************************************************************localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

In this example, we need to prompt the admin and dev password.

Let's try to store the passwords within files for admin and dev.

# echo "dev" > .devvaultfile
# echo "admin" > .adminvaultfile
# ansible-playbook --vault-id .devvaultfile --vault-id .adminvaultfile playbook.yml --connection=localPLAY [ansible-vault test playbook] **********************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************ok: [localhost]
TASK [show vault encrypted variables] *******************************************************************************************************ok: [localhost] => {
"msg": "admin and dev"
}
PLAY RECAP **********************************************************************************************************************************localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

or you can define the path of your files with ansible.cfg

# cat ansible.cfg
[defaults]
vault_identity_list = admin@~/.adminvaultfile , dev@~/.devvaultfile
##vault_password_file = .vaultpass
# ansible-playbook playbook.yml --connection=localPLAY [ansible-vault test playbook] **********************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************ok: [localhost]
TASK [show vault encrypted variables] *******************************************************************************************************ok: [localhost] => {
"msg": "admin and dev"
}
PLAY RECAP **********************************************************************************************************************************localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

or you can define ANSIBLE_VAULT_IDENTITY_LIST env variable in your .bash_profile

export ANSIBLE_VAULT_IDENTITY_LIST=admin@~/.adminvaultfile,dev@~/.devvaultfile

to encrypt an existing vars file.

# ansible-vault encrypt --encrypt-vault-id .vaultadminfile vars.ymlor# ansible-vault encrypt --encrypt-vault-id admin vars.yml

to encrypt just a variable with vault id. You can copy the result hash code to paste your vars file.

# ansible-vault encrypt_string --encrypt-vault-id admin -n testing this-is-the-secret
testing: !vault |
$ANSIBLE_VAULT;1.2;AES256;admin
66363830313062616562336238386564613664363132336366386338666430323337363661336330 6466643264346638613162353934663164346336626261650a376436386434306535383138613461 34623234386334366536623666356632633638626661333563323036323536653937626333353134 3337653463313834350a346538623536613737386462336132343262626432373261393031336533
63613736323061323162376532353566346230616665323039346437623138316364
Encryption successful
or# ansible-vault encrypt_string --encrypt-vault-id admin 'test_var' --name 'result'
result: !vault |
$ANSIBLE_VAULT;1.2;AES256;admin
36613138366266366239306630306533336434636336343938633862643064343230353838643364 3265626330626533376137636536356538313263333937370a33303231336538646623736316663 30303234363063376531383833343362306630613865646539633934636633373363303930373065 3662653765326363660a3736623562393130333964353332353366323466343336663532613161333464
Encryption successful

Use Vault with AWX

To use vault with AWX, first, you should create a vault credential like the one below.

You can store your vault password and save it. Now, you need to add your vault password to your template as a second credential.

As you can see the file that we encrypted in the first example named vault_file_name.yml has shown us output successfully.

our playbook content,

# cat playbook2.yml 
---
- name: ansible-vault test playbook
hosts: all
vars_files:
- vault_file_name.yml
tasks:
- name: show vault encrypted variables
debug:
msg: "{{dba_user_name}}"

Let's use vault id with AWX,

As we talked about before, Vault id provides us to use multiple passwords in the same project. There is a section on AWX for the Vault ids. After storing your password, you have to define de vault id name. For our example, We’ve used admin and dev for the 2 different yamls in our projects.

To add a new Vault Id on AWX, You should create a new vault credential and define the vault identifier name. For our example, I need to create 2 different vault credentials like the one below.

After creating vault id credentials, you should assign your template to both of them at the same time. If you assign just 1, your project will give an error

Here is our successful output

playbook.yml content,

---
- name: ansible-vault test playbook
hosts: all
vars_files:
- vault_admin_vars.yml
- vault_dev_vars.yml
tasks:
- name: show vault encrypted variables
debug:
msg: "{{team_admin}} and {{team_dev}}"

This is the end of the article. I hope that it was clear to use Vault in your projects.

Feel free to ask me any questions.

May the Force be with you :)

--

--