Storing API keys, tokens, and passwords in your playbooks isn’t safe—especially if you keep your Ansible project in version control. That’s where Ansible Vault comes in. It lets you encrypt sensitive variables while still using them like any other part of your automation.
In this third part of the series, I’ll show you how I use Vault to securely manage secrets in my homelab setup. In this example, we’ll use Vault to store a Tailscale auth key, which one of my roles uses to authenticate a server into my private Tailscale network.
Suggested Directory Structure
Here’s how I structure my group variables folder:
1group_vars/
2├── all.yml # (optional) public/global variables
3└── vault.yml # encrypted secrets (Vault protected)
Create the Vault File
Create an encrypted file for your secrets:
1ansible-vault create group_vars/vault.yml
When the editor opens, enter something like:
1tailscale_auth_key: "tskey-REPLACE_ME"
Then save and close the editor. The file is now encrypted and safe to commit (if you’re careful with your vault password).
Use the Vault Variable in a Playbook
You can now use the secret just like any other variable:
1---
2- name: Check if tailscaled service is running
3 ansible.builtin.systemd:
4 name: tailscaled
5 register: tailscaled_service
6 changed_when: false
7 failed_when: false
8
9- name: Skip Tailscale Setup
10 ansible.builtin.meta: end_host
11 when: tailscaled_service.status.ActiveState == "active"
12
13- name: Check if Tailscale is installed
14 ansible.builtin.stat:
15 path: /usr/sbin/tailscale
16 register: tailscale_installed
17
18- name: Download Tailscale install script
19 ansible.builtin.get_url:
20 url: "{{ tailscale_install_url }}"
21 dest: /tmp/tailscale-install.sh
22 mode: '0755'
23 when: not tailscale_installed.stat.exists
24
25- name: Run Tailscale install script
26 ansible.builtin.command: /tmp/tailscale-install.sh
27 when: not tailscale_installed.stat.exists
28 changed_when: true
29 notify: Restart tailscaled
30
31- name: Ensure tailscaled is enabled and started
32 ansible.builtin.systemd:
33 name: tailscaled
34 enabled: true
35 state: started
36
37- name: Check Tailscale status
38 ansible.builtin.command: tailscale status
39 register: tailscale_status
40 changed_when: false
41 failed_when: false
42 when: tailscale_installed.stat.exists
43
44# The Tailscale auth key should be stored in an encrypted vault:
45# tailscale_auth_key: "tskey-YOUR_KEY_HERE"
46
47- name: Authenticate with Tailscale if logged out and auth key is provided
48 ansible.builtin.command: >
49 tailscale up --authkey={{ tailscale_auth_key }}
50 when:
51 - tailscale_auth_key is defined
52 - tailscale_auth_key | length > 0
53 - "'Logged out.' in tailscale_status.stdout"
54 changed_when: true
55
56- name: Enable Tailscale SSH on the host
57 ansible.builtin.command: tailscale up --ssh
58 when: tailscale_enable_ssh and tailscale_auth_key is defined and tailscale_installed.stat.exists
59 changed_when: true
60 tags:
61 - tailscale_ssh
Run the Playbook with Vault
In your playbook you need to reference where the vault file can be found.
1---
2# Enroll hosts into Tailscale network.
3- name: Enroll hosts into Tailscale
4 hosts: all
5 become: true
6 vars_files:
7 - ../group_vars/all/vault.yml
8 gather_facts: true
9 roles:
10 - tailscale
Once you’ve encrypted your secrets with Ansible Vault, you can run your playbook securely by providing the vault password at runtime:
1ansible-playbook playbooks/tailscale.yml --ask-vault-pass
This command will prompt you for the vault password before executing the playbook, ensuring your secrets are decrypted only when needed.
Editing or Updating the Vault
To edit your encrypted file later
1ansible-vault edit group_vars/all/vault.yml
To change the vault password
1ansible-vault rekey group_vars/all/vault.yml
Git Ignore Vault Files
Add this to your .gitignore
file to prevent secrets from being committed:
1group_vars/all/vault.yml
Recap
In this post, you:
- Learned what Ansible Vault is and why it matters
- Created an encrypted secrets file
- Used Vault variables in a real playbook
- Ran a playbook securely with password or file-based vault access
- Updated your
.gitignore
to protect sensitive data