Skip to content

Commit 83d473e

Browse files
authored
Merge pull request #25 from stackhpc/unseal
Improve initialisation and unsealing
2 parents 169f87e + 4f3b694 commit 83d473e

File tree

7 files changed

+134
-32
lines changed

7 files changed

+134
-32
lines changed

roles/vault/README.md

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,38 @@ s (default: Omitted)
3131
* `vault_extra_volumes`: List of `"<host_location>:<container_mountpoint>"`
3232
* `vault_tls_key`: Path to TLS key to use by Vault
3333
* `vault_tls_cert`: Path to TLS cert to use by Vault
34+
* `vault_log_keys`: Whether to log the root token and unseal keys in the Ansible output. Default `false`
35+
* `vault_set_keys_fact`: Whether to set a `vault_keys` fact containing the root token and unseal keys. Default `false`
36+
* `vault_write_keys_file`: Whether to write the root token and unseal keys to a file. Default `false`
37+
* `vault_write_keys_file_host`: Host on which to write root token and unseal keys. Default `localhost`
38+
* `vault_write_keys_file_path`: Path of file to write root token and unseal keys. Default `vault-keys.json`
3439

40+
Root and unseal keys
41+
--------------------
3542

43+
After Vault has been initialised, a root token and a set of unseal keys are emitted.
44+
It is very important to store these keys safely and securely.
45+
This role provides several mechanisms for extracting the root token and unseal keys:
46+
47+
1. Print to Ansible log output (`vault_log_keys`)
48+
1. Set a `vault_keys` fact (`vault_set_keys_fact`)
49+
1. Write to a file (`vault_write_keys_file`)
50+
51+
In each case, the output will contain the following:
52+
53+
```json
54+
{
55+
"keys": [
56+
"...",
57+
"..."
58+
],
59+
"keys_base64": [
60+
"...",
61+
"..."
62+
],
63+
"root_token": "..."
64+
}
65+
```
3666

3767
Example playbook (used with OpenStack Kayobe)
3868
---------------------------------------------
@@ -96,21 +126,4 @@ Example post-config playbook to enable secrets engines:
96126
run_once: True
97127
```
98128

99-
Example vault unseal playbook based on Kayobe's secrets.yml
100-
```
101-
---
102-
- name: Unseal vault
103-
any_errors_fatal: True
104-
gather_facts: True
105-
hosts: vault
106-
tasks:
107-
- name: Unseal vault
108-
hashivault_unseal:
109-
url: "https://sparrow.cf.ac.uk:8200"
110-
keys: "{{ item }}"
111-
run_once: True
112-
with_items: "{{ secrets_vault_keys.unseal_keys_b64 }}"
113-
no_log: True
114-
```
115-
116129
NOTE: secrets_external_tls_cert/key are variables in Kayobe's secrets.yml

roles/vault/defaults/main.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,16 @@ consul_extra_volumes: []
6868
# Combined volume lists
6969
_vault_volumes: "{{ _vault_default_volumes + vault_extra_volumes }}"
7070
_consul_volumes: "{{ _consul_default_volumes + consul_extra_volumes }}"
71+
72+
# Whether to log the root token and unseal keys in the Ansible output.
73+
vault_log_keys: false
74+
75+
# Whether to set a vault_keys fact containing the root token and unseal keys.
76+
vault_set_keys_fact: false
77+
78+
# Whether to write the root token and unseal keys to a file.
79+
vault_write_keys_file: false
80+
# Host on which to write root token and unseal keys.
81+
vault_write_keys_file_host: localhost
82+
# Path of file to write root token and unseal keys.
83+
vault_write_keys_file_path: vault-keys.json

roles/vault/tasks/vault.yml

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,36 @@
2222
register: vault_init_status
2323
retries: 50
2424
delay: 1
25+
run_once: true
2526
until: vault_init_status.status == 200
2627

27-
- name: Initialize vault
28-
hashivault_init:
29-
url: "{{ vault_api_addr }}"
30-
run_once: True
31-
no_log: True
32-
when: not vault_init_status.json.initialized
33-
register: vault_keys
28+
- block:
29+
- name: Initialize vault
30+
hashivault_init:
31+
url: "{{ vault_api_addr }}"
32+
no_log: true
33+
register: vault_keys_result
3434

35-
- name: Print vault keys
36-
debug:
37-
var: vault_keys
38-
when: not vault_init_status.json.initialized
35+
- name: Print vault keys
36+
debug:
37+
var: vault_keys_result
38+
when:
39+
- vault_log_keys | bool
3940

41+
- name: Set vault_keys fact
42+
set_fact:
43+
vault_keys: "{{ vault_keys_result }}"
44+
when:
45+
- vault_set_keys_fact | bool
46+
47+
- name: Write vault keys to a file
48+
copy:
49+
content: "{{ vault_keys_result | to_nice_json }}"
50+
dest: "{{ vault_write_keys_file_path }}"
51+
mode: 0600
52+
delegate_to: "{{ vault_write_keys_file_host }}"
53+
when:
54+
- vault_write_keys_file | bool
55+
run_once: true
56+
when:
57+
- not vault_init_status.json.initialized

roles/vault_unseal/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
This role unseals Hashicorp Vault.
2+
3+
Note that in a Vault cluster, each Vault server must be unsealed individually.
4+
5+
Requirements
6+
------------
7+
8+
``ansible-modules-hashivault`` PyPI package installed
9+
10+
Role variables
11+
--------------
12+
13+
* `vault_api_addr`: Vault [API addr](https://www.vaultproject.io/docs/configuration#api_addr) - Full URL including protocol and port (e.g. "http://127.0.0.1:8200"). In a Vault cluster, this should point to an individual Vault server, rather than a load balancer.
14+
* `vault_unseal_keys`: List of unseal key shards.
15+
16+
Example playbook
17+
----------------
18+
19+
Example vault unseal playbook:
20+
```
21+
---
22+
- name: Unseal vault
23+
any_errors_fatal: True
24+
gather_facts: True
25+
hosts: vault
26+
tasks:
27+
- name: Unseal vault
28+
import_role:
29+
name: stackhpc.vault_unseal
30+
vars:
31+
vault_api_addr: "https://vault.example.com"
32+
vault_keys: "{{ vault_keys.keys_base64 }}"
33+
```

roles/vault_unseal/defaults/main.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
# Allow vault_vip_url and vault_vip_address for backwards compatibility.
3+
vault_vip_address: "{{ vault_vip_url | default('') }}"
4+
vault_api_addr: "{{ ('https://' ~ vault_vip_address ~ ':8200') if vault_vip_address else '' }}"
5+
6+
# List of unseal key shards.
7+
vault_unseal_keys: []

roles/vault_unseal/tasks/main.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
- name: Unseal Vault
3+
hashivault_unseal:
4+
url: "{{ vault_api_addr }}"
5+
keys: "{{ vault_unseal_keys | join(' ') }}"

tests/test_vault.yml

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
- name: Prepare for vault role
33
gather_facts: True
44
hosts: consul
5+
vars:
6+
consul_bind_interface: lo
7+
vault_bind_address: 127.0.0.1
8+
vault_api_addr: http://127.0.0.1:8200
9+
vault_config_dir: "/etc/vault"
10+
vault_log_keys: true
11+
vault_set_keys_fact: true
12+
vault_write_keys_file: true
513
tasks:
614
- name: Ensure /etc/vault exists
715
file:
@@ -11,8 +19,13 @@
1119

1220
- include_role:
1321
name: vault
22+
23+
# Idempotence test
24+
- include_role:
25+
name: vault
26+
27+
- name: Unseal vault
28+
import_role:
29+
name: vault_unseal
1430
vars:
15-
consul_bind_interface: lo
16-
vault_bind_address: 127.0.0.1
17-
vault_api_addr: http://127.0.0.1:8200
18-
vault_config_dir: "/etc/vault"
31+
vault_keys: "{{ vault_keys.keys_base64 }}"

0 commit comments

Comments
 (0)