Unsealing HashiCorp Vault cluster with a Ansible Playbook
One of the downsides with having a clustered HashiCorp Vault, like I set up last year, is that each host has to be unsealed individually. Doing this from the command line requires specifying the URL of each host to the vault command, sending each of the 3 keys needed to unseal the vault then moving on to the next one. I made an Ansible playbook to do it with an API call, targeting the hosts from the inventory and reading the keys once as variables to unlock all of the hosts.
The playbook itself is actually really, really simple (so much so, I don’t think it needs any explanation!):
- name: Unseal the vault on all nodes in HA cluster
hosts: hashicorp_vault_servers
vars_prompt:
# Assumes 3 keys needed to unseal - this might not be the case...
- name: unseal_key_1
prompt: Enter unseal key 1
private: true
- name: unseal_key_2
prompt: Enter unseal key 2
private: true
- name: unseal_key_3
prompt: Enter unseal key 3
private: true
tasks:
- name: Enter unseal keys
delegate_to: localhost
ansible.builtin.uri:
body:
key: "{{ item }}"
body_format: json
force: true
method: PUT
url: "https://{{ ansible_facts.fqdn }}:8200/v1/sys/unseal"
loop:
- '{{ unseal_key_1 }}'
- '{{ unseal_key_2 }}'
- '{{ unseal_key_3 }}'
loop_control:
extended: true
label: "key {{ ansible_loop.index }}/{{ ansible_loop.length }}"
Only unlocking a subset of hosts, e.g. if one gets rebooted, can be done by passing -l to ansible-playbook to limit the hosts being targetted.
Simple, convenient and so far reliable. I like this playbook and am mildly proud of it!