Ansible is a great tool to automate mundane or complex tasks. It also allows code reuse by passing variables to roles or collections. This is important when sharing code across a large base of users.
However, sometimes those variables are credentials that are specific to a user's access or password rather than a service account credential like you might use in Ansible Automation Platform. You wouldn't want to share sensitive credentials with your team, let alone place them into a Git repo for the world to see. Sometimes these variables are derived from an environment file, such as your .bashrc. And they could be things you need to access from the shell, not only in an Ansible playbook.
This is where Ansible Vault comes into play. Ansible Vault is a command-line tool that allows you to encrypt and decrypt any structured data file. In this article, I'll show you how to protect your shell environment variables while making them available for your typical Bash commands and your Ansible playbooks, roles, and collections.
[ Download now: A sysadmin's guide to Bash scripting. ]
Use encrypted environment variables with Ansible
First, create a .bash_vault file in your home directory:
$ touch ~/.bash_vault
Next, append the following code to your .bashrc file:
export EDITOR=vi
BASH_VAULT=${HOME}/.bash_vault
function bash_vault.load(){
echo "Loading bash vault..."
source <(ansible-vault view ${BASH_VAULT})
}
function bash_vault.edit(){
ansible-vault edit ${BASH_VAULT}
}
function bash_vault.reload(){
echo "Reloading bash vault..."
source <(ansible-vault view ${BASH_VAULT})
}
After updating your .bashrc, create your secrets in the .bash_vault file. In this example, you want to keep your usernames, passwords, and destinations secret from prying eyes:
APP1_API_USERNAME='mike.wazowski'
APP1_API_PASSWORD='Ey3b4LL!'
APP1_API_URL='www.foo.com'
APP2_API_USERNAME='james.sullivan'
APP2_API_PASSWORD='H41rB4ll!'
APP2_API_URL='www.bar.com'
APP3_API_USERNAME='randall.boggs'
APP3_API_PASSWORD='Ch4m3l0N!'
APP3_API_URL='www.foobar.com'
export APP1_API_USERNAME APP1_API_PASSWORD APP1_API_URL APP2_API_USERNAME APP2_API_PASSWORD APP2_API_URL APP3_API_USERNAME APP3_API_PASSWORD APP3_API_URL
After updating your .bash_vault file, you must encrypt it using ansible-vault:
$ ansible-vault encrypt .bash_vault
New Vault password: ****
Confirm New Vault password: ****
Encryption successful
Now, validate you've encrypted the environment variables:
$ cat .bash_vault
$ANSIBLE_VAULT;1.1;AES256
66623436333962663336333666306230366230336465333865326363666232383365326233333836
6630393461333137633865303134616262353230636163330a386338366663633230343537303335
3635...shortened for brevity....
Reload your .bashrc file and reload the encrypted shell variables stored in .bash_vault using the functions available in your .bashrc file. You will be prompted for your Ansible Vault password:
$ source .bashrc
$ bash_vault.load
Loading bash vault...
Vault password: ****
Write a playbook showcasing how Ansible can access these variables:
- name: Example playbook to show vaulted shell variables
hosts: localhost
gather_facts: false
become: false
tasks:
- name: Debug app1 shell variables
ansible.builtin.debug:
msg:
- "{{ lookup('env','APP1_API_USERNAME') }}"
- "{{ lookup('env','APP1_API_PASSWORD') }}"
- "{{ lookup('env','APP1_API_URL') }}"
- name: Debug app2 shell variables
ansible.builtin.debug:
msg:
- "{{ lookup('env','APP2_API_USERNAME') }}"
- "{{ lookup('env','APP2_API_PASSWORD') }}"
- "{{ lookup('env','APP2_API_URL') }}"
- name: Debug app3 shell variables
ansible.builtin.debug:
msg:
- "{{ lookup('env','APP3_API_USERNAME') }}"
- "{{ lookup('env','APP3_API_PASSWORD') }}"
- "{{ lookup('env','APP3_API_URL') }}"
[ Write your first playbook in this hands-on interactive lab. ]
Finally, run the playbook to showcase the results:
$ ansible-playbook -i localhost, bash_vault_example.yml
PLAY [Example playbook to show vaulted shell variables] ************************
TASK [Debug app1 shell variables] **********************************************
ok: [localhost] => {
"msg": [
"mike.wazowski",
"Ey3b4LL!",
"www.foo.com"
]
}
TASK [Debug app2 shell variables] **********************************************
ok: [localhost] => {
"msg": [
"james.sullivan",
"H41rB4ll!",
"www.bar.com"
]
}
TASK [Debug app3 shell variables] **********************************************
ok: [localhost] => {
"msg": [
"randall.boggs",
"Ch4m3l30N!",
"www.foobar.com"
]
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Use variables on the command line
But wait, these are shell environment variables, so you can also access them using the command line outside of Ansible.
Typically when users run commands, Bash stores them in command history. You can override this using set +o history or clear it using history -c, but sometimes you need the history to recall previously executed long commands more easily.
By using Ansible Vault-created environment variables, the history shows the variable name but not the variable value. To test this, first execute a command that uses one of the variables:
# Run a curl command with our encrypted shell variables
$ curl -o /dev/null -s -w "%{http_code}\n" ${APP1_API_URL}
# CURL RESULTS
200
Then review the history to check that it shows the variable name and not the variable value:
# Run the history command to check our shell variables
$ history|tail -2|grep -v history
# HISTORY RESULTS
1034 curl -o /dev/null -s -w "%{http_code}\n" ${APP1_API_URL}
Change the vaulted variables
If you need to add, delete, modify, or review your Ansible Vault-created environment variables, call the bash_vault.edit function:
$ bash_vault.edit
Once you've completed the updates, reload the shell variables using the bash_vault.reload function:
$ bash_vault.reload
Finally, when you're done, you can just log out and know that your sensitive shell variables are safe from prying eyes. This is possible because your variables are encrypted at rest.
[ Get started with automation controller in this hands-on interactive lab. ]
Words of caution
Your variables are only as secure as your security practices, so keep the following in mind:
- Avoid logging your sensitive shell variables.
- Avoid writing the environment variables to your logs when running tasks.
- Use
no_log=truein your Ansible tasks - Avoid using redirects to a log like
>or|tee -a somelog
Here's an example of usingno_log=trueto protect your sensitive information:
- Use
# Protect your creds using no_log
- name: Debug keep passwords private shell variables using nolog
ansible.builtin.uri:
url: "{{ destination_url }}"
user: "{{ lookup('env','APP1_API_USERNAME') }}"
password: "{{ lookup('env','APP1_API_PASSWORD') }}"
no_log: true
- Never reveal your environment variable to stdout.
- Avoid printing your environment variables to stdout using the
envcommand orechocommands. This is especially important, when:- Using a shared resource like Ansible Automation Platform
- Using a shared system where others have admin access
- A tool like tlog has been implemented for terminal session logging
# AVOID DOING THIS
$ env|grep APP
APP3_API_USERNAME=randall.boggs
APP1_API_PASSWORD=Ey3b4LL!
APP3_API_URL=www.foobar.com
APP3_API_PASSWORD=Ch4m3l30N!
APP2_API_PASSWORD=H41rB4ll!
APP1_API_URL=www.foo.com
APP2_API_URL=www.bar.com
APP2_API_USERNAME=james.sullivan
APP1_API_USERNAME=mike.wazowski
# AVOID DOING THIS
$ echo $APP1_API_PASSWORD
Ey3b4LL!
Wrap up
Keeping your personal data, such as web tokens, passphrases, and passwords, safe from prying eyes is imperative. In this article, you learned how to encrypt Bash shell variables with Ansible Vault for use inside and outside of Ansible playbooks. This article provides a straightforward solution for keeping your personal credentials and data private using Ansible Vault.
Über den Autor
Randy Romero is a Senior Ansible Consultant and Red Hat Certified Architect at Red Hat where he specializes in IT automation with Ansible and Ansible Automation Platform. He has experience in the cable, insurance, and loyalty-marketing industries, having performed multiple roles starting with junior Systems Administrator all the way to Cloud Architect with over 27 years of experience in the IT industry.
Randy fervently advocates for automation with Ansible to increase an individual's ability to grow by removing mundane repeatable tasks that tend to stand in the way of a person's own professional development and growth. He is also motivated in his mission to evangelize automation through Ansible by changing the minds of people who say "This is how we've always done it'. In his spare time when he is not studying or working, he enjoys mentoring individuals (young and old) seeking to achieve their Red Hat Certified System Administrator and Red Hat Certified Engineer certifications. When he's not doing IT related things he enjoys watching/reading all things paranormal.
Ähnliche Einträge
Slash VM provisioning time on Red Hat Openshift Virtualization using Red Hat Ansible Automation Platform
Red Hat Ansible Automation Platform: Measuring Business Impact with Dashboard and Analytics
What Is Product Security? | Compiler
Technically Speaking | Security for the AI supply chain
Nach Thema durchsuchen
Automatisierung
Das Neueste zum Thema IT-Automatisierung für Technologien, Teams und Umgebungen
Künstliche Intelligenz
Erfahren Sie das Neueste von den Plattformen, die es Kunden ermöglichen, KI-Workloads beliebig auszuführen
Open Hybrid Cloud
Erfahren Sie, wie wir eine flexiblere Zukunft mit Hybrid Clouds schaffen.
Sicherheit
Erfahren Sie, wie wir Risiken in verschiedenen Umgebungen und Technologien reduzieren
Edge Computing
Erfahren Sie das Neueste von den Plattformen, die die Operations am Edge vereinfachen
Infrastruktur
Erfahren Sie das Neueste von der weltweit führenden Linux-Plattform für Unternehmen
Anwendungen
Entdecken Sie unsere Lösungen für komplexe Herausforderungen bei Anwendungen
Virtualisierung
Erfahren Sie das Neueste über die Virtualisierung von Workloads in Cloud- oder On-Premise-Umgebungen