Skip to content

Instantly share code, notes, and snippets.

@tristanfisher
Last active April 3, 2024 13:55
Show Gist options
  • Save tristanfisher/e5a306144a637dc739e7 to your computer and use it in GitHub Desktop.
Save tristanfisher/e5a306144a637dc739e7 to your computer and use it in GitHub Desktop.
A short tutorial on how to use Vault in your Ansible workflow. Ansible-vault allows you to more safely store sensitive information in a source code repository or on disk.

Working with ansible-vault


I've been using a lot of Ansible lately and while almost everything has been great, finding a clean way to implement ansible-vault wasn't immediately apparent.

What I decided on was the following: put your secret information into a vars file, reference that vars file from your task, and encrypt the whole vars file using ansible-vault encrypt.

Let's use an example: You're writing an Ansible role and want to encrypt the spoiler for the movie Aliens.

Your Ansible role should have the following structure similar to the following:

roles/aliens
	├── tasks
	│   └── main.yml
	└── vars
		    └── spoilers.yml

First, put your spoiler text in a roles/aliens/vars/spoilers.yml:

---
spoiler_text: | 
  people run into some space aliens
  and they end up fighting them

(Note the pipe, followed by the new line with text indented by two spaces. This allows you to easily put multi-line text into a variable.)

Then, reference your spoiler_text variable in your task:

---
- include_vars: spoilers.yml

- name: Put the spoiler text in the tmp directory on the remote server.
  copy:
    content="{{spoiler_text}}"
    dest=/tmp/spoiler_text.txt

Encrypt your spoilers file using your vault password file on the command line:

$ ansible-vault encrypt roles/aliens/vars/spoilers.yml --vault-password-file ~/.vault_pass.txt
Encryption successful

You can now safely put this file in your source control without spoiling the movie for everyone.

$ head -n3 aliens/vars/spoilers.yml
$ANSIBLE_VAULT;1.1;AES256
61616366326131636131323230613333356361333737356566646133343062623061313931666462
3933316533346664393430643963646533663737343434320a613862353665663862393939383336
...

Then, given a playbook that looks like:

---
# file: movies.yml
- hosts: all

  roles:
    - { role: aliens }

You can now run this against your server:

$ ansible-playbook -i inventory/development.hosts playbooks/movies.yml --vault-password-file ~/.vault_pass.txt

That's it! Hop on the server and you can see that the decrypted content is there on disk:

remote_server$ cat /tmp/spoiler_text.txt 
people run into some space aliens
and they end up fighting them

This is useful for more than just movie spoilers -- I use this approach to copy over my deploy-keys to make continuous integration and simple deployments a reality.

26-April-2016 edit: There's now a "best practice" document that may be interesting to you if you're reading this tutorial: http://docs.ansible.com/ansible/playbooks_best_practices.html#best-practices-for-variables-and-vaults

@dgolja
Copy link

dgolja commented Dec 1, 2015

hmmm but how can you reuse the same role on a different group of hosts with a different secret ?

@depend
Copy link

depend commented Dec 21, 2015

I wish all Ansible official documents were written like this...

@gvenka008c
Copy link

I am using ansible v 2.0.0.2. we encrypt the file using ansible-vault. When we run the playbook as below, the file on the server is showing encrypted as well. Is this expected behaviour? or the file is supposed to be in decrypted plain text format?

ansible-playbook -i inventory/openstack.py jenkins_mesos_master.yml --vault-password-file vault_pass.txt

Thanks,
Govind

@bonovoxly
Copy link

Just thought I'd chime into a really nice post...

@n1tr0g

I like to put my vault files in either ./group_vars/all/vault.yml or ./host_vars/127.0.0.1/vault.yml. This way I avoid any include_vars for my playbooks. I actually put all my variables in those paths. Just another way of doing things (heart ansible).

@knepperjm
Copy link

For real thanks! This should be in Ansible's documentation for vault. I'm glad you took care of it for them ;)

@xamox
Copy link

xamox commented Jun 2, 2016

Thanks!

@zx1986
Copy link

zx1986 commented Aug 21, 2016

@therealmarv
Copy link

therealmarv commented Jan 28, 2017

There is something important missing: no_log: true. For vault encrypted stuff it is useful to hide log output (because it's a secret) ;) otherwise it can be made visible with -vvvv in the deployment logs or maybe in error messages.

This would be better:

---
- include_vars: spoilers.yml
  no_log: true

- name: Put the spoiler text in the tmp directory on the remote server.
  copy:
    content="{{spoiler_text}}"
    dest=/tmp/spoiler_text.txt
  no_log: true

I've also written a blog post about this topic 2015: https://therealmarv.com/ansible-vault-file-handling/

@csc-bnguyen43
Copy link

Thanks, nice explanation

@TumTum
Copy link

TumTum commented Feb 28, 2017

Thanks!!!

@libert-xyz
Copy link

awesome

@martymac
Copy link

Hey, you just spoiled Aliens ;-) Thanks for those explanations !

@webknjaz
Copy link

There's also ansible-vault encrypt_string available now. You may inline encrypted values by injecting them into your yaml files with !vault tag.
N.B. Use v2.3.1.0+ for this.

@ekim197711
Copy link

Damn nice document. And great follow up comments like encrypt_string features.

@rfederici
Copy link

This is a fantastic little tutorial. Thank you so much!

@luisffc
Copy link

luisffc commented Sep 11, 2017

Awesome! Helped a lot

@jlhopkinsjr
Copy link

This little tutorial was incredible helpful thanks!!

@tdavison784
Copy link

Thanks for sharing! Great post to help get started and understand how vault works!

  • cheers!

@kanapuli
Copy link

Thanks ! Great post

@sgnl
Copy link

sgnl commented Apr 26, 2018

Very nice Thanks

(someone update the header markdown code plz lol)

@bennykusman
Copy link

thanks for sharing!

@tristanfisher
Copy link
Author

@sgnl Sorry, fixed the cosmetic typo in the markdown.

@yungezz
Copy link

yungezz commented Jun 4, 2018

thanks for sharing, very useful!

@siseko
Copy link

siseko commented Aug 18, 2018

@tristanfisher Great write up thank you! What's best practice for managing vault passwords if you're in a team? My teammates would need to know the vault password to run playbooks.

@queglay
Copy link

queglay commented Feb 23, 2019

This is great! my only question as someone new to this would be including an example of the ~/ansible_pass.txt file too.

@DEVxALMIGHTY
Copy link

@queglay its simply a file with an encrypted password in it
@siseko maybe a shared pwd manager with a decent enterprise solution ... lastpass ?

@aminvakil
Copy link

Still helpful in 2020, thanks!

@petrmalkov
Copy link

petrmalkov commented Oct 27, 2020

how to create empty encrypted vault file from playbook?

@mrchief
Copy link

mrchief commented Nov 7, 2020

You can also use a tool like groupsecret to share vault password between team members

@ztnel
Copy link

ztnel commented Apr 22, 2021

cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment