Skip to content

Commit bc83165

Browse files
authored
Merge pull request #1090 from stackhpc/2023.1-vault-without-haproxy
2023.1: Various fixes & improvements to HCP Vault
2 parents f4d30a9 + 334b663 commit bc83165

16 files changed

+190
-147
lines changed

doc/source/configuration/vault.rst

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -84,47 +84,6 @@ Setup Vault on the seed node
8484
ansible-vault encrypt --vault-password-file ~/vault.pass $KAYOBE_CONFIG_PATH/environments/$KAYOBE_ENVIRONMENT/vault/seed-vault-keys.json
8585
ansible-vault encrypt --vault-password-file ~/vault.pass $KAYOBE_CONFIG_PATH/environments/$KAYOBE_ENVIRONMENT/vault/overcloud.key
8686
87-
Setup HAProxy config for Vault
88-
------------------------------
89-
90-
1. Create the HAProxy config to reverse proxy the Vault HA container
91-
92-
Set the vault_front to the external VIP address or internal VIP address depending on the installation. Set the vault_back to the IPs of the control nodes.
93-
94-
Set the following in etc/kayobe/kolla/config/haproxy/services.d/vault.cfg or if environments are being used etc/kayobe/environments/$KAYOBE_ENVIRONMENT/kolla/config/haproxy/services.d/vault.cfg
95-
96-
.. code-block::
97-
98-
# Delete "verify none" if not using self-signed/unknown issuer
99-
{% raw %}
100-
frontend vault_front
101-
mode tcp
102-
option tcplog
103-
bind {{ kolla_internal_vip_address }}:8200
104-
default_backend vault_back
105-
106-
backend vault_back
107-
mode tcp
108-
option httpchk GET /v1/sys/health
109-
# https://www.vaultproject.io/api-docs/system/health
110-
# 200: initialized, unsealed, and active
111-
# 501: not initialised (required for bootstrapping)
112-
# 503: sealed (required for bootstrapping)
113-
http-check expect rstatus (200|501|503)
114-
115-
{% for host in groups['control'] %}
116-
{% set host_name = hostvars[host].ansible_facts.hostname %}
117-
{% set host_ip = 'api' | kolla_address(host) %}
118-
server {{ host_name }} {{ host_ip }}:8200 check check-ssl verify none inter 2000 rise 2 fall 5
119-
{% endfor %}
120-
{% endraw %}
121-
122-
2. Deploy HAProxy with the new Vault service configuration:
123-
124-
.. code-block::
125-
126-
kayobe overcloud service deploy --skip-tags os_capacity -kt haproxy
127-
12887
Setup Vault HA on the overcloud hosts
12988
-------------------------------------
13089

@@ -215,6 +174,55 @@ Create the backend TLS and RabbitMQ TLS certificates
215174
216175
ansible-vault encrypt --vault-password-file ~/vault.pass $KAYOBE_CONFIG_PATH/environments/$KAYOBE_ENVIRONMENT/kolla/certificates/<controller>-key.pem
217176
177+
.. _vault-haproxy:
178+
179+
HAProxy integration
180+
===================
181+
182+
It is possible to expose the overcloud Vault service via the Kolla Ansible HAProxy load balancer.
183+
This provides a single highly available API endpoint, as well as monitoring of the Vault backends when combined with Prometheus.
184+
HAProxy integration is no longer required for generating OpenStack control plane certificates, making it possible to deploy Vault and generate certificates before any containers have been deployed by Kolla Ansible.
185+
186+
1. Create the HAProxy config to reverse proxy the Vault HA container
187+
188+
Set the vault_front to the external VIP address or internal VIP address depending on the installation. Set the vault_back to the IPs of the control nodes.
189+
190+
Set the following in etc/kayobe/kolla/config/haproxy/services.d/vault.cfg or if environments are being used etc/kayobe/environments/$KAYOBE_ENVIRONMENT/kolla/config/haproxy/services.d/vault.cfg
191+
192+
.. code-block::
193+
194+
# Delete "verify none" if not using self-signed/unknown issuer
195+
{% raw %}
196+
frontend vault_front
197+
mode tcp
198+
option tcplog
199+
bind {{ kolla_internal_vip_address }}:8200
200+
default_backend vault_back
201+
202+
backend vault_back
203+
mode tcp
204+
option httpchk GET /v1/sys/health
205+
# https://www.vaultproject.io/api-docs/system/health
206+
# 200: initialized, unsealed, and active
207+
# 429: standby
208+
http-check expect rstatus (200|429)
209+
210+
{% for host in groups['control'] %}
211+
{% set host_name = hostvars[host].ansible_facts.hostname %}
212+
{% set host_ip = 'api' | kolla_address(host) %}
213+
server {{ host_name }} {{ host_ip }}:8200 check check-ssl verify none inter 2000 rise 2 fall 5
214+
{% endfor %}
215+
{% endraw %}
216+
217+
2. If HAProxy has not yet been deployed, continue to :ref:`certificates deployment <vault-certificates>`.
218+
If HAProxy has been deployed, it may be redeployed with the new Vault service configuration:
219+
220+
.. code-block::
221+
222+
kayobe overcloud service deploy -kt haproxy
223+
224+
.. _vault-certificates:
225+
218226
Certificates deployment
219227
=======================
220228

@@ -231,6 +239,7 @@ Enable the required TLS variables in kayobe and kolla
231239
232240
# Whether TLS is enabled for the external API endpoints. Default is 'no'.
233241
kolla_enable_tls_external: yes
242+
kolla_public_openrc_cacert: "{{ '/etc/pki/tls/certs/ca-bundle.crt' if os_distribution in ['centos', 'rocky'] else '/etc/ssl/certs/ca-certificates.crt' }}"
234243
235244
See :ref:`tempest-cacert` for information on adding CA certificates to the trust store when running Tempest.
236245

@@ -240,6 +249,7 @@ Enable the required TLS variables in kayobe and kolla
240249
241250
# Whether TLS is enabled for the internal API endpoints. Default is 'no'.
242251
kolla_enable_tls_internal: yes
252+
kolla_admin_openrc_cacert: "{{ '/etc/pki/tls/certs/ca-bundle.crt' if os_distribution in ['centos', 'rocky'] else '/etc/ssl/certs/ca-certificates.crt' }}"
243253
244254
See :ref:`os-capacity` for information on adding CA certificates to the trust store when deploying the OpenStack Capacity exporter.
245255

@@ -291,6 +301,8 @@ Enable the required TLS variables in kayobe and kolla
291301
Barbican integration
292302
====================
293303

304+
Barbican integration depends on :ref:`HAProxy integration <vault-haproxy>`.
305+
294306
Enable Barbican in kayobe
295307
-------------------------
296308

@@ -341,7 +353,7 @@ Configure Barbican
341353
enabled_secretstore_plugins=vault_plugin
342354
343355
[vault_plugin]
344-
vault_url = https://{{ kolla_internal_vip_address }}:8200
356+
vault_url = https://{{ kolla_internal_fqdn }}:8200
345357
use_ssl = True
346358
{% raw %}
347359
ssl_ca_crt_file = {{ openstack_cacert }}

etc/kayobe/ansible/requirements.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ collections:
99
- name: stackhpc.pulp
1010
version: 0.5.5
1111
- name: stackhpc.hashicorp
12-
version: 2.4.0
12+
version: 2.5.0
1313
- name: stackhpc.kayobe_workflows
1414
version: 1.0.3
1515
roles:

etc/kayobe/ansible/vault-deploy-barbican.yml

Lines changed: 72 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
gather_facts: True
55
hosts: controllers[0]
66
vars:
7-
vault_api_addr: "https://{{ kolla_internal_fqdn }}:8200"
7+
vault_api_addr: "https://{{ internal_net_name | net_ip }}:8200"
88
vault_ca_cert: "{{ '/etc/pki/tls/certs/ca-bundle.crt' if ansible_facts.os_family == 'RedHat' else '/usr/local/share/ca-certificates/OS-TLS-ROOT.crt' }}"
99
tasks:
1010
- name: Assert that secrets_barbican_approle_secret_id is defined
@@ -25,79 +25,82 @@
2525
extra_args: "{% if pip_upper_constraints_file %}-c {{ pip_upper_constraints_file }}{% endif %}"
2626
virtualenv: "{{ virtualenv_path }}/kayobe"
2727

28-
- name: Enable AppRole auth module
29-
hashivault_auth_method:
30-
url: "{{ vault_api_addr }}"
31-
ca_cert: "{{ vault_ca_cert }}"
32-
token: "{{ vault_keys.root_token }}"
33-
method_type: approle
34-
state: enabled
28+
- environment:
29+
https_proxy: ''
30+
block:
31+
- name: Enable AppRole auth module
32+
hashivault_auth_method:
33+
url: "{{ vault_api_addr }}"
34+
ca_cert: "{{ vault_ca_cert }}"
35+
token: "{{ vault_keys.root_token }}"
36+
method_type: approle
37+
state: enabled
3538

36-
- name: Enable barbican kv store
37-
hashivault_secret_engine:
38-
url: "{{ vault_api_addr }}"
39-
ca_cert: "{{ vault_ca_cert }}"
40-
token: "{{ vault_keys.root_token }}"
41-
name: barbican
42-
backend: kv
43-
description: "Barbican kv store"
39+
- name: Enable barbican kv store
40+
hashivault_secret_engine:
41+
url: "{{ vault_api_addr }}"
42+
ca_cert: "{{ vault_ca_cert }}"
43+
token: "{{ vault_keys.root_token }}"
44+
name: barbican
45+
backend: kv
46+
description: "Barbican kv store"
4447

45-
- name: Ensure barbican policy is defined
46-
hashivault_policy:
47-
url: "{{ vault_api_addr }}"
48-
ca_cert: "{{ vault_ca_cert }}"
49-
token: "{{ vault_keys.root_token }}"
50-
name: "barbican-policy"
51-
state: present
52-
rules: |
53-
path "barbican/*" {
54-
capabilities = ["create", "read", "update", "delete", "list"]
55-
}
48+
- name: Ensure barbican policy is defined
49+
hashivault_policy:
50+
url: "{{ vault_api_addr }}"
51+
ca_cert: "{{ vault_ca_cert }}"
52+
token: "{{ vault_keys.root_token }}"
53+
name: "barbican-policy"
54+
state: present
55+
rules: |
56+
path "barbican/*" {
57+
capabilities = ["create", "read", "update", "delete", "list"]
58+
}
5659
57-
- name: Ensure barbican AppRole is defined
58-
hashivault_approle_role:
59-
url: "{{ vault_api_addr }}"
60-
ca_cert: "{{ vault_ca_cert }}"
61-
token: "{{ vault_keys.root_token }}"
62-
bind_secret_id: true
63-
secret_id_bound_cidrs: "{{ internal_net_name | net_cidr }}"
64-
secret_id_ttl: 0
65-
token_policies: barbican-policy
66-
name: barbican
60+
- name: Ensure barbican AppRole is defined
61+
hashivault_approle_role:
62+
url: "{{ vault_api_addr }}"
63+
ca_cert: "{{ vault_ca_cert }}"
64+
token: "{{ vault_keys.root_token }}"
65+
bind_secret_id: true
66+
secret_id_bound_cidrs: "{{ internal_net_name | net_cidr }}"
67+
secret_id_ttl: 0
68+
token_policies: barbican-policy
69+
name: barbican
6770

68-
- name: Get barbican Approle ID
69-
hashivault_approle_role_id:
70-
url: "{{ vault_api_addr }}"
71-
ca_cert: "{{ vault_ca_cert }}"
72-
token: "{{ vault_keys.root_token }}"
73-
name: barbican
74-
register: barbican_role_id
71+
- name: Get barbican Approle ID
72+
hashivault_approle_role_id:
73+
url: "{{ vault_api_addr }}"
74+
ca_cert: "{{ vault_ca_cert }}"
75+
token: "{{ vault_keys.root_token }}"
76+
name: barbican
77+
register: barbican_role_id
7578

76-
- name: Print barbican Approle ID
77-
debug:
78-
msg: "barbican role id is {{ barbican_role_id.id }}"
79+
- name: Print barbican Approle ID
80+
debug:
81+
msg: "barbican role id is {{ barbican_role_id.id }}"
7982

80-
- name: Write barbican Approle ID to file if requested
81-
delegate_to: localhost
82-
copy:
83-
content: "{{ barbican_role_id.id }}"
84-
dest: "{{ stackhpc_barbican_role_id_file_path | default('~/barbican-role-id') }}"
85-
when: stackhpc_write_barbican_role_id_to_file | default(false) | bool
83+
- name: Write barbican Approle ID to file if requested
84+
delegate_to: localhost
85+
copy:
86+
content: "{{ barbican_role_id.id }}"
87+
dest: "{{ stackhpc_barbican_role_id_file_path | default('~/barbican-role-id') }}"
88+
when: stackhpc_write_barbican_role_id_to_file | default(false) | bool
8689

87-
- name: Check if barbican Approle Secret ID is defined
88-
hashivault_approle_role_secret_get:
89-
url: "{{ vault_api_addr }}"
90-
ca_cert: "{{ vault_ca_cert }}"
91-
token: "{{ vault_keys.root_token }}"
92-
secret: "{{ secrets_barbican_approle_secret_id }}"
93-
name: barbican
94-
register: barbican_approle_secret_get
90+
- name: Check if barbican Approle Secret ID is defined
91+
hashivault_approle_role_secret_get:
92+
url: "{{ vault_api_addr }}"
93+
ca_cert: "{{ vault_ca_cert }}"
94+
token: "{{ vault_keys.root_token }}"
95+
secret: "{{ secrets_barbican_approle_secret_id }}"
96+
name: barbican
97+
register: barbican_approle_secret_get
9598

96-
- name: Ensure barbican AppRole Secret ID is defined
97-
hashivault_approle_role_secret:
98-
url: "{{ vault_api_addr }}"
99-
ca_cert: "{{ vault_ca_cert }}"
100-
token: "{{ vault_keys.root_token }}"
101-
secret: "{{ secrets_barbican_approle_secret_id }}"
102-
name: barbican
103-
when: barbican_approle_secret_get.status == "absent"
99+
- name: Ensure barbican AppRole Secret ID is defined
100+
hashivault_approle_role_secret:
101+
url: "{{ vault_api_addr }}"
102+
ca_cert: "{{ vault_ca_cert }}"
103+
token: "{{ vault_keys.root_token }}"
104+
secret: "{{ secrets_barbican_approle_secret_id }}"
105+
name: barbican
106+
when: barbican_approle_secret_get.status == "absent"

etc/kayobe/ansible/vault-deploy-overcloud.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,12 @@
8585
- import_role:
8686
name: stackhpc.hashicorp.vault_unseal
8787
vars:
88-
# NOTE: Need to unseal each backend, so don't use the VIP
89-
vault_api_addr: "http://localhost:8200"
88+
vault_api_addr: "https://{{ internal_net_name | net_ip }}:8200"
89+
vault_unseal_token: "{{ vault_keys.root_token }}"
90+
vault_unseal_ca_cert: "{{ '/etc/pki/tls/certs/ca-bundle.crt' if ansible_facts.os_family == 'RedHat' else '/usr/local/share/ca-certificates/OS-TLS-ROOT.crt' }}"
9091
vault_unseal_keys: "{{ vault_keys.keys_base64 }}"
92+
environment:
93+
https_proxy: ''
9194

9295
- name: Configure PKI
9396
any_errors_fatal: true
@@ -108,3 +111,5 @@
108111
vault_pki_intermediate_roles: "{{ overcloud_vault_pki_roles }}"
109112
vault_pki_write_certificate_files: true
110113
vault_pki_certificates_directory: "{{ kayobe_env_config_path }}/vault"
114+
environment:
115+
https_proxy: ''

etc/kayobe/ansible/vault-generate-backend-tls.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
- name: Generate backend API certificates
1919
hosts: controllers:network
2020
vars:
21-
vault_api_addr: "https://{{ kolla_internal_fqdn }}:8200"
21+
vault_api_addr: "https://{{ internal_net_name | net_ip }}:8200"
2222
vault_intermediate_ca_name: "OS-TLS-INT"
2323
tasks:
2424
- name: Set a fact about the virtualenv on the remote system
@@ -53,6 +53,8 @@
5353
extra_params:
5454
ip_sans: "{{ internal_net_name | net_ip }}"
5555
register: backend_cert
56+
environment:
57+
https_proxy: ''
5658

5759
- name: Ensure certificates directory exists
5860
file:

etc/kayobe/ansible/vault-generate-internal-tls.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
hosts: controllers
44
run_once: true
55
vars:
6-
vault_api_addr: "https://{{ kolla_internal_fqdn }}:8200"
6+
vault_api_addr: "https://{{ internal_net_name | net_ip }}:8200"
77
vault_intermediate_ca_name: "OS-TLS-INT"
88
tasks:
99
- name: Include Vault keys
@@ -22,6 +22,8 @@
2222
extra_params:
2323
ip_sans: "{{ kolla_internal_vip_address }}"
2424
register: internal_cert
25+
environment:
26+
https_proxy: ''
2527

2628
- name: Ensure certificates directory exists
2729
file:

etc/kayobe/ansible/vault-generate-test-external-tls.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
hosts: controllers
44
run_once: true
55
vars:
6-
vault_api_addr: "https://{{ kolla_internal_fqdn }}:8200"
6+
vault_api_addr: "https://{{ internal_net_name | net_ip }}:8200"
77
# NOTE: Using the same CA as internal TLS.
88
vault_intermediate_ca_name: "OS-TLS-INT"
99
tasks:
@@ -23,6 +23,8 @@
2323
extra_params:
2424
ip_sans: "{{ kolla_external_vip_address }}"
2525
register: external_cert
26+
environment:
27+
https_proxy: ''
2628

2729
- name: Ensure certificates directory exists
2830
file:

etc/kayobe/ansible/vault-unseal-overcloud.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
- import_role:
2929
name: stackhpc.hashicorp.vault_unseal
3030
vars:
31-
# NOTE: Need to unseal each backend, so don't use the VIP
32-
vault_api_addr: "http://localhost:8200"
31+
vault_api_addr: "https://{{ internal_net_name | net_ip }}:8200"
32+
vault_unseal_token: "{{ vault_keys.root_token }}"
33+
vault_unseal_ca_cert: "{{ '/etc/pki/tls/certs/ca-bundle.crt' if ansible_facts.os_family == 'RedHat' else '/usr/local/share/ca-certificates/OS-TLS-ROOT.crt' }}"
3334
vault_unseal_keys: "{{ vault_keys.keys_base64 }}"
35+
environment:
36+
https_proxy: ''

0 commit comments

Comments
 (0)