Securely Accessing Ansible Vault in Development
Categories:
Projects: c2platform/phx/ansible
,
c2platform.core
Problem
When developing and testing Ansible playbooks that use Ansible Vault, running
ansible-playbook
can be cumbersome. You must repeatedly enter the vault
password each time. Using a vault password file is an option, but it is not
secure and is considered poor practice, as it risks exposing sensitive
information.
Context
In Ansible engineering work on projects that use an
Ansible Inventory Project
which includes a vault managed with Ansible Vault, you must provide the vault
passphrase to avoid provisioning failures. You can do this with the
--ask-vault-pass
flag:
ansible-playbook site.yml --ask-vault-pass
Alternatively, use --vault-password-file
to specify a password file. For more
details, see the
Ansible documentation
.
If using a password file, ensure its permissions prevent unauthorized access, and never commit it to source control. However, storing vault passwords in files is not ideal—it increases security risks, as mistakes can easily lead to leaks.
Solution
A more secure alternative, especially in high-security environments where
storing secrets in files is unacceptable, is to use an environment variable
to hold the password in memory. Then, set the Ansible environment variable
ANSIBLE_VAULT_PASSWORD_FILE
to a script that
echoes this variable. Note that ANSIBLE_VAULT_PASSWORD_FILE
serves as an
alternative to --vault-password-file
. Importantly, the “password file” can be
either a plain text file or an executable script (e.g., Bash or Python) that
outputs the password.
The password resides in memory only for the duration of the shell session, which is acceptable for most environments1.
Examples and implementation
The Ansible inventory project
c2platform/phx/ansible
includes an Ansible Vault-based vault (see folder secret_vars
).
This vault is included via include_vars
in the Ansible Secrets role
c2platform.core.secrets
.
20 - name: Include secrets
21 ansible.builtin.include_vars:
22 dir: "{{ secrets_dir_item['secrets_dir_item'] }}"
23 loop: >-
24 {{ secrets_dirs_stats['results']
25 | selectattr('stat.exists', 'equalto', True) }}
26 loop_control:
27 label: "{{ secrets_dir_item['secrets_dir_item'] }}"
28 loop_var: secrets_dir_item
29 when: secrets_dir_item.stat.exists
The Ansible Secrets role allows flexible configuration of vault locations using
a variable secrets_dirs
.
---
secrets_dirs:
- "{{ inventory_dir }}/secret_vars/development"
- "/runner/project/secret_vars/{{ px_env }}" # awx / aap
On the Ubuntu-based desktop pxd-ubuntu-devtop
, Ansible creates a script
/usr/local/bin/vault-client.sh
, see
Setting Up an Ansible Development Desktop
for more information. The configuration responsible for creating this file is in
group_vars/ubuntu_devtop/main.yml
group_vars/ubuntu_devtop/main.yml
16 - name: /usr/local/bin/vault-client.sh
17 type: copy
18 dest: /usr/local/bin/vault-client.sh
19 content: |
20 #!/bin/bash
21
22 # vault-client.sh
23 # This script is intended to be used as ANSIBLE_VAULT_PASSWORD_FILE.
24 # It checks if the environment variable PX_ANSIBLE_VAULT_PASSWORD is set.
25 # If set, it echoes the value (returns it).
26 # If not set, it outputs an error to stderr and exits with status 1.
27 # Use the set_vault_password function in your shell (e.g., from .bash_aliases.sh)
28 # to set the variable before running ansible-playbook.
29
30 if [ -z "${PX_ANSIBLE_VAULT_PASSWORD}" ]; then
31 echo "Error: PX_ANSIBLE_VAULT_PASSWORD is not set. Please set it using 'set_vault_password' in your shell session." >&2
32 exit 1
33 fi
34
35 echo "${PX_ANSIBLE_VAULT_PASSWORD}"
36 mode: "0755"
The how-to Set Up Ansible with Kerberos on a PHX Development Desktop simulates how an Ansible desktop is used within the PHX domain. It incorporates Kerberos and Ansible Vault in a secure manner using environment variables.
In the how-to, domain user “Tony” adds a bash function phx-vault-password
to
his ~/.bash_aliases
and exports ANSIBLE_VAULT_PASSWORD_FILE
. This setup
allows Tony to access the Ansible Vault securely on the desktop
pxd-ubuntu-devtop
without Vagrant. It demonstrates how to do this in an
air-gapped PHX domain by keeping the password in memory only, avoiding storage
in plain files:
function phx-vault-password() {
local password
echo -n "Enter Ansible Vault passphrase: " >&2
read -s password
echo >&2 # Add a newline after the hidden input
export PX_ANSIBLE_VAULT_PASSWORD="$password"
echo "PX_ANSIBLE_VAULT_PASSWORD has been set for this shell session." >&2
}
export ANSIBLE_VAULT_PASSWORD_FILE="/usr/local/bin/vault-client.sh"
With this approach, a user can set the password in their shell session using:
phx-vault-password
And then view the vault with passphrase prompts using:
ansible-vault view secret_vars/development/main.yml
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ phx-vault-password
Enter Ansible Vault passphrase:
PX_ANSIBLE_VAULT_PASSWORD has been set for this shell session.
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ alias phx-vault
alias phx-vault='ansible-vault edit secret_vars/development/main.yml'
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ phx-vault
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ ansible-vault view secret_vars/development/main.yml
---
# ad
px_ad_admin_password: Supersecret!
# cacerts_server
px_cacerts2_ca_domain_passphrase: huhohleSh8Beis9
# vagrant ssh
px_vagrant_ssh_id_rsa: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
If phx-vault-password
is not used (and so PX_ANSIBLE_VAULT_PASSWORD
is not
set), this will result in an error:
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ ansible-playbook plays/mgmt/ad.yml
[WARNING]: Error in vault password file loading (default): Vault password
client script /usr/local/bin/vault-client.sh returned non-zero (1) when getting
secret for vault-id=default: b"Error: PX_ANSIBLE_VAULT_PASSWORD is not set.
Please set it using 'set_vault_password' in your shell session.\n"
ERROR! Vault password client script /usr/local/bin/vault-client.sh returned non-zero (1) when getting secret for vault-id=default: b"Error: PX_ANSIBLE_VAULT_PASSWORD is not set. Please set it using 'set_vault_password' in your shell session.\n"
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$
Note that if ANSIBLE_VAULT_PASSWORD_FILE
is not set, this will result in a
message:
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ ansible-playbook plays/mgmt/ad.yml | tee provision.log
[WARNING]: Error getting vault password file (default): The vault password file
/home/tony@c2.org/git/gitlab/c2/ansible-phx/vpass was not found
ERROR! The vault password file /home/tony@c2.org/git/gitlab/c2/ansible-phx/vpass was not found
This is because in the PHX Ansible inventory project
c2platform/phx/ansible
in ansible.cfg
, there is a line with vault_password_file
:
vault_password_file=vpass
In inventory projects consumed by
Ansible Automation Platform ( AAP )
, this setting is
typically not made. But in the open-source PHX development environment, which
uses Vagrant, this file vpass
is created by Vagrant as you can see in the
Vagrantfile
. As this is only an Ansible development environment, security
is not a major concern; everything is open source, so the vault password is
secret
.
231# vpass file for Ansible vault secrets.yml
232vpass_file = File.join(File.dirname(__FILE__), 'vpass')
233File.open(vpass_file, 'w') { |f| f.write('secret') } unless File.exist? vpass_file
Additional Information
- Set Up Ansible with Kerberos on a PHX Development Desktop: In the air-gapped PHX domain, Kerberos is used for secure authentication. This extends to the Ansible Development Environment, which runs on an Ubuntu 22/24-based desktop. Kerberos offers convenience and security, especially when combined with forwardable tickets, eliminating the need for repeated password prompts.
- Managing Secrets with Ansible Vault in AAP / AWX: Learn how to effectively manage secrets using Ansible Vault in Ansible projects, particularly in the context of Red Hat Automation Platform (AAP) and AWX.
- Ansible Vault: Securely manage secrets using Ansible Vault.
- Ansible Inventory Project: An Ansible Inventory project contains inventory files, plays, host configurations, group variables, and vault files. It is also referred to as a playbook project or configuration project.
- Development Environment: Experience unparalleled flexibility and productivity through local development, a reality realized by embracing the “open, unless” approach.
- Using Vault in playbooks — Ansible Documentation
This is acceptable but not ideal for highly sensitive environments. If someone compromises your session (e.g., via malware), they could dump env vars. For production/automation, consider integrating with a secret manager like HashiCorp Vault, AWS Secrets Manager, or pass instead of manual input ↩︎
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.