feat(ess_pro): deploy Element Server Suite Pro via K3s + Helm
Adds k3s and ess_pro roles to replace the planned Nextcloud Talk stack. Integrates with existing Keycloak (OIDC), Garage (S3 media) and OpenBao (secrets). Hostnames under digitalboard.ch.
This commit is contained in:
parent
c11f019aae
commit
01fd12d75c
18 changed files with 1098 additions and 0 deletions
41
roles/ess-pro/tasks/credentials.yml
Normal file
41
roles/ess-pro/tasks/credentials.yml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
# Helm needs to authenticate against registry.element.io to pull both the
|
||||
# matrix-stack chart AND the Pro container images. We do both:
|
||||
# 1. `helm registry login` so the chart pull works.
|
||||
# 2. A docker-registry Secret in the namespace so pods can pull images.
|
||||
|
||||
- name: Log in to Element Helm/OCI registry
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
{{ ess_pro_helm_install_dir }}/helm registry login {{ ess_pro_registry_url }}
|
||||
--username {{ ess_pro_registry_username | quote }}
|
||||
--password-stdin
|
||||
stdin: "{{ ess_pro_registry_token }}"
|
||||
register: helm_login
|
||||
changed_when: "'Login Succeeded' in (helm_login.stdout + helm_login.stderr)"
|
||||
no_log: true
|
||||
|
||||
- name: Create image pull Secret for the ESS namespace
|
||||
kubernetes.core.k8s:
|
||||
kubeconfig: "{{ ess_pro_kubeconfig }}"
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
metadata:
|
||||
name: "{{ ess_pro_image_pull_secret_name }}"
|
||||
namespace: "{{ ess_pro_namespace }}"
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: ansible
|
||||
data:
|
||||
.dockerconfigjson: "{{ _dockerconfig | to_json | b64encode }}"
|
||||
vars:
|
||||
_dockerconfig:
|
||||
auths:
|
||||
"{{ ess_pro_registry_url }}":
|
||||
username: "{{ ess_pro_registry_username }}"
|
||||
password: "{{ ess_pro_registry_token }}"
|
||||
auth: "{{ (ess_pro_registry_username ~ ':' ~ ess_pro_registry_token) | b64encode }}"
|
||||
no_log: true
|
||||
63
roles/ess-pro/tasks/deploy.yml
Normal file
63
roles/ess-pro/tasks/deploy.yml
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
- name: Render ESS values.yaml
|
||||
ansible.builtin.template:
|
||||
src: values.yaml.j2
|
||||
dest: "{{ ess_pro_values_file }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0640"
|
||||
|
||||
- name: Deploy / upgrade ESS Pro Helm release
|
||||
kubernetes.core.helm:
|
||||
kubeconfig: "{{ ess_pro_kubeconfig }}"
|
||||
name: "{{ ess_pro_release_name }}"
|
||||
chart_ref: "{{ ess_pro_chart_ref }}"
|
||||
chart_version: "{{ ess_pro_chart_version | default(omit, true) }}"
|
||||
release_namespace: "{{ ess_pro_namespace }}"
|
||||
create_namespace: false
|
||||
values_files:
|
||||
- "{{ ess_pro_values_file }}"
|
||||
wait: "{{ ess_pro_helm_wait | bool }}"
|
||||
wait_timeout: "{{ ess_pro_helm_timeout }}"
|
||||
atomic: false
|
||||
state: present
|
||||
register: helm_release
|
||||
|
||||
- name: Show release status
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ helm_release.status | default('no status returned') }}"
|
||||
when: helm_release is defined
|
||||
|
||||
- name: Wait for Synapse pod to be Ready
|
||||
kubernetes.core.k8s_info:
|
||||
kubeconfig: "{{ ess_pro_kubeconfig }}"
|
||||
kind: Pod
|
||||
namespace: "{{ ess_pro_namespace }}"
|
||||
label_selectors:
|
||||
- "app.kubernetes.io/name=synapse"
|
||||
register: synapse_pods
|
||||
until:
|
||||
- synapse_pods.resources | length > 0
|
||||
- synapse_pods.resources[0].status.containerStatuses is defined
|
||||
- (synapse_pods.resources[0].status.containerStatuses | selectattr('ready', 'equalto', true) | list | length) > 0
|
||||
retries: 30
|
||||
delay: 10
|
||||
|
||||
- name: Fetch the localadmin bootstrap password (one-shot, only printed in verbose runs)
|
||||
kubernetes.core.k8s_info:
|
||||
kubeconfig: "{{ ess_pro_kubeconfig }}"
|
||||
kind: Secret
|
||||
namespace: "{{ ess_pro_namespace }}"
|
||||
name: "{{ ess_pro_release_name }}-generated"
|
||||
register: ess_generated_secret
|
||||
when: ess_pro_create_initial_admin | bool
|
||||
no_log: true
|
||||
|
||||
- name: Show how to retrieve the localadmin password
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
ESS Pro is up. To get the localadmin password:
|
||||
kubectl -n {{ ess_pro_namespace }} get secrets/{{ ess_pro_release_name }}-generated \
|
||||
-o jsonpath='{.data.ADMIN_USER_PASSWORD}' | base64 -d
|
||||
Login at https://{{ ess_pro_hostnames.element_admin }} as @localadmin:{{ ess_pro_server_name }}
|
||||
when: ess_pro_create_initial_admin | bool
|
||||
51
roles/ess-pro/tasks/main.yml
Normal file
51
roles/ess-pro/tasks/main.yml
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# SPDX-License-Identifier: MIT-0
|
||||
---
|
||||
- name: Validate required variables
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ess_pro_server_name | length > 0
|
||||
- ess_pro_registry_username | length > 0
|
||||
- ess_pro_registry_token | length > 0
|
||||
fail_msg: >-
|
||||
ess_pro_server_name, ess_pro_registry_username and ess_pro_registry_token
|
||||
must be set. Provide them in group_vars/ess_servers.yml (typically as
|
||||
OpenBao lookups, following the digitalboard.core convention).
|
||||
quiet: true
|
||||
|
||||
- name: Validate OIDC variables when OIDC is enabled
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ess_pro_oidc_issuer | length > 0
|
||||
- ess_pro_oidc_client_secret | length > 0
|
||||
fail_msg: ess_pro_oidc_issuer and ess_pro_oidc_client_secret must be set when OIDC is enabled.
|
||||
quiet: true
|
||||
when: ess_pro_oidc_enabled | bool
|
||||
|
||||
- name: Validate S3 variables when S3 media is enabled
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ess_pro_s3_endpoint | length > 0
|
||||
- ess_pro_s3_access_key | length > 0
|
||||
- ess_pro_s3_secret_key | length > 0
|
||||
fail_msg: S3 endpoint, access key and secret key must be set when S3 media is enabled.
|
||||
quiet: true
|
||||
when: ess_pro_s3_media_enabled | bool
|
||||
|
||||
- name: Validate external Postgres variables
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ess_pro_postgres_host | length > 0
|
||||
- ess_pro_postgres_synapse_password | length > 0
|
||||
- ess_pro_postgres_mas_password | length > 0
|
||||
fail_msg: External Postgres host and per-component passwords must be set when ess_pro_postgres_external is true.
|
||||
quiet: true
|
||||
when: ess_pro_postgres_external | bool
|
||||
|
||||
- name: Run prerequisite tasks (Helm CLI, namespace)
|
||||
ansible.builtin.import_tasks: prerequisites.yml
|
||||
|
||||
- name: Authenticate against Element image registry and create pull secret
|
||||
ansible.builtin.import_tasks: credentials.yml
|
||||
|
||||
- name: Render values.yaml and deploy the Helm release
|
||||
ansible.builtin.import_tasks: deploy.yml
|
||||
66
roles/ess-pro/tasks/prerequisites.yml
Normal file
66
roles/ess-pro/tasks/prerequisites.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
- name: Ensure required OS packages are present
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- python3-kubernetes
|
||||
- python3-yaml
|
||||
- ca-certificates
|
||||
- curl
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Check whether Helm is already installed
|
||||
ansible.builtin.stat:
|
||||
path: "{{ ess_pro_helm_install_dir }}/helm"
|
||||
register: helm_binary
|
||||
|
||||
- name: Check installed Helm version
|
||||
ansible.builtin.command: "{{ ess_pro_helm_install_dir }}/helm version --short"
|
||||
register: helm_version_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: helm_binary.stat.exists
|
||||
|
||||
- name: Download Helm tarball
|
||||
ansible.builtin.get_url:
|
||||
url: "https://get.helm.sh/helm-{{ ess_pro_helm_version }}-linux-amd64.tar.gz"
|
||||
dest: "/tmp/helm-{{ ess_pro_helm_version }}.tar.gz"
|
||||
mode: "0644"
|
||||
when: not helm_binary.stat.exists or (ess_pro_helm_version not in (helm_version_check.stdout | default('')))
|
||||
|
||||
- name: Unpack Helm
|
||||
ansible.builtin.unarchive:
|
||||
src: "/tmp/helm-{{ ess_pro_helm_version }}.tar.gz"
|
||||
dest: /tmp/
|
||||
remote_src: true
|
||||
creates: "/tmp/linux-amd64/helm"
|
||||
when: not helm_binary.stat.exists or (ess_pro_helm_version not in (helm_version_check.stdout | default('')))
|
||||
|
||||
- name: Install Helm binary
|
||||
ansible.builtin.copy:
|
||||
src: /tmp/linux-amd64/helm
|
||||
dest: "{{ ess_pro_helm_install_dir }}/helm"
|
||||
remote_src: true
|
||||
mode: "0755"
|
||||
when: not helm_binary.stat.exists or (ess_pro_helm_version not in (helm_version_check.stdout | default('')))
|
||||
|
||||
- name: Ensure ESS config directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ ess_pro_config_dir }}"
|
||||
state: directory
|
||||
mode: "0750"
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Ensure ESS namespace exists
|
||||
kubernetes.core.k8s:
|
||||
kubeconfig: "{{ ess_pro_kubeconfig }}"
|
||||
state: present
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: "{{ ess_pro_namespace }}"
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: ansible
|
||||
app.kubernetes.io/part-of: digitalboard
|
||||
Loading…
Add table
Add a link
Reference in a new issue