Skip to content

Commit

Permalink
perf: ⚡ enable vault ha
Browse files Browse the repository at this point in the history
  • Loading branch information
this-is-tobi committed Jun 7, 2024
1 parent 9d5165c commit d90ee55
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 402 deletions.
45 changes: 18 additions & 27 deletions roles/vault/tasks/check.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
---
- name: Get vault health
ansible.builtin.uri:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
url: https://{{ vault_domain }}/v1/sys/health?sealedcode=200&uninitcode=200
status_code: [200, 503]
- name: Get vault status
kubernetes.core.k8s_exec:
container: vault
pod: "{{ vault_pod }}"
namespace: "{{ dsc.vault.namespace }}"
command: vault status -format=json
register: vault_health
retries: 12
delay: 5
until: vault_health.json is defined
ignore_errors: true

- name: Set vault_status to unavailable
- name: Set vault_status to "not init"
ansible.builtin.set_fact:
vault_status: unavailable
when: vault_health.status == 503
vault_status: not init
when: vault_health.stdout | from_json | json_query('initialized') == false

- name: If Vault json is defined
when: vault_health.json is defined
block:
- name: Set vault_status to sealed
ansible.builtin.set_fact:
vault_status: sealed
when: vault_health.json.sealed

- name: Set vault_status to "not init"
ansible.builtin.set_fact:
vault_status: not init
when: not vault_health.json.initialized
- name: Set vault_status to sealed
ansible.builtin.set_fact:
vault_status: sealed
when: (vault_health.stdout | from_json | json_query('initialized') == true) and (vault_health.stdout | from_json | json_query('sealed') == true)

- name: Set vault_status to OK
ansible.builtin.set_fact:
vault_status: OK
when: vault_health.json.initialized and not vault_health.json.sealed
- name: Set vault_status to OK
ansible.builtin.set_fact:
vault_status: OK
when: (vault_health.stdout | from_json | json_query('initialized') == true) and (vault_health.stdout | from_json | json_query('sealed') == false)
289 changes: 6 additions & 283 deletions roles/vault/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,4 @@
---
- name: Get Vault namespace
kubernetes.core.k8s_info:
kind: Namespace
name: "{{ dsc.vault.namespace }}"
register: vault_ns

- name: Get initial Vault config
when: vault_ns.resources | length > 0
kubernetes.core.k8s_info:
kind: ConfigMap
namespace: "{{ dsc.vault.namespace }}"
name: "{{ dsc_name }}-vault-config"
register: initial_vault_conf

- name: Preinstall check
ansible.builtin.include_tasks:
file: preinstall_check.yml

- name: Create Vault namespace
kubernetes.core.k8s:
state: present
Expand Down Expand Up @@ -56,269 +38,10 @@
with_items:
- ingress.yaml.j2

- name: Wait vault container
kubernetes.core.k8s:
kind: Pod
name: "{{ dsc_name }}-vault-0"
namespace: "{{ dsc.vault.namespace }}"
wait: true
wait_sleep: 10
wait_timeout: 600
wait_condition:
reason:
type: Initialized
status: "True"

- name: Find vault keys
kubernetes.core.k8s_info:
namespace: "{{ dsc.vault.namespace }}"
kind: Secret
name: "{{ dsc_name }}-vault-keys"
register: vault_keys

- name: Wait Vault URL
ansible.builtin.uri:
url: https://{{ vault_domain }}
method: GET
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
status_code: [200, 202]
return_content: false
register: vault_response
until: vault_response is not failed
retries: 15
delay: 5

- name: Check Vault health
ansible.builtin.include_tasks:
file: check.yml

- name: Check if vault is coherent
ansible.builtin.assert:
that:
- ((vault_status in ['sealed', 'OK']) and (vault_keys.resources | length > 0)) or ((vault_status == 'not init') and (vault_keys.resources | length == 0))
fail_msg:
- Attention ! Soit le vault n'est pas initialisé mais vous avez un secret vault-keys dans {{ dsc.vault.namespace }}
- Veuillez le suppripmer et relancer si vous souhaitez lancer une initialisation
- Soit le vault est initialisé mais vous n'avez pas de secret vault-keys dans {{ dsc.vault.namespace }}, et c'est inquiétant !

- name: Init vault
kubernetes.core.k8s_exec:
container: vault
pod: "{{ dsc_name }}-vault-0"
namespace: "{{ dsc.vault.namespace }}"
command: vault operator init -key-shares=3 -key-threshold=2
when: vault_status == 'not init'
register: init
until: init is not failed
retries: 1
delay: 10

- name: Store vault keys
kubernetes.core.k8s:
definition:
kind: Secret
metadata:
name: "{{ dsc_name }}-vault-keys"
namespace: "{{ dsc.vault.namespace }}"
data:
key1: "{{ init.stdout_lines[0] | regex_replace('^Unseal Key 1: (.*)$', '\\1', multiline=True) | b64encode }}"
key2: "{{ init.stdout_lines[1] | regex_replace('^Unseal Key 2: (.*)$', '\\1', multiline=True) | b64encode }}"
key3: "{{ init.stdout_lines[2] | regex_replace('^Unseal Key 3: (.*)$', '\\1', multiline=True) | b64encode }}"
root_token: "{{ init.stdout_lines[4] | regex_replace('^Initial Root Token: (.*)$', '\\1', multiline=True) | b64encode }}"
when: vault_keys.resources | length == 0

- name: Preinstall check
ansible.builtin.include_tasks:
file: preinstall_check.yml

- name: "Config: get auth method"
ansible.builtin.uri:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
url: https://{{ vault_domain }}/v1/sys/auth/jwt
status_code: [200, 400]
headers:
X-Vault-Token: "{{ root_token }}"
register: jwt_state
retries: 5

- name: "Config: set auth method"
when: jwt_state.status == 400
ansible.builtin.uri:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
url: https://{{ vault_domain }}/v1/sys/auth/jwt
method: POST
status_code: [204]
headers:
X-Vault-Token: "{{ root_token }}"
body:
type: jwt
description: Login for Gitlab-ci
body_format: json

- name: "Config: add role default-ci"
ansible.builtin.uri:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
url: https://{{ vault_domain }}/v1/auth/jwt/role/default-ci
method: POST
status_code: [204]
headers:
X-Vault-Token: "{{ root_token }}"
Content-Type: application/json
body:
role_type: jwt
policies:
- default-ci
token_explicit_max_ttl: 60
bound_claims_type: glob
user_claim: user_email
bound_claims:
iss: "{{ gitlab_domain }}"
claim_mappings:
namespace_path: namespace_path
project_path: project_path
project_id: project_id
ref: ref
body_format: json
# Post install
- name: Post install
ansible.builtin.include_tasks: post-install.yml

- name: "Config: set jwt config"
ansible.builtin.uri:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
url: https://{{ vault_domain }}/v1/auth/jwt/config
method: POST
status_code: [204]
headers:
X-Vault-Token: "{{ root_token }}"
body:
oidc_discovery_url: https://{{ gitlab_domain }}
oidc_discovery_ca_pem: "{{ exposed_ca_pem }}"
default_role: default-ci
namespace_in_state: false
body_format: json

- name: "Config: get accessor jwt config"
ansible.builtin.uri:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
url: https://{{ vault_domain }}/v1/sys/auth/jwt
status_code: [200]
headers:
X-Vault-Token: "{{ root_token }}"
register: get_accessor

- name: "Config: create policy"
ansible.builtin.uri:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
url: https://{{ vault_domain }}/v1/sys/policy/default-ci
method: POST
status_code: [204]
headers:
X-Vault-Token: "{{ root_token }}"
body:
policy: |
path "forge-dso/+/{{ '{{' }}identity.entity.aliases.{{ get_accessor.json.accessor }}.metadata.namespace_path{{ '}}' }}/*" {
capabilities = ["list","read"]
}
path "forge-dso/+/{{ '{{' }}identity.entity.aliases.{{ get_accessor.json.accessor }}.metadata.namespace_path{{ '}}' }}" {
capabilities = ["list","read"]
}
body_format: json

- name: "Config: get kv engines"
ansible.builtin.uri:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
url: https://{{ vault_domain }}/v1/sys/mounts/forge-dso
status_code: [200, 400]
headers:
X-Vault-Token: "{{ root_token }}"
register: get_engines

- name: "Config: create kv engine"
when: get_engines.status == 400
ansible.builtin.uri:
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
url: https://{{ vault_domain }}/v1/sys/mounts/forge-dso
method: POST
status_code: [204]
headers:
X-Vault-Token: "{{ root_token }}"
body:
type: kv
options:
version: 2
body_format: json

- name: Get Vault config
when: vault_ns.resources | length > 0
kubernetes.core.k8s_info:
kind: ConfigMap
namespace: "{{ dsc.vault.namespace }}"
name: "{{ dsc_name }}-vault-config"
register: vault_conf

- name: Initialize conf_state fact
ansible.builtin.set_fact:
conf_state: ""

- name: Set conf_state fact
when: (initial_vault_conf.resources[0].metadata.resourceVersion is defined)
and (vault_conf.resources[0].metadata.resourceVersion is defined)
and (vault_conf.resources[0].metadata.resourceVersion > initial_vault_conf.resources[0].metadata.resourceVersion)
ansible.builtin.set_fact:
conf_state: changed

- name: Restart and unseal Vault when config changed
when: conf_state == 'changed'
block:
- name: Delete Vault pod
kubernetes.core.k8s:
kind: Pod
namespace: "{{ dsc.vault.namespace }}"
label_selectors:
- app.kubernetes.io/instance={{ dsc_name }}-vault
- app.kubernetes.io/name=vault
- component=server
state: absent

- name: Wait a few seconds
ansible.builtin.wait_for:
timeout: 5

- name: Wait Vault URL
ansible.builtin.uri:
url: https://{{ vault_domain }}
method: GET
validate_certs: "{{ dsc.exposedCA.type == 'none' }}"
status_code: [200, 202]
return_content: false
register: vault_response
until: vault_response is not failed
retries: 15
delay: 5

- name: Preinstall check
ansible.builtin.include_tasks:
file: preinstall_check.yml

- name: Patch ServiceMonitor
when: dsc.global.metrics.enabled
kubernetes.core.k8s:
api_version: monitoring.coreos.com/v1
kind: ServiceMonitor
namespace: "{{ dsc.vault.namespace }}"
name: "{{ dsc_name }}-vault"
state: patched
definition:
spec:
endpoints:
- bearerTokenSecret:
key: root_token
name: "{{ dsc_name }}-vault-keys"
interval: 30s
params:
format:
- prometheus
path: /v1/sys/metrics
port: http
scheme: http
scrapeTimeout: 10s
tlsConfig:
insecureSkipVerify: true
# Setup sso
- name: Setup SSO
ansible.builtin.include_tasks: sso.yml
Loading

0 comments on commit d90ee55

Please sign in to comment.