From 473c5007320abe80e98c96eab239404209016e5d Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 8 Jan 2026 14:46:06 +0200 Subject: [PATCH 01/98] feat: Customise nginx conf.d --- charts/opencrvs-services/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/opencrvs-services/Chart.yaml b/charts/opencrvs-services/Chart.yaml index 7fda9017..8296132a 100644 --- a/charts/opencrvs-services/Chart.yaml +++ b/charts/opencrvs-services/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: opencrvs-services description: OpenCRVS Services type: application -version: 0.1.27 +version: 0.1.26 appVersion: 1.9.5 From d61684dc483df79bbcea89db4c0c2eca8cfcf267 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 10:55:44 +0200 Subject: [PATCH 02/98] fix: Run data-seed as separate step from reset --- .github/workflows/k8s-seed-data.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/k8s-seed-data.yml b/.github/workflows/k8s-seed-data.yml index 7e8fe4d7..f11a7c7e 100644 --- a/.github/workflows/k8s-seed-data.yml +++ b/.github/workflows/k8s-seed-data.yml @@ -1,5 +1,9 @@ name: Seed environment +<<<<<<< HEAD run-name: "Seed ${{ inputs.environment }} by ${{ github.actor }}" +======= +run-name: "Reset ${{ inputs.environment }} environment" +>>>>>>> 2a0472f (fix: Run data-seed as separate step from reset) on: workflow_dispatch: inputs: From d5ef5ea5d97ab529f4f136e943179b226a8e8520 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Fri, 7 Nov 2025 16:50:20 +0200 Subject: [PATCH 03/98] testing --- .github/workflows/deploy-dependencies.yml | 4 +- .github/workflows/deploy-opencrvs.yml | 4 +- .github/workflows/github-to-k8s-sync-env.yml | 6 +- .github/workflows/k8s-reindex.yml | 4 +- .github/workflows/k8s-reset-data.yml | 4 +- .github/workflows/k8s-seed-data.yml | 4 +- .github/workflows/provision.yml | 4 +- .github/workflows/reset-2fa.yml | 4 +- environments/demo1/dependencies/values.yaml | 25 ++++++ environments/demo1/mosip-api/values.yaml | 2 + .../demo1/opencrvs-services/values.yaml | 56 +++++++++++++ environments/demo1/traefik/values.yaml | 72 ++++++++++++++++ .../production/dependencies/values.yaml | 31 +++++++ environments/production/mosip-api/values.yaml | 2 + .../production/opencrvs-services/values.yaml | 56 +++++++++++++ environments/production/traefik/values.yaml | 72 ++++++++++++++++ environments/staging/dependencies/values.yaml | 25 ++++++ environments/staging/mosip-api/values.yaml | 2 + .../staging/opencrvs-services/values.yaml | 56 +++++++++++++ environments/staging/traefik/values.yaml | 72 ++++++++++++++++ .../server-setup/inventory/demo1.yml | 47 +++++++++++ .../server-setup/inventory/production.yml | 82 +++++++++++++++++++ .../server-setup/inventory/staging.yml | 47 +++++++++++ 23 files changed, 672 insertions(+), 9 deletions(-) create mode 100644 environments/demo1/dependencies/values.yaml create mode 100644 environments/demo1/mosip-api/values.yaml create mode 100644 environments/demo1/opencrvs-services/values.yaml create mode 100644 environments/demo1/traefik/values.yaml create mode 100644 environments/production/dependencies/values.yaml create mode 100644 environments/production/mosip-api/values.yaml create mode 100644 environments/production/opencrvs-services/values.yaml create mode 100644 environments/production/traefik/values.yaml create mode 100644 environments/staging/dependencies/values.yaml create mode 100644 environments/staging/mosip-api/values.yaml create mode 100644 environments/staging/opencrvs-services/values.yaml create mode 100644 environments/staging/traefik/values.yaml create mode 100644 infrastructure/server-setup/inventory/demo1.yml create mode 100644 infrastructure/server-setup/inventory/production.yml create mode 100644 infrastructure/server-setup/inventory/staging.yml diff --git a/.github/workflows/deploy-dependencies.yml b/.github/workflows/deploy-dependencies.yml index 534383bc..9a2fa426 100644 --- a/.github/workflows/deploy-dependencies.yml +++ b/.github/workflows/deploy-dependencies.yml @@ -9,7 +9,9 @@ on: default: "dev" type: choice options: - - "" + - demo1 + - production + - staging jobs: approve: environment: ${{ inputs.environment }} diff --git a/.github/workflows/deploy-opencrvs.yml b/.github/workflows/deploy-opencrvs.yml index 9b502212..05a1b09a 100644 --- a/.github/workflows/deploy-opencrvs.yml +++ b/.github/workflows/deploy-opencrvs.yml @@ -25,7 +25,9 @@ on: default: "dev" type: choice options: - - "" + - demo1 + - production + - staging jobs: approve: diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index f829aecb..c457d76d 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -10,8 +10,10 @@ on: default: "development" type: choice options: - - "" - namespace_template: + - demo1 + - production + - staging + mapping_file: description: "Secrets mapping template" default: "opencrvs" type: choice diff --git a/.github/workflows/k8s-reindex.yml b/.github/workflows/k8s-reindex.yml index cf4dfb9e..fb8c3f71 100644 --- a/.github/workflows/k8s-reindex.yml +++ b/.github/workflows/k8s-reindex.yml @@ -9,7 +9,9 @@ on: default: "dev" type: choice options: - - "" + - demo1 + - production + - staging workflow_call: inputs: environment: diff --git a/.github/workflows/k8s-reset-data.yml b/.github/workflows/k8s-reset-data.yml index bcb1bdd6..f1ed702c 100644 --- a/.github/workflows/k8s-reset-data.yml +++ b/.github/workflows/k8s-reset-data.yml @@ -9,7 +9,9 @@ on: default: "dev" type: choice options: - - "" + - demo1 + - production + - staging workflow_call: inputs: environment: diff --git a/.github/workflows/k8s-seed-data.yml b/.github/workflows/k8s-seed-data.yml index f11a7c7e..1e052c1d 100644 --- a/.github/workflows/k8s-seed-data.yml +++ b/.github/workflows/k8s-seed-data.yml @@ -13,7 +13,9 @@ on: default: "dev" type: choice options: - - "" + - demo1 + - production + - staging workflow_call: inputs: environment: diff --git a/.github/workflows/provision.yml b/.github/workflows/provision.yml index 4082b763..559649c2 100644 --- a/.github/workflows/provision.yml +++ b/.github/workflows/provision.yml @@ -9,7 +9,9 @@ on: default: 'dev' type: choice options: - - "" + - staging + - production + - demo1 tags: description: 'Tags to apply to the provisioned resources' required: true diff --git a/.github/workflows/reset-2fa.yml b/.github/workflows/reset-2fa.yml index a67f0737..586a9ab8 100644 --- a/.github/workflows/reset-2fa.yml +++ b/.github/workflows/reset-2fa.yml @@ -13,7 +13,9 @@ on: default: required: true options: - - "" + - staging + - production + - demo1 jobs: approve: diff --git a/environments/demo1/dependencies/values.yaml b/environments/demo1/dependencies/values.yaml new file mode 100644 index 00000000..cffcaa7f --- /dev/null +++ b/environments/demo1/dependencies/values.yaml @@ -0,0 +1,25 @@ +storage_type: host_path + +environment_type: non-production + +ingress: + tls_resolver: letsencrypt + +minio: + use_default_credentials: false + +elasticsearch: + use_default_credentials: false + +mongodb: + use_default_credentials: false + +postgres: + use_default_credentials: false + +monitoring: + enabled: true + +elastalert: + env: + HTTP_POST2_ALERT_URL: http://countryconfig.opencrvs-demo2.svc.cluster.local:3040 diff --git a/environments/demo1/mosip-api/values.yaml b/environments/demo1/mosip-api/values.yaml new file mode 100644 index 00000000..442be8ee --- /dev/null +++ b/environments/demo1/mosip-api/values.yaml @@ -0,0 +1,2 @@ +ingress: + ssl_enabled: true \ No newline at end of file diff --git a/environments/demo1/opencrvs-services/values.yaml b/environments/demo1/opencrvs-services/values.yaml new file mode 100644 index 00000000..0ded4e9b --- /dev/null +++ b/environments/demo1/opencrvs-services/values.yaml @@ -0,0 +1,56 @@ +######################################################################################## +# Initial configuration file for OpenCRVS installation +######################################################################################## +# Some properties are not defined in this file and should be provided as key/value at +# installation time: +# - hostname: valid DNS name for opencrvs +# - countryconfig.image.name: Countryconfig image repository +# - countryconfig.image.tag: Countryconfig image tag +ingress: + tls_resolver: letsencrypt + +environment_type: non-production + +hpa: + enabled: false + +env: + APN_SERVICE_URL: "http://apm-server.opencrvs-deps-demo1.svc.cluster.local:8200" + +influxdb: + host: influxdb-0.influxdb.opencrvs-deps-demo1.svc.cluster.local +elasticsearch: + auth_mode: auto + host: elasticsearch.opencrvs-deps-demo1.svc.cluster.local + + +minio: + auth_mode: use_secret + host: minio-0.minio.opencrvs-deps-demo1.svc.cluster.local + external_hostname: minio.test-k8s.opencrvs.dev + +mongodb: + auth_mode: auto + host: mongodb-0.mongodb.opencrvs-deps-demo1.svc.cluster.local + +redis: + auth_mode: acl + host: redis-0.redis.opencrvs-deps-demo1.svc.cluster.local + +postgres: + auth_mode: auto + host: postgres-0.postgres.opencrvs-deps-demo1.svc.cluster.local + +imagePullSecrets: + # Default value for credentials created while yarn environment:init + - name: dockerhub-credentials + +countryconfig: + smtp-config: + - ALERT_EMAIL + - SENDER_EMAIL_ADDRESS + - SMTP_HOST + - SMTP_PASSWORD + - SMTP_PORT + - SMTP_SECURE + - SMTP_USERNAME diff --git a/environments/demo1/traefik/values.yaml b/environments/demo1/traefik/values.yaml new file mode 100644 index 00000000..38f45b4e --- /dev/null +++ b/environments/demo1/traefik/values.yaml @@ -0,0 +1,72 @@ +# Overwriting https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml +namespaceOverride: "traefik" +logs: + general: + # "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "PANIC" + level: "INFO" + # format: "common" # For local environment + format: "json" # For server environment + access: + # -- To enable access logs + enabled: true + format: "json" + +ingressRoute: + dashboard: + enabled: false + +# Be explicit that we only use CRDs, not ingress/gw support +providers: + kubernetesCRD: + enabled: true + kubernetesIngress: + enabled: false + kubernetesGateway: + enabled: false + +service: + enabled: true + single: false + type: NodePort + +ports: + web: + port: 8000 + hostPort: 80 + protocol: TCP + nodePort: 30080 + websecure: + port: 8443 + nodePort: 30443 + hostPort: 443 + protocol: TCP + +certificatesResolvers: + letsencrypt: + acme: + tlsChallenge: false + httpChallenge: + entryPoint: web + email: vadym@opencrvs.org + # Storage for certificates: + storage: /certificates/acme.json + # NOTE: Sometimes Let's Encrypt hit production SSL certificate issuing limits + # If you are having issues, switch to staging + # Staging server + # caServer: https://acme-staging-v02.api.letsencrypt.org/directory + # Production server + caServer: https://acme-v02.api.letsencrypt.org/directory + +deployment: + hostNetwork: true + additionalVolumes: + - name: acme + hostPath: + path: /data/traefik + +additionalVolumeMounts: + - name: acme + mountPath: /certificates + +nodeSelector: + traefik-role: ingress diff --git a/environments/production/dependencies/values.yaml b/environments/production/dependencies/values.yaml new file mode 100644 index 00000000..2b736478 --- /dev/null +++ b/environments/production/dependencies/values.yaml @@ -0,0 +1,31 @@ +storage_type: host_path + +environment_type: production + +ingress: + tls_resolver: letsencrypt + +minio: + use_default_credentials: false + +elasticsearch: + use_default_credentials: false + +mongodb: + use_default_credentials: false + +postgres: + use_default_credentials: false + +monitoring: + enabled: true + +elastalert: + env: + HTTP_POST2_ALERT_URL: http://countryconfig.opencrvs-production.svc.cluster.local:3040 + +# Backup configuration +backup: + enabled: true + schedule: "0 1 * * *" + backup_server_dir: /home/backup/production diff --git a/environments/production/mosip-api/values.yaml b/environments/production/mosip-api/values.yaml new file mode 100644 index 00000000..442be8ee --- /dev/null +++ b/environments/production/mosip-api/values.yaml @@ -0,0 +1,2 @@ +ingress: + ssl_enabled: true \ No newline at end of file diff --git a/environments/production/opencrvs-services/values.yaml b/environments/production/opencrvs-services/values.yaml new file mode 100644 index 00000000..895dc36f --- /dev/null +++ b/environments/production/opencrvs-services/values.yaml @@ -0,0 +1,56 @@ +######################################################################################## +# Initial configuration file for OpenCRVS installation +######################################################################################## +# Some properties are not defined in this file and should be provided as key/value at +# installation time: +# - hostname: valid DNS name for opencrvs +# - countryconfig.image.name: Countryconfig image repository +# - countryconfig.image.tag: Countryconfig image tag +ingress: + tls_resolver: letsencrypt + +environment_type: production + +hpa: + enabled: false + +env: + APN_SERVICE_URL: "http://apm-server.opencrvs-deps-production.svc.cluster.local:8200" + +influxdb: + host: influxdb-0.influxdb.opencrvs-deps-production.svc.cluster.local +elasticsearch: + auth_mode: auto + host: elasticsearch.opencrvs-deps-production.svc.cluster.local + + +minio: + auth_mode: use_secret + host: minio-0.minio.opencrvs-deps-production.svc.cluster.local + external_hostname: minio.test-k8s.opencrvs.dev + +mongodb: + auth_mode: auto + host: mongodb-0.mongodb.opencrvs-deps-production.svc.cluster.local + +redis: + auth_mode: acl + host: redis-0.redis.opencrvs-deps-production.svc.cluster.local + +postgres: + auth_mode: auto + host: postgres-0.postgres.opencrvs-deps-production.svc.cluster.local + +imagePullSecrets: + # Default value for credentials created while yarn environment:init + - name: dockerhub-credentials + +countryconfig: + smtp-config: + - ALERT_EMAIL + - SENDER_EMAIL_ADDRESS + - SMTP_HOST + - SMTP_PASSWORD + - SMTP_PORT + - SMTP_SECURE + - SMTP_USERNAME diff --git a/environments/production/traefik/values.yaml b/environments/production/traefik/values.yaml new file mode 100644 index 00000000..38f45b4e --- /dev/null +++ b/environments/production/traefik/values.yaml @@ -0,0 +1,72 @@ +# Overwriting https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml +namespaceOverride: "traefik" +logs: + general: + # "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "PANIC" + level: "INFO" + # format: "common" # For local environment + format: "json" # For server environment + access: + # -- To enable access logs + enabled: true + format: "json" + +ingressRoute: + dashboard: + enabled: false + +# Be explicit that we only use CRDs, not ingress/gw support +providers: + kubernetesCRD: + enabled: true + kubernetesIngress: + enabled: false + kubernetesGateway: + enabled: false + +service: + enabled: true + single: false + type: NodePort + +ports: + web: + port: 8000 + hostPort: 80 + protocol: TCP + nodePort: 30080 + websecure: + port: 8443 + nodePort: 30443 + hostPort: 443 + protocol: TCP + +certificatesResolvers: + letsencrypt: + acme: + tlsChallenge: false + httpChallenge: + entryPoint: web + email: vadym@opencrvs.org + # Storage for certificates: + storage: /certificates/acme.json + # NOTE: Sometimes Let's Encrypt hit production SSL certificate issuing limits + # If you are having issues, switch to staging + # Staging server + # caServer: https://acme-staging-v02.api.letsencrypt.org/directory + # Production server + caServer: https://acme-v02.api.letsencrypt.org/directory + +deployment: + hostNetwork: true + additionalVolumes: + - name: acme + hostPath: + path: /data/traefik + +additionalVolumeMounts: + - name: acme + mountPath: /certificates + +nodeSelector: + traefik-role: ingress diff --git a/environments/staging/dependencies/values.yaml b/environments/staging/dependencies/values.yaml new file mode 100644 index 00000000..2908aa25 --- /dev/null +++ b/environments/staging/dependencies/values.yaml @@ -0,0 +1,25 @@ +storage_type: host_path + +environment_type: production + +ingress: + tls_resolver: letsencrypt + +minio: + use_default_credentials: false + +elasticsearch: + use_default_credentials: false + +mongodb: + use_default_credentials: false + +postgres: + use_default_credentials: false + +monitoring: + enabled: true + +elastalert: + env: + HTTP_POST2_ALERT_URL: http://countryconfig.opencrvs-staging.svc.cluster.local:3040 diff --git a/environments/staging/mosip-api/values.yaml b/environments/staging/mosip-api/values.yaml new file mode 100644 index 00000000..442be8ee --- /dev/null +++ b/environments/staging/mosip-api/values.yaml @@ -0,0 +1,2 @@ +ingress: + ssl_enabled: true \ No newline at end of file diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml new file mode 100644 index 00000000..d4b7dcda --- /dev/null +++ b/environments/staging/opencrvs-services/values.yaml @@ -0,0 +1,56 @@ +######################################################################################## +# Initial configuration file for OpenCRVS installation +######################################################################################## +# Some properties are not defined in this file and should be provided as key/value at +# installation time: +# - hostname: valid DNS name for opencrvs +# - countryconfig.image.name: Countryconfig image repository +# - countryconfig.image.tag: Countryconfig image tag +ingress: + tls_resolver: letsencrypt + +environment_type: production + +hpa: + enabled: false + +env: + APN_SERVICE_URL: "http://apm-server.opencrvs-deps-staging.svc.cluster.local:8200" + +influxdb: + host: influxdb-0.influxdb.opencrvs-deps-staging.svc.cluster.local +elasticsearch: + auth_mode: auto + host: elasticsearch.opencrvs-deps-staging.svc.cluster.local + + +minio: + auth_mode: use_secret + host: minio-0.minio.opencrvs-deps-staging.svc.cluster.local + external_hostname: minio.test-k8s.opencrvs.dev + +mongodb: + auth_mode: auto + host: mongodb-0.mongodb.opencrvs-deps-staging.svc.cluster.local + +redis: + auth_mode: acl + host: redis-0.redis.opencrvs-deps-staging.svc.cluster.local + +postgres: + auth_mode: auto + host: postgres-0.postgres.opencrvs-deps-staging.svc.cluster.local + +imagePullSecrets: + # Default value for credentials created while yarn environment:init + - name: dockerhub-credentials + +countryconfig: + smtp-config: + - ALERT_EMAIL + - SENDER_EMAIL_ADDRESS + - SMTP_HOST + - SMTP_PASSWORD + - SMTP_PORT + - SMTP_SECURE + - SMTP_USERNAME diff --git a/environments/staging/traefik/values.yaml b/environments/staging/traefik/values.yaml new file mode 100644 index 00000000..38f45b4e --- /dev/null +++ b/environments/staging/traefik/values.yaml @@ -0,0 +1,72 @@ +# Overwriting https://github.com/traefik/traefik-helm-chart/blob/master/traefik/values.yaml +namespaceOverride: "traefik" +logs: + general: + # "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL", "PANIC" + level: "INFO" + # format: "common" # For local environment + format: "json" # For server environment + access: + # -- To enable access logs + enabled: true + format: "json" + +ingressRoute: + dashboard: + enabled: false + +# Be explicit that we only use CRDs, not ingress/gw support +providers: + kubernetesCRD: + enabled: true + kubernetesIngress: + enabled: false + kubernetesGateway: + enabled: false + +service: + enabled: true + single: false + type: NodePort + +ports: + web: + port: 8000 + hostPort: 80 + protocol: TCP + nodePort: 30080 + websecure: + port: 8443 + nodePort: 30443 + hostPort: 443 + protocol: TCP + +certificatesResolvers: + letsencrypt: + acme: + tlsChallenge: false + httpChallenge: + entryPoint: web + email: vadym@opencrvs.org + # Storage for certificates: + storage: /certificates/acme.json + # NOTE: Sometimes Let's Encrypt hit production SSL certificate issuing limits + # If you are having issues, switch to staging + # Staging server + # caServer: https://acme-staging-v02.api.letsencrypt.org/directory + # Production server + caServer: https://acme-v02.api.letsencrypt.org/directory + +deployment: + hostNetwork: true + additionalVolumes: + - name: acme + hostPath: + path: /data/traefik + +additionalVolumeMounts: + - name: acme + mountPath: /certificates + +nodeSelector: + traefik-role: ingress diff --git a/infrastructure/server-setup/inventory/demo1.yml b/infrastructure/server-setup/inventory/demo1.yml new file mode 100644 index 00000000..1b388a31 --- /dev/null +++ b/infrastructure/server-setup/inventory/demo1.yml @@ -0,0 +1,47 @@ +all: + vars: + # Domain/IP address for remote access to your cluster API (see ~/.kube/config) + # - If you are behind VPN, use private IP address + # - If your server is exposed (not recommeded), use public IP address + # - If you would like to run kubectl commands from the remote server, leave this field empty + # kube_api_host: '' + kube_api_host: + # Default ansible provision user, keep as is + ansible_user: provision + + # single_node: + # For development/qa/testing/staging keep true + # For production keep false + # Defaults production configuration: + # - master node + # - 2 worker nodes + single_node: true + + # users: Add as many users as you wish + # Configuration example + # - name: + # ssh_keys: + # - + # - + # state: present + # role: admin + # Allowed roles: + # - operator, read only access to OS, full access to kubernetes cluster + # - admin, full access + # Allowed states: + # - present, user is allowed to login + # - absent, account is disabled + users: [] + + children: + master: + hosts: + # Replace master with value returned by command: hostname + master: + # Keep values (ansible_host, ansible_connection) as is + # Ansible is executed on master node + ansible_host: localhost + ansible_connection: local + labels: + # traefik-role label is used to identify where to deploy traefik + traefik-role: ingress diff --git a/infrastructure/server-setup/inventory/production.yml b/infrastructure/server-setup/inventory/production.yml new file mode 100644 index 00000000..eb71a886 --- /dev/null +++ b/infrastructure/server-setup/inventory/production.yml @@ -0,0 +1,82 @@ +all: + vars: + # single_node: + # For development/qa/testing/staging keep true + # For production keep false + # Defaults production configuration: + # - master node + # - 2 worker nodes + single_node: false + + # Domain/IP address for remote access to your cluster API + # Domain/IP address will be added as main endpoint to your ~/.kube/config + # - If you are behind VPN, use private IP address + # - If your server is exposed (not recommeded), use public IP address + # - If you would like to run kubectl commands from the remote server, leave this field empty + # kube_api_endpoint: '' + + # IMPORTANT: If master VM has multiple ethernet interfaces, put private IP address at kube_api_address + # kube_api_host: 10.10.10.10 + kube_api_host: tmp-prod.opencrvs.dev + + # Default ansible provision user, keep as is + ansible_user: provision + + # users: Add as many users as you wish + # Configuration example + # - name: + # ssh_keys: + # - + # - + # state: present + # role: admin + # Allowed roles: + # - operator, read only access to OS, full access to kubernetes cluster + # - admin, full access + # Allowed states: + # - present, user is allowed to login + # - absent, account is disabled + users: + - name: vmudryi + state: present + role: admin + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINgMcsSBwTE0EbMDRSF1T4vJDcN/5HAjKGbi2DqV7g/Q vmudryi@opencrvs.org + + children: + master: + hosts: + # Replace master with value returned by command: hostname + master: + # Keep values (ansible_host, ansible_connection) as is + # Ansible is executed on master node + ansible_host: localhost + ansible_connection: local + labels: + # traefik-role label is used to identify where to deploy traefik + traefik-role: ingress + + # Workers section is optional, for single node cluster feel free to remove this section + # section can be added later + # more workers can be added later as well + + workers: + hosts: + worker0: + ansible_host: 10.2.0.5 + labels: + # By default all datastores are deployed to worker node with role data1 + role: data1 + + worker1: + ansible_host: 10.2.0.6 + + + + # backup section is optional, feel free to remove if backups are not enabled + # section can be added later + + backup: + hosts: + backup1: + ansible_host: 10.2.0.3 diff --git a/infrastructure/server-setup/inventory/staging.yml b/infrastructure/server-setup/inventory/staging.yml new file mode 100644 index 00000000..20020f81 --- /dev/null +++ b/infrastructure/server-setup/inventory/staging.yml @@ -0,0 +1,47 @@ +all: + vars: + # Domain/IP address for remote access to your cluster API (see ~/.kube/config) + # - If you are behind VPN, use private IP address + # - If your server is exposed (not recommeded), use public IP address + # - If you would like to run kubectl commands from the remote server, leave this field empty + # kube_api_host: '' + kube_api_host: test-stg.opencrvs.dev + # Default ansible provision user, keep as is + ansible_user: provision + + # single_node: + # For development/qa/testing/staging keep true + # For production keep false + # Defaults production configuration: + # - master node + # - 2 worker nodes + single_node: true + + # users: Add as many users as you wish + # Configuration example + # - name: + # ssh_keys: + # - + # - + # state: present + # role: admin + # Allowed roles: + # - operator, read only access to OS, full access to kubernetes cluster + # - admin, full access + # Allowed states: + # - present, user is allowed to login + # - absent, account is disabled + users: [] + + children: + master: + hosts: + # Replace master with value returned by command: hostname + master: + # Keep values (ansible_host, ansible_connection) as is + # Ansible is executed on master node + ansible_host: localhost + ansible_connection: local + labels: + # traefik-role label is used to identify where to deploy traefik + traefik-role: ingress From d501b7ad9f3ea7ee217fa1ae6c772e356870c584 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 12 Nov 2025 08:40:33 +0200 Subject: [PATCH 04/98] fix --- infrastructure/server-setup/inventory/staging.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/infrastructure/server-setup/inventory/staging.yml b/infrastructure/server-setup/inventory/staging.yml index 20020f81..a882bf2d 100644 --- a/infrastructure/server-setup/inventory/staging.yml +++ b/infrastructure/server-setup/inventory/staging.yml @@ -31,7 +31,12 @@ all: # Allowed states: # - present, user is allowed to login # - absent, account is disabled - users: [] + users: + - name: vmudryi + state: present + role: admin + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINgMcsSBwTE0EbMDRSF1T4vJDcN/5HAjKGbi2DqV7g/Q vmudryi@opencrvs.org children: master: From 5555e29357a2059bfe83b5b962a1d39c89bb6ff2 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 12 Nov 2025 10:22:58 +0200 Subject: [PATCH 05/98] fix --- environments/staging/dependencies/values.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/environments/staging/dependencies/values.yaml b/environments/staging/dependencies/values.yaml index 2908aa25..7362ff72 100644 --- a/environments/staging/dependencies/values.yaml +++ b/environments/staging/dependencies/values.yaml @@ -23,3 +23,16 @@ monitoring: elastalert: env: HTTP_POST2_ALERT_URL: http://countryconfig.opencrvs-staging.svc.cluster.local:3040 + +# Restore configuration +restore: + enabled: true + # Schedule job + schedule: "0 0 * * *" + # Secret to store backup server connection configuration: + # - user, backup server username + # - host, hostname / IP of backup server + # - ssh_key, ssh key for passwordless connection + backup_server_secret: backup-server-ssh-credentials + backup_server_dir: /home/backup/production + backup_encryption_secret: restore-encryption-secret \ No newline at end of file From 844b3eccee0fe102e7d5fe442e7f21a0c4741374 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 12 Nov 2025 10:24:48 +0200 Subject: [PATCH 06/98] fix --- infrastructure/server-setup/inventory/staging.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/server-setup/inventory/staging.yml b/infrastructure/server-setup/inventory/staging.yml index a882bf2d..323eb680 100644 --- a/infrastructure/server-setup/inventory/staging.yml +++ b/infrastructure/server-setup/inventory/staging.yml @@ -5,7 +5,7 @@ all: # - If your server is exposed (not recommeded), use public IP address # - If you would like to run kubectl commands from the remote server, leave this field empty # kube_api_host: '' - kube_api_host: test-stg.opencrvs.dev + kube_api_host: tmp-stg.opencrvs.dev # Default ansible provision user, keep as is ansible_user: provision From ea1d9e856c160ec0b6b8e9085a2c9280ca0df317 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 12 Nov 2025 17:41:48 +0200 Subject: [PATCH 07/98] fix --- environments/production/opencrvs-services/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environments/production/opencrvs-services/values.yaml b/environments/production/opencrvs-services/values.yaml index 895dc36f..2b44c8ef 100644 --- a/environments/production/opencrvs-services/values.yaml +++ b/environments/production/opencrvs-services/values.yaml @@ -16,7 +16,7 @@ hpa: env: APN_SERVICE_URL: "http://apm-server.opencrvs-deps-production.svc.cluster.local:8200" - + QA_ENV: false influxdb: host: influxdb-0.influxdb.opencrvs-deps-production.svc.cluster.local elasticsearch: From cca5ed5883577f38b9a3a23ce12166303490155f Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 12 Nov 2025 17:52:21 +0200 Subject: [PATCH 08/98] fix --- .../production/opencrvs-services/values.yaml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/environments/production/opencrvs-services/values.yaml b/environments/production/opencrvs-services/values.yaml index 2b44c8ef..cf1bbeae 100644 --- a/environments/production/opencrvs-services/values.yaml +++ b/environments/production/opencrvs-services/values.yaml @@ -46,11 +46,12 @@ imagePullSecrets: - name: dockerhub-credentials countryconfig: - smtp-config: - - ALERT_EMAIL - - SENDER_EMAIL_ADDRESS - - SMTP_HOST - - SMTP_PASSWORD - - SMTP_PORT - - SMTP_SECURE - - SMTP_USERNAME + secrets: + smtp-config: + - ALERT_EMAIL + - SENDER_EMAIL_ADDRESS + - SMTP_HOST + - SMTP_PASSWORD + - SMTP_PORT + - SMTP_SECURE + - SMTP_USERNAME From 3db1abfa40c77876bc8d7723d58fc1818bc49445 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Mon, 17 Nov 2025 18:40:01 +0200 Subject: [PATCH 09/98] fix --- environments/production/opencrvs-services/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environments/production/opencrvs-services/values.yaml b/environments/production/opencrvs-services/values.yaml index cf1bbeae..44bf341f 100644 --- a/environments/production/opencrvs-services/values.yaml +++ b/environments/production/opencrvs-services/values.yaml @@ -16,7 +16,7 @@ hpa: env: APN_SERVICE_URL: "http://apm-server.opencrvs-deps-production.svc.cluster.local:8200" - QA_ENV: false + QA_ENV: true influxdb: host: influxdb-0.influxdb.opencrvs-deps-production.svc.cluster.local elasticsearch: From 5dcf4577ed38e2c865574b349b19bb9c5d9ba056 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 20 Nov 2025 19:11:45 +0200 Subject: [PATCH 10/98] fix: Bot username --- .github/workflows/publish-charts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-charts.yml b/.github/workflows/publish-charts.yml index 75c28ed7..c7dc543d 100644 --- a/.github/workflows/publish-charts.yml +++ b/.github/workflows/publish-charts.yml @@ -30,7 +30,7 @@ jobs: env: GITHUB_TOKEN_REGISTRY: ${{ secrets.PACKAGE_GITHUB_TOKEN }} run: | - echo $GITHUB_TOKEN_REGISTRY | helm registry login ghcr.io --username adskyiproger --password-stdin + echo $GITHUB_TOKEN_REGISTRY | helm registry login ghcr.io --username ocrvs-bot --password-stdin for package in $(ls -1 packages) do helm push packages/$package oci://ghcr.io/opencrvs From 457e9d4213253458bbbc5d5245475e68da843a77 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 20 Nov 2025 19:19:39 +0200 Subject: [PATCH 11/98] testing --- .github/TEMPLATES/secret-mapping-opencrvs-deps.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml index 28c33dba..2d7eba20 100644 --- a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml +++ b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml @@ -35,6 +35,9 @@ postgres-admin-user: - POSTGRES_USER - POSTGRES_PASSWORD +foo-secret: + - POSTGRES_USER + kibana-users-secret: type: Opaque data: From 8cf38f0016aae0c2660b73dabb02499641e87002 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 20 Nov 2025 19:21:45 +0200 Subject: [PATCH 12/98] testing --- .github/TEMPLATES/secret-mapping-opencrvs-deps.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml index 2d7eba20..42413fd7 100644 --- a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml +++ b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml @@ -37,6 +37,7 @@ postgres-admin-user: foo-secret: - POSTGRES_USER + - DUMMY_VARIABLE kibana-users-secret: type: Opaque From 9c2674c3fcf4d67b5f5fe3500ad5d28c2ed27594 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Fri, 21 Nov 2025 08:50:16 +0200 Subject: [PATCH 13/98] testing --- environments/production/opencrvs-services/values.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/environments/production/opencrvs-services/values.yaml b/environments/production/opencrvs-services/values.yaml index 44bf341f..c78696de 100644 --- a/environments/production/opencrvs-services/values.yaml +++ b/environments/production/opencrvs-services/values.yaml @@ -27,7 +27,6 @@ elasticsearch: minio: auth_mode: use_secret host: minio-0.minio.opencrvs-deps-production.svc.cluster.local - external_hostname: minio.test-k8s.opencrvs.dev mongodb: auth_mode: auto From 6e70ebb559ce60cd20ef2ed2261c6a25c2b14199 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Mon, 24 Nov 2025 14:26:16 +0200 Subject: [PATCH 14/98] fix: Swap was not disabled by provision script --- infrastructure/server-setup/tasks/k8s/system-preparation.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/infrastructure/server-setup/tasks/k8s/system-preparation.yml b/infrastructure/server-setup/tasks/k8s/system-preparation.yml index 3696e20e..e2223567 100644 --- a/infrastructure/server-setup/tasks/k8s/system-preparation.yml +++ b/infrastructure/server-setup/tasks/k8s/system-preparation.yml @@ -4,7 +4,11 @@ - name: Comment active swap entries in fstab ansible.builtin.replace: path: /etc/fstab +<<<<<<< HEAD regexp: '^([^#].*[ \t]swap[ \t].*)$' +======= + regexp: '^([^#].*\s+swap\s+.*)$' +>>>>>>> cff2993 (fix: Swap was not disabled by provision script) replace: '# \1' backup: yes From 7323ff1f9d4ccb07dc33b439def08b3076081891 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Mon, 24 Nov 2025 15:14:56 +0200 Subject: [PATCH 15/98] testing --- infrastructure/server-setup/tasks/k8s/system-preparation.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/infrastructure/server-setup/tasks/k8s/system-preparation.yml b/infrastructure/server-setup/tasks/k8s/system-preparation.yml index e2223567..3696e20e 100644 --- a/infrastructure/server-setup/tasks/k8s/system-preparation.yml +++ b/infrastructure/server-setup/tasks/k8s/system-preparation.yml @@ -4,11 +4,7 @@ - name: Comment active swap entries in fstab ansible.builtin.replace: path: /etc/fstab -<<<<<<< HEAD regexp: '^([^#].*[ \t]swap[ \t].*)$' -======= - regexp: '^([^#].*\s+swap\s+.*)$' ->>>>>>> cff2993 (fix: Swap was not disabled by provision script) replace: '# \1' backup: yes From f2c143983a4d7786d9ad7b9a2b6a365b02460988 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 10:08:59 +0200 Subject: [PATCH 16/98] testing --- environments/production/opencrvs-services/values.yaml | 4 ++++ environments/staging/opencrvs-services/values.yaml | 3 +++ 2 files changed, 7 insertions(+) diff --git a/environments/production/opencrvs-services/values.yaml b/environments/production/opencrvs-services/values.yaml index c78696de..8712f705 100644 --- a/environments/production/opencrvs-services/values.yaml +++ b/environments/production/opencrvs-services/values.yaml @@ -54,3 +54,7 @@ countryconfig: - SMTP_PORT - SMTP_SECURE - SMTP_USERNAME + + +dashboards: + enabled: true diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index d4b7dcda..0306edfe 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -54,3 +54,6 @@ countryconfig: - SMTP_PORT - SMTP_SECURE - SMTP_USERNAME + +dashboards: + enabled: true From 136e9538492000fc4c701837d3278155188f4045 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 10:57:01 +0200 Subject: [PATCH 17/98] fix: data seed job name --- .github/workflows/k8s-seed-data.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/k8s-seed-data.yml b/.github/workflows/k8s-seed-data.yml index 1e052c1d..4e7ec716 100644 --- a/.github/workflows/k8s-seed-data.yml +++ b/.github/workflows/k8s-seed-data.yml @@ -1,9 +1,5 @@ name: Seed environment -<<<<<<< HEAD run-name: "Seed ${{ inputs.environment }} by ${{ github.actor }}" -======= -run-name: "Reset ${{ inputs.environment }} environment" ->>>>>>> 2a0472f (fix: Run data-seed as separate step from reset) on: workflow_dispatch: inputs: From b22b2af0ac45ceff685caecde601264b767f907f Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 15:26:50 +0200 Subject: [PATCH 18/98] fix --- environments/production/dependencies/values.yaml | 3 --- environments/production/opencrvs-services/values.yaml | 3 --- 2 files changed, 6 deletions(-) diff --git a/environments/production/dependencies/values.yaml b/environments/production/dependencies/values.yaml index 2b736478..ebadabad 100644 --- a/environments/production/dependencies/values.yaml +++ b/environments/production/dependencies/values.yaml @@ -2,9 +2,6 @@ storage_type: host_path environment_type: production -ingress: - tls_resolver: letsencrypt - minio: use_default_credentials: false diff --git a/environments/production/opencrvs-services/values.yaml b/environments/production/opencrvs-services/values.yaml index 8712f705..8d031129 100644 --- a/environments/production/opencrvs-services/values.yaml +++ b/environments/production/opencrvs-services/values.yaml @@ -6,9 +6,6 @@ # - hostname: valid DNS name for opencrvs # - countryconfig.image.name: Countryconfig image repository # - countryconfig.image.tag: Countryconfig image tag -ingress: - tls_resolver: letsencrypt - environment_type: production hpa: From 4520895f7d3b7c0e0adcf9acbf4a96d17af193cb Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 15:38:23 +0200 Subject: [PATCH 19/98] fix --- environments/production/traefik/values.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/environments/production/traefik/values.yaml b/environments/production/traefik/values.yaml index 38f45b4e..75ae6559 100644 --- a/environments/production/traefik/values.yaml +++ b/environments/production/traefik/values.yaml @@ -40,11 +40,13 @@ ports: nodePort: 30443 hostPort: 443 protocol: TCP + redirectTo: websecure + certificatesResolvers: letsencrypt: acme: - tlsChallenge: false + tlsChallenge: true httpChallenge: entryPoint: web email: vadym@opencrvs.org From 9174e36b769a810381c798e196d8ddc39fb313fc Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 15:40:34 +0200 Subject: [PATCH 20/98] fix --- environments/production/traefik/values.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/environments/production/traefik/values.yaml b/environments/production/traefik/values.yaml index 75ae6559..308947a8 100644 --- a/environments/production/traefik/values.yaml +++ b/environments/production/traefik/values.yaml @@ -40,7 +40,8 @@ ports: nodePort: 30443 hostPort: 443 protocol: TCP - redirectTo: websecure + redirectTo: + name: websecure certificatesResolvers: From 71d770a72719c5362d8620273a79dcd8fda0aac9 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 15:41:10 +0200 Subject: [PATCH 21/98] fix --- environments/production/traefik/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environments/production/traefik/values.yaml b/environments/production/traefik/values.yaml index 308947a8..c6f06b02 100644 --- a/environments/production/traefik/values.yaml +++ b/environments/production/traefik/values.yaml @@ -41,7 +41,7 @@ ports: hostPort: 443 protocol: TCP redirectTo: - name: websecure + port: websecure certificatesResolvers: From 631651d79b620f874402e50d7156e8b4a31e720d Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 15:43:12 +0200 Subject: [PATCH 22/98] fix --- environments/production/traefik/values.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/environments/production/traefik/values.yaml b/environments/production/traefik/values.yaml index c6f06b02..86b7f903 100644 --- a/environments/production/traefik/values.yaml +++ b/environments/production/traefik/values.yaml @@ -35,14 +35,17 @@ ports: hostPort: 80 protocol: TCP nodePort: 30080 + redirections: + entryPoint: + to: websecure + scheme: https + permanent: true + websecure: port: 8443 nodePort: 30443 hostPort: 443 protocol: TCP - redirectTo: - port: websecure - certificatesResolvers: letsencrypt: From 1f14c99940ff8b6e2fb7e5e208783b75a9b73a5b Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 15:49:11 +0200 Subject: [PATCH 23/98] fix --- environments/production/traefik/values.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/environments/production/traefik/values.yaml b/environments/production/traefik/values.yaml index 86b7f903..d00a773b 100644 --- a/environments/production/traefik/values.yaml +++ b/environments/production/traefik/values.yaml @@ -43,9 +43,9 @@ ports: websecure: port: 8443 - nodePort: 30443 hostPort: 443 protocol: TCP + nodePort: 30443 certificatesResolvers: letsencrypt: @@ -59,9 +59,9 @@ certificatesResolvers: # NOTE: Sometimes Let's Encrypt hit production SSL certificate issuing limits # If you are having issues, switch to staging # Staging server - # caServer: https://acme-staging-v02.api.letsencrypt.org/directory + caServer: https://acme-staging-v02.api.letsencrypt.org/directory # Production server - caServer: https://acme-v02.api.letsencrypt.org/directory + # caServer: https://acme-v02.api.letsencrypt.org/directory deployment: hostNetwork: true From ce83e342c9202e6f1f1541da95611f7444c33e9e Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 15:53:13 +0200 Subject: [PATCH 24/98] fix --- environments/production/traefik/values.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/environments/production/traefik/values.yaml b/environments/production/traefik/values.yaml index d00a773b..f3023866 100644 --- a/environments/production/traefik/values.yaml +++ b/environments/production/traefik/values.yaml @@ -46,6 +46,10 @@ ports: hostPort: 443 protocol: TCP nodePort: 30443 + # ADJUST OR REMOVE THIS LINE + tls: + enabled: true + certResolver: letsencrypt certificatesResolvers: letsencrypt: From be1f690e4150d3c64873b8da19dea229cdd8d63e Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 16:17:15 +0200 Subject: [PATCH 25/98] fix --- environments/production/traefik/values.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/environments/production/traefik/values.yaml b/environments/production/traefik/values.yaml index f3023866..e076f9b3 100644 --- a/environments/production/traefik/values.yaml +++ b/environments/production/traefik/values.yaml @@ -46,17 +46,17 @@ ports: hostPort: 443 protocol: TCP nodePort: 30443 - # ADJUST OR REMOVE THIS LINE + # 👇 Adjust this section at websecure entrypoint tls: enabled: true certResolver: letsencrypt +# 👇 Adjust this section if needed certificatesResolvers: letsencrypt: acme: tlsChallenge: true - httpChallenge: - entryPoint: web + # 👇 Provide admin email address email: vadym@opencrvs.org # Storage for certificates: storage: /certificates/acme.json From 128802e7be1516c098d90a92b946e23403a3c844 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 25 Nov 2025 16:41:44 +0200 Subject: [PATCH 26/98] fix --- environments/staging/dependencies/values.yaml | 3 --- environments/staging/opencrvs-services/values.yaml | 3 --- 2 files changed, 6 deletions(-) diff --git a/environments/staging/dependencies/values.yaml b/environments/staging/dependencies/values.yaml index 7362ff72..3186e054 100644 --- a/environments/staging/dependencies/values.yaml +++ b/environments/staging/dependencies/values.yaml @@ -2,9 +2,6 @@ storage_type: host_path environment_type: production -ingress: - tls_resolver: letsencrypt - minio: use_default_credentials: false diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index 0306edfe..129e3342 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -6,9 +6,6 @@ # - hostname: valid DNS name for opencrvs # - countryconfig.image.name: Countryconfig image repository # - countryconfig.image.tag: Countryconfig image tag -ingress: - tls_resolver: letsencrypt - environment_type: production hpa: From a3fa5245bae6595c4ba8e6ab235d436cfadb36a9 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 26 Nov 2025 14:50:31 +0200 Subject: [PATCH 27/98] testing --- infrastructure/server-setup/inventory/production.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/server-setup/inventory/production.yml b/infrastructure/server-setup/inventory/production.yml index eb71a886..2a2f05f3 100644 --- a/infrastructure/server-setup/inventory/production.yml +++ b/infrastructure/server-setup/inventory/production.yml @@ -17,7 +17,7 @@ all: # IMPORTANT: If master VM has multiple ethernet interfaces, put private IP address at kube_api_address # kube_api_host: 10.10.10.10 - kube_api_host: tmp-prod.opencrvs.dev + kube_api_host: # Default ansible provision user, keep as is ansible_user: provision From fdd6d081551499aca69335974eac62ba9d384d6d Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 26 Nov 2025 15:01:19 +0200 Subject: [PATCH 28/98] enable redis on existing envs --- environments/production/dependencies/values.yaml | 3 +++ environments/staging/dependencies/values.yaml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/environments/production/dependencies/values.yaml b/environments/production/dependencies/values.yaml index ebadabad..8a5ccc4d 100644 --- a/environments/production/dependencies/values.yaml +++ b/environments/production/dependencies/values.yaml @@ -14,6 +14,9 @@ mongodb: postgres: use_default_credentials: false +redis: + auth_mode: acl + monitoring: enabled: true diff --git a/environments/staging/dependencies/values.yaml b/environments/staging/dependencies/values.yaml index 3186e054..bee96bd8 100644 --- a/environments/staging/dependencies/values.yaml +++ b/environments/staging/dependencies/values.yaml @@ -14,6 +14,9 @@ mongodb: postgres: use_default_credentials: false +redis: + auth_mode: acl + monitoring: enabled: true From 14819078be9d2b9cea9ceda9c0349b2e0647c703 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 26 Nov 2025 16:49:03 +0200 Subject: [PATCH 29/98] testing --- environments/staging/opencrvs-services/values.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index 129e3342..8af7fe67 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -24,7 +24,6 @@ elasticsearch: minio: auth_mode: use_secret host: minio-0.minio.opencrvs-deps-staging.svc.cluster.local - external_hostname: minio.test-k8s.opencrvs.dev mongodb: auth_mode: auto From 643dd58433c6c1f11d262da60ad3910e34691059 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 27 Nov 2025 09:25:23 +0200 Subject: [PATCH 30/98] testing --- .../server-setup/inventory/production.yml | 63 ++++++++++++++++++- .../server-setup/inventory/staging.yml | 63 ++++++++++++++++++- 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/infrastructure/server-setup/inventory/production.yml b/infrastructure/server-setup/inventory/production.yml index 2a2f05f3..5c24ed5a 100644 --- a/infrastructure/server-setup/inventory/production.yml +++ b/infrastructure/server-setup/inventory/production.yml @@ -37,11 +37,72 @@ all: # - present, user is allowed to login # - absent, account is disabled users: - - name: vmudryi + - name: pyry + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJBcrSLLdrkLrhqNQi7Uo/ZIWXb1y4kc0vGb16e2s0Jq pyry@opencrvs.org + state: present + role: admin + - name: tameem + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGUprcQyUFYwRto0aRpgriR95C1pgNxrQ0lEWEe1D8he haidertameem@gmail.com + state: present + role: admin + - name: riku + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWIF63S4f3z9wQMvWibmvl7MPuJ6EVrkP0HuvgNhcs/4DZYMcR/GRBvV4ldOSYMlBevIXycgGzNDxKJgENUuwIWanjBu7uVAHyD6+cIRD1h63qq7Cjv/2HYTfBDKOrKzPOhA6zWvKO0ZGWsjRXk5LWMCbKOkvKJCxOpj/NVBxeE4FTK5YADYPV3OSsmBtqTHrVLm2sMmShU/2hMYYswWkobidjX65+nK/X+3C+yJbHwiydVvn+QCrFlFfCLPWKe8rUpOxyxofPqWVQh6CHhHfT8okaOc9sOE8Qeip9ljo84DftJh3Xm3ynOdWK1hH2BvRvxNadWqcE1qECbkg4tx2x riku.rouvila@gmail.com + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDGfWxxQHJv6Md/vBVoDH2UNm/uYgIBlFpP1mfh2Yj6jRNiQ/TQrfwpTawq0Sg+UW4LfYk5yxttsZ0h6L/v6PLiawgbMtf2ZqSviRTYSZTSihkK2zLmeJA2ByBCh57w4tR6IGqJK4w0kjYQSaaU6V5skQ4u+gnLQoKtkVQ4K34EFXAiIur96tLwjwDd/xCm+9T91+cAxGLv8Pe0PjirjwnvktUtzpgOhedkYK7KX0l8SKxQXUK6Ul2/QbpGO3rmguzEdtrl3Dw1TAEfu2njXbNGVQ+JWV9htH+ymsMIGoeumJRaaAZ4AXLlQPBCxTXcdQDuAjfFDPuppms/h7qB1S4Aioz7zqyd7pL7Z6Z8mJBZZlP3PsfGvADM2CdShpbL4HAa+n9miNNSYcJ7cHvC/zCitNjfaEYLVYkB5G+ggeK8Ss/MDcnsh3YFB8WnT582zt/TTJda5n+5Q7tquc1m+61t2gEKKTfBoDft9UYW2/4ViHj3ROL2Oyj7udrh/oAqV8M= riku@MBP16inch2231 + state: present + role: admin + - name: euan + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDECqHO65UpyrrO8uueD06RxGaVVq22f152Rf8qVQQAAIGAMu6gCs7ztlZ8a3yQgSEIjM/Jl1/RqIVs6CziTEef74nLFTZ5Ufz3CLRVgdebBeSBEmhTfTUV0HLkSyNzwKFpuzJxucGd72ulPvEp6eHvyJAPJz37YcU8cjaL1v05T6s2ee99li35GlDDtCzfjVV4ZPAg5JdfWuTj41RAVC0LQhk2/NB4qEu37UxGGjhRFSjBEsS5LxI9QfvgrsHpl/VOn+soH7ZkK7kS6qRgNP/uYsXRWXhHaamcl5OX68gJWTbrW6c7PCqlbCWGnsHJswCmqPIthwXXMfC7ULDNLSKG6mslAt5Dyc8/MCr3vTW7pDyr2d0FvvY86SMQUggxv3qF7TZewqfX1bhK0fMLarIxVMQ1RFo//wN9QGA+2we8rxd2Y1Kr1DBuJyuwXPfv+Exo8yNYQ+x/AYH5k6UVcSYuaB8eYmplG2KQCxt8RBFtoChrwOKNRWLqXdKyfpdp5XmnnWxPvR95gf3h3yLocVYkF0i0uvKKJ0vt8J0Ezfkdfow0B1kUg5bPXKJROX7PwbaCPdYcxyDaO6wwOigRnSmoFvkH1pLb4j1RQAXcX531CHgfN6Izi/h0mpMS4bnyIUcv2GQr+h4z4TxcCtj7qpH2y6yw7XG12jVh7TfeesXG2Q== euanmillar77@gmail.com + state: present + role: admin + - name: tahmid + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINUml9O5ySwPtEMD1yGEYHlf9Z3jro97NWAnM9+ew9gn tahmidrahman.dsi@gmail.com + state: present + role: admin + - name: tareq + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCWQihdKkwxTItN+rwYAX1vBg+8sv59sFsjYoVaO2mzS01rARfh+M+UVqpEv3zFT/3v6Dr5Z5VhzYvvbH8akiGQxURqie9quEi1iBCqcq+LApkMZxNm7yyvexlFsbkKMHsSZyVCzjE2Wt+6fwR1NqkMQgJjZS+b4CB+CUTNP2i6ytUTmck9K5iAOp1Gpm+Xgyvz6ZEJPkAJ16gV7gzNJUt/DSCkCyV8G2BqYLWeR2QxAbKyuf3LzO5i4XZdiZi9o60QAt3A6KGGLazd0UuYdehQDqVwXzwimLeeuZbaPNmwoAy7DeatOdurrWbnL7ytaiPvAbwai6Grt3PhhM41qO+uojnqTdnFdSOEPVIYMR7+mYu9tuwHZcMJIbbvMPD6EvKumD5Ndn5OxiLY/zQF5PuG89pBdTkTzzREvbV1Dkh2hwAIvgavlZl3P64On+4+FAgjrAx5U55khoRAe2FbEvB+EUGwro0bRffiM2NmxkUBraEuT2Xt5K01ZoBU6F4feO0= tareq.aziz@dsinnovators.com + state: present + role: admin + - name: jamil + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINMSNTIIsM0C3uJg3V/Fqh2gi4lvl2y6nenrb2Ft1JlX jamil31415926@gmail.com + state: present + role: admin + - name: ashikul + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDFr/v3hUGEbc2wQsDLCmqLrwiz964yVrnLZ6kafemjmX8aRGLp1CNFvrZ674SLnXidZGMkx9d5xVvv8IdFR3R50MqSqfolF43MV34/JVHjQHh9Vk4MJT/3GIaeNmr2GQ/38qAmt2BQn1ecnb7FjNO2bFvHokLhm2wCXt+A4avuTgJe0p4e6uu01IHeIzDb5sPzZ3ID0h6jJnjEDcET+Lf5NGpCjn7YKhLhBWSSl9cXQdOGLzNzg3aBk32kgJ1beP1funSeVd0jniJPZeZRC1G/kRdqBUOHKiENtwgquzZxXzdHkZV9+4mF7YGlx6LpQdNuDpW7JADtYNldtdbexdyfrgNoRzKwyMmaKNDbeHd1FsIHSDJmGm9hCoLTM2dEtsGzgghfe0tat8sOWmsj5v2en0V8rKV+w8OQEmHtaQkgMjqmZaAnd8uWiB2xIbrUuax5Pq8zkj37xnfbRxUPOEkMlOUbhh1wzGbqeUEB7nbv/vXZxwC0b7ryMk5egBP+0ZRONsdib9RkSTr3B9uSb7iTOQftdhy+CTqqOq+6s+TyC2qnu12B1WZb9sx9jQl0mBHd9gx/FgYDs8jfIr2vF4jRkejW/moaVqvCd/FLyS91eCMXQjIXdGKWKPUUL7GEBqdZRLnYSJOqgPp9sk1+NEvMabTXlWmoUjaShq8z+o7JsQ== nileeeem36@gmail.com + state: present + role: admin + - name: markus + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDGvvjFxXqcdKn9kk8VHzm38R3nLWvvwP8W0e3uXxOgby/7LJZx2bosXCZ28FyPTYwVRezHE9lguKiaCo2kxqzNwwx64MzUFRH60sE5cYeH1IqjCBTY3Ht8hkZlYaVoRmsHiqiqogW+bJPo8PBO+ydCh53KUdJFEOXAYvKZ/RfDsWh7/SjeQrQzpRFNeb9keefX+uNNBbKRm9/AEWIHFCGJpDvpJcz3i8hKbRPtXi5OTcEx1Kr4iOMikGXvGzsC1u84qgiy5moeBzpWeROwyJOHRLqPqQ/IHvUkE4F1BXen02G69nHpFdmjTOcjBbT1RzGTeWZs+ehc/kJaS3dUMHd5rSPsimjiCKZ5+wCAyxc5gJlQof71IpHVN4ZDoetH4Lo2bnLdA1YX6DaVU1Fd/6rPWw02DA1OEIhrjJ3Gak87/HUYGNhpZVyIxyNYGXBMPkmHCHCjzjN7sPdMRvkbl5tahD2PoS4172tsO7YYMfAZ/UYYZw745CDxQYIjjfrFRn8= markuslaurila@MacBook-Pro.local state: present role: admin + - name: vmudryi ssh_keys: - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINgMcsSBwTE0EbMDRSF1T4vJDcN/5HAjKGbi2DqV7g/Q vmudryi@opencrvs.org + state: present + role: admin + - name: cihan + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEEtz5M5hYKcUehDiCm84BplV+3t1ex8DPjIsMtQEWGv cihan.m.bebek@gmail.com + state: present + role: admin + - name: shoumik + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINRSRTqm3vOfjyTutISEtbVp7ZddoWa9NZDZLeWZGzLy dsi@dsi-Inspiron-15-3511 + state: present + role: admin + - name: pankaj + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL23KrPmFT6tZxR5d7dsTybtDf5j9DWzJcoR/Y7iJfL6 github + state: present + role: admin children: master: diff --git a/infrastructure/server-setup/inventory/staging.yml b/infrastructure/server-setup/inventory/staging.yml index 323eb680..4a61604f 100644 --- a/infrastructure/server-setup/inventory/staging.yml +++ b/infrastructure/server-setup/inventory/staging.yml @@ -32,11 +32,72 @@ all: # - present, user is allowed to login # - absent, account is disabled users: - - name: vmudryi + - name: pyry + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJBcrSLLdrkLrhqNQi7Uo/ZIWXb1y4kc0vGb16e2s0Jq pyry@opencrvs.org + state: present + role: admin + - name: tameem + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGUprcQyUFYwRto0aRpgriR95C1pgNxrQ0lEWEe1D8he haidertameem@gmail.com + state: present + role: admin + - name: riku + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWIF63S4f3z9wQMvWibmvl7MPuJ6EVrkP0HuvgNhcs/4DZYMcR/GRBvV4ldOSYMlBevIXycgGzNDxKJgENUuwIWanjBu7uVAHyD6+cIRD1h63qq7Cjv/2HYTfBDKOrKzPOhA6zWvKO0ZGWsjRXk5LWMCbKOkvKJCxOpj/NVBxeE4FTK5YADYPV3OSsmBtqTHrVLm2sMmShU/2hMYYswWkobidjX65+nK/X+3C+yJbHwiydVvn+QCrFlFfCLPWKe8rUpOxyxofPqWVQh6CHhHfT8okaOc9sOE8Qeip9ljo84DftJh3Xm3ynOdWK1hH2BvRvxNadWqcE1qECbkg4tx2x riku.rouvila@gmail.com + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDGfWxxQHJv6Md/vBVoDH2UNm/uYgIBlFpP1mfh2Yj6jRNiQ/TQrfwpTawq0Sg+UW4LfYk5yxttsZ0h6L/v6PLiawgbMtf2ZqSviRTYSZTSihkK2zLmeJA2ByBCh57w4tR6IGqJK4w0kjYQSaaU6V5skQ4u+gnLQoKtkVQ4K34EFXAiIur96tLwjwDd/xCm+9T91+cAxGLv8Pe0PjirjwnvktUtzpgOhedkYK7KX0l8SKxQXUK6Ul2/QbpGO3rmguzEdtrl3Dw1TAEfu2njXbNGVQ+JWV9htH+ymsMIGoeumJRaaAZ4AXLlQPBCxTXcdQDuAjfFDPuppms/h7qB1S4Aioz7zqyd7pL7Z6Z8mJBZZlP3PsfGvADM2CdShpbL4HAa+n9miNNSYcJ7cHvC/zCitNjfaEYLVYkB5G+ggeK8Ss/MDcnsh3YFB8WnT582zt/TTJda5n+5Q7tquc1m+61t2gEKKTfBoDft9UYW2/4ViHj3ROL2Oyj7udrh/oAqV8M= riku@MBP16inch2231 + state: present + role: admin + - name: euan + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDECqHO65UpyrrO8uueD06RxGaVVq22f152Rf8qVQQAAIGAMu6gCs7ztlZ8a3yQgSEIjM/Jl1/RqIVs6CziTEef74nLFTZ5Ufz3CLRVgdebBeSBEmhTfTUV0HLkSyNzwKFpuzJxucGd72ulPvEp6eHvyJAPJz37YcU8cjaL1v05T6s2ee99li35GlDDtCzfjVV4ZPAg5JdfWuTj41RAVC0LQhk2/NB4qEu37UxGGjhRFSjBEsS5LxI9QfvgrsHpl/VOn+soH7ZkK7kS6qRgNP/uYsXRWXhHaamcl5OX68gJWTbrW6c7PCqlbCWGnsHJswCmqPIthwXXMfC7ULDNLSKG6mslAt5Dyc8/MCr3vTW7pDyr2d0FvvY86SMQUggxv3qF7TZewqfX1bhK0fMLarIxVMQ1RFo//wN9QGA+2we8rxd2Y1Kr1DBuJyuwXPfv+Exo8yNYQ+x/AYH5k6UVcSYuaB8eYmplG2KQCxt8RBFtoChrwOKNRWLqXdKyfpdp5XmnnWxPvR95gf3h3yLocVYkF0i0uvKKJ0vt8J0Ezfkdfow0B1kUg5bPXKJROX7PwbaCPdYcxyDaO6wwOigRnSmoFvkH1pLb4j1RQAXcX531CHgfN6Izi/h0mpMS4bnyIUcv2GQr+h4z4TxcCtj7qpH2y6yw7XG12jVh7TfeesXG2Q== euanmillar77@gmail.com + state: present + role: admin + - name: tahmid + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINUml9O5ySwPtEMD1yGEYHlf9Z3jro97NWAnM9+ew9gn tahmidrahman.dsi@gmail.com + state: present + role: admin + - name: tareq + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCWQihdKkwxTItN+rwYAX1vBg+8sv59sFsjYoVaO2mzS01rARfh+M+UVqpEv3zFT/3v6Dr5Z5VhzYvvbH8akiGQxURqie9quEi1iBCqcq+LApkMZxNm7yyvexlFsbkKMHsSZyVCzjE2Wt+6fwR1NqkMQgJjZS+b4CB+CUTNP2i6ytUTmck9K5iAOp1Gpm+Xgyvz6ZEJPkAJ16gV7gzNJUt/DSCkCyV8G2BqYLWeR2QxAbKyuf3LzO5i4XZdiZi9o60QAt3A6KGGLazd0UuYdehQDqVwXzwimLeeuZbaPNmwoAy7DeatOdurrWbnL7ytaiPvAbwai6Grt3PhhM41qO+uojnqTdnFdSOEPVIYMR7+mYu9tuwHZcMJIbbvMPD6EvKumD5Ndn5OxiLY/zQF5PuG89pBdTkTzzREvbV1Dkh2hwAIvgavlZl3P64On+4+FAgjrAx5U55khoRAe2FbEvB+EUGwro0bRffiM2NmxkUBraEuT2Xt5K01ZoBU6F4feO0= tareq.aziz@dsinnovators.com + state: present + role: admin + - name: jamil + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINMSNTIIsM0C3uJg3V/Fqh2gi4lvl2y6nenrb2Ft1JlX jamil31415926@gmail.com + state: present + role: admin + - name: ashikul + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDFr/v3hUGEbc2wQsDLCmqLrwiz964yVrnLZ6kafemjmX8aRGLp1CNFvrZ674SLnXidZGMkx9d5xVvv8IdFR3R50MqSqfolF43MV34/JVHjQHh9Vk4MJT/3GIaeNmr2GQ/38qAmt2BQn1ecnb7FjNO2bFvHokLhm2wCXt+A4avuTgJe0p4e6uu01IHeIzDb5sPzZ3ID0h6jJnjEDcET+Lf5NGpCjn7YKhLhBWSSl9cXQdOGLzNzg3aBk32kgJ1beP1funSeVd0jniJPZeZRC1G/kRdqBUOHKiENtwgquzZxXzdHkZV9+4mF7YGlx6LpQdNuDpW7JADtYNldtdbexdyfrgNoRzKwyMmaKNDbeHd1FsIHSDJmGm9hCoLTM2dEtsGzgghfe0tat8sOWmsj5v2en0V8rKV+w8OQEmHtaQkgMjqmZaAnd8uWiB2xIbrUuax5Pq8zkj37xnfbRxUPOEkMlOUbhh1wzGbqeUEB7nbv/vXZxwC0b7ryMk5egBP+0ZRONsdib9RkSTr3B9uSb7iTOQftdhy+CTqqOq+6s+TyC2qnu12B1WZb9sx9jQl0mBHd9gx/FgYDs8jfIr2vF4jRkejW/moaVqvCd/FLyS91eCMXQjIXdGKWKPUUL7GEBqdZRLnYSJOqgPp9sk1+NEvMabTXlWmoUjaShq8z+o7JsQ== nileeeem36@gmail.com + state: present + role: admin + - name: markus + ssh_keys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDGvvjFxXqcdKn9kk8VHzm38R3nLWvvwP8W0e3uXxOgby/7LJZx2bosXCZ28FyPTYwVRezHE9lguKiaCo2kxqzNwwx64MzUFRH60sE5cYeH1IqjCBTY3Ht8hkZlYaVoRmsHiqiqogW+bJPo8PBO+ydCh53KUdJFEOXAYvKZ/RfDsWh7/SjeQrQzpRFNeb9keefX+uNNBbKRm9/AEWIHFCGJpDvpJcz3i8hKbRPtXi5OTcEx1Kr4iOMikGXvGzsC1u84qgiy5moeBzpWeROwyJOHRLqPqQ/IHvUkE4F1BXen02G69nHpFdmjTOcjBbT1RzGTeWZs+ehc/kJaS3dUMHd5rSPsimjiCKZ5+wCAyxc5gJlQof71IpHVN4ZDoetH4Lo2bnLdA1YX6DaVU1Fd/6rPWw02DA1OEIhrjJ3Gak87/HUYGNhpZVyIxyNYGXBMPkmHCHCjzjN7sPdMRvkbl5tahD2PoS4172tsO7YYMfAZ/UYYZw745CDxQYIjjfrFRn8= markuslaurila@MacBook-Pro.local state: present role: admin + - name: vmudryi ssh_keys: - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINgMcsSBwTE0EbMDRSF1T4vJDcN/5HAjKGbi2DqV7g/Q vmudryi@opencrvs.org + state: present + role: admin + - name: cihan + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEEtz5M5hYKcUehDiCm84BplV+3t1ex8DPjIsMtQEWGv cihan.m.bebek@gmail.com + state: present + role: admin + - name: shoumik + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINRSRTqm3vOfjyTutISEtbVp7ZddoWa9NZDZLeWZGzLy dsi@dsi-Inspiron-15-3511 + state: present + role: admin + - name: pankaj + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL23KrPmFT6tZxR5d7dsTybtDf5j9DWzJcoR/Y7iJfL6 github + state: present + role: admin children: master: From 01b88455705d75854decbb3900ecd1195ca0d293 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Sun, 30 Nov 2025 08:26:18 +0200 Subject: [PATCH 31/98] add reindex --- environments/staging/opencrvs-services/values.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index 8af7fe67..0c01ef9b 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -19,6 +19,9 @@ influxdb: elasticsearch: auth_mode: auto host: elasticsearch.opencrvs-deps-staging.svc.cluster.local + reindex: + enabled: true + schedule: "0 3 * * *" minio: From 7241c8b92dfdf37ade4777cc537f00ef367066cb Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 3 Dec 2025 10:54:31 +0200 Subject: [PATCH 32/98] fix --- .../staging/opencrvs-services/values.yaml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index 0c01ef9b..7c51d500 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -45,14 +45,15 @@ imagePullSecrets: - name: dockerhub-credentials countryconfig: - smtp-config: - - ALERT_EMAIL - - SENDER_EMAIL_ADDRESS - - SMTP_HOST - - SMTP_PASSWORD - - SMTP_PORT - - SMTP_SECURE - - SMTP_USERNAME + secrets: + smtp-config: + - ALERT_EMAIL + - SENDER_EMAIL_ADDRESS + - SMTP_HOST + - SMTP_PASSWORD + - SMTP_PORT + - SMTP_SECURE + - SMTP_USERNAME dashboards: enabled: true From aeef445b81048266fe4359891a8dc1ee290c1841 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 3 Dec 2025 12:58:58 +0200 Subject: [PATCH 33/98] fix --- environments/staging/opencrvs-services/values.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index 7c51d500..4249624e 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -45,6 +45,8 @@ imagePullSecrets: - name: dockerhub-credentials countryconfig: + env: + QA_ENV: false secrets: smtp-config: - ALERT_EMAIL From 2c1c745c48e6ef2625a374afa39cf6af7ca46da0 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 3 Dec 2025 13:04:25 +0200 Subject: [PATCH 34/98] fix --- environments/staging/opencrvs-services/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index 4249624e..76aba579 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -19,7 +19,7 @@ influxdb: elasticsearch: auth_mode: auto host: elasticsearch.opencrvs-deps-staging.svc.cluster.local - reindex: + cronjob: enabled: true schedule: "0 3 * * *" From 910ba9db1ea011f8dcf47c11d696c8de21371d1b Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 3 Dec 2025 13:17:24 +0200 Subject: [PATCH 35/98] fix --- .github/workflows/deploy-opencrvs.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/deploy-opencrvs.yml b/.github/workflows/deploy-opencrvs.yml index 05a1b09a..b54bdf91 100644 --- a/.github/workflows/deploy-opencrvs.yml +++ b/.github/workflows/deploy-opencrvs.yml @@ -35,6 +35,10 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 60 steps: + - name: Debug vars + run: | + echo "SENDER_EMAIL_ADDRESS: $SENDER_EMAIL_ADDRESS" + echo "ALERT_EMAIL: $ALERT_EMAIL" - name: Waiting for manual approval if: ${{ (vars.APPROVAL_REQUIRED || 'false') == 'true' }} uses: trstringer/manual-approval@v1 From 50b9c4c5d3eb7c4f1206d1443c687e1fd1f96df6 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 3 Dec 2025 13:19:48 +0200 Subject: [PATCH 36/98] fix --- .github/workflows/deploy-opencrvs.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-opencrvs.yml b/.github/workflows/deploy-opencrvs.yml index b54bdf91..c187b353 100644 --- a/.github/workflows/deploy-opencrvs.yml +++ b/.github/workflows/deploy-opencrvs.yml @@ -34,11 +34,14 @@ jobs: environment: ${{ inputs.environment }} runs-on: ubuntu-24.04 timeout-minutes: 60 + env: + SENDER_EMAIL_ADDRESS: ${{ vars.SENDER_EMAIL_ADDRESS }} + ALERT_EMAIL: ${{ vars.ALERT_EMAIL }} steps: - name: Debug vars run: | - echo "SENDER_EMAIL_ADDRESS: $SENDER_EMAIL_ADDRESS" - echo "ALERT_EMAIL: $ALERT_EMAIL" + echo "SENDER_EMAIL_ADDRESS: $SENDER_EMAIL_ADDRESS -> ${{ vars.SENDER_EMAIL_ADDRESS }}" + echo "ALERT_EMAIL: $ALERT_EMAIL -> ${{ vars.ALERT_EMAIL }}" - name: Waiting for manual approval if: ${{ (vars.APPROVAL_REQUIRED || 'false') == 'true' }} uses: trstringer/manual-approval@v1 From e7d61584782dcae4cba500640fb0e55ee5e46863 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 3 Dec 2025 13:25:11 +0200 Subject: [PATCH 37/98] fix --- .github/workflows/deploy-opencrvs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-opencrvs.yml b/.github/workflows/deploy-opencrvs.yml index c187b353..b10afdf3 100644 --- a/.github/workflows/deploy-opencrvs.yml +++ b/.github/workflows/deploy-opencrvs.yml @@ -42,6 +42,7 @@ jobs: run: | echo "SENDER_EMAIL_ADDRESS: $SENDER_EMAIL_ADDRESS -> ${{ vars.SENDER_EMAIL_ADDRESS }}" echo "ALERT_EMAIL: $ALERT_EMAIL -> ${{ vars.ALERT_EMAIL }}" + echo "${{ toJSON(vars) }}" - name: Waiting for manual approval if: ${{ (vars.APPROVAL_REQUIRED || 'false') == 'true' }} uses: trstringer/manual-approval@v1 From 1dd274097e6b56832383945f8edd9c91656862e2 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 3 Dec 2025 13:27:11 +0200 Subject: [PATCH 38/98] fixush --- .github/workflows/deploy-opencrvs.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/deploy-opencrvs.yml b/.github/workflows/deploy-opencrvs.yml index b10afdf3..05a1b09a 100644 --- a/.github/workflows/deploy-opencrvs.yml +++ b/.github/workflows/deploy-opencrvs.yml @@ -34,15 +34,7 @@ jobs: environment: ${{ inputs.environment }} runs-on: ubuntu-24.04 timeout-minutes: 60 - env: - SENDER_EMAIL_ADDRESS: ${{ vars.SENDER_EMAIL_ADDRESS }} - ALERT_EMAIL: ${{ vars.ALERT_EMAIL }} steps: - - name: Debug vars - run: | - echo "SENDER_EMAIL_ADDRESS: $SENDER_EMAIL_ADDRESS -> ${{ vars.SENDER_EMAIL_ADDRESS }}" - echo "ALERT_EMAIL: $ALERT_EMAIL -> ${{ vars.ALERT_EMAIL }}" - echo "${{ toJSON(vars) }}" - name: Waiting for manual approval if: ${{ (vars.APPROVAL_REQUIRED || 'false') == 'true' }} uses: trstringer/manual-approval@v1 From 09da9fe97ca0b0fb8ab74409bbd63fb862677c0a Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 3 Dec 2025 13:50:36 +0200 Subject: [PATCH 39/98] fixush --- environments/staging/dependencies/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environments/staging/dependencies/values.yaml b/environments/staging/dependencies/values.yaml index bee96bd8..f89bc415 100644 --- a/environments/staging/dependencies/values.yaml +++ b/environments/staging/dependencies/values.yaml @@ -22,7 +22,7 @@ monitoring: elastalert: env: - HTTP_POST2_ALERT_URL: http://countryconfig.opencrvs-staging.svc.cluster.local:3040 + HTTP_POST2_ALERT_URL: http://countryconfig.opencrvs-staging.svc.cluster.local:3040/email # Restore configuration restore: From 937d188551576f2a932c062657e5bc1a97e083bb Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 3 Dec 2025 14:30:57 +0200 Subject: [PATCH 40/98] fix --- environments/staging/opencrvs-services/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index 76aba579..08ad7ae1 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -33,7 +33,7 @@ mongodb: host: mongodb-0.mongodb.opencrvs-deps-staging.svc.cluster.local redis: - auth_mode: acl + auth_mode: use_secret host: redis-0.redis.opencrvs-deps-staging.svc.cluster.local postgres: From ed883ccff758f99f776016f349a28515dd192d76 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Mon, 8 Dec 2025 17:29:54 +0200 Subject: [PATCH 41/98] fix: Add gather facts to master --- infrastructure/server-setup/k8s.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/infrastructure/server-setup/k8s.yml b/infrastructure/server-setup/k8s.yml index 125ef615..bc457aed 100644 --- a/infrastructure/server-setup/k8s.yml +++ b/infrastructure/server-setup/k8s.yml @@ -64,6 +64,7 @@ - name: Initialize Kubernetes Master hosts: master tags: k8s + gather_facts: yes tasks: - name: Include master initialization include_tasks: tasks/k8s/init-master.yml From 0bd29cc3e595151f5ab9e18af3aa176ce793ed00 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Mon, 8 Dec 2025 17:45:45 +0200 Subject: [PATCH 42/98] testing --- infrastructure/server-setup/k8s.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infrastructure/server-setup/k8s.yml b/infrastructure/server-setup/k8s.yml index bc457aed..9883c04f 100644 --- a/infrastructure/server-setup/k8s.yml +++ b/infrastructure/server-setup/k8s.yml @@ -61,10 +61,10 @@ - kubernetes-installation tags: - kubernetes-installation -- name: Initialize Kubernetes Master + +- name: Kubernetes Master hosts: master tags: k8s - gather_facts: yes tasks: - name: Include master initialization include_tasks: tasks/k8s/init-master.yml @@ -73,7 +73,7 @@ - name: Upgrade cluster include_tasks: tasks/k8s/upgrade-k8s-master.yml -- name: Join Worker Nodes +- name: Kubernetes Worker Nodes hosts: workers tags: - join-workers From 668094d5991987d2a4604be67bab5e40063ec94c Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Fri, 12 Dec 2025 16:51:47 +0200 Subject: [PATCH 43/98] testing --- infrastructure/server-setup/inventory/staging.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/infrastructure/server-setup/inventory/staging.yml b/infrastructure/server-setup/inventory/staging.yml index 4a61604f..8643f2f1 100644 --- a/infrastructure/server-setup/inventory/staging.yml +++ b/infrastructure/server-setup/inventory/staging.yml @@ -98,6 +98,11 @@ all: - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL23KrPmFT6tZxR5d7dsTybtDf5j9DWzJcoR/Y7iJfL6 github state: present role: admin + - name: alise + ssh_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINRSRTqm3vOfjyTutISEtbVp7ZddoWa9NZDZLeWZGzLy/Y7iJfL6 github + state: present + role: operator children: master: From ef4aa92dd5c8f0834a3eab779f2b959bbd441395 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 17 Dec 2025 19:17:52 +0200 Subject: [PATCH 44/98] fix --- .github/TEMPLATES/secret-mapping-opencrvs-deps.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml index 42413fd7..28c33dba 100644 --- a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml +++ b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml @@ -35,10 +35,6 @@ postgres-admin-user: - POSTGRES_USER - POSTGRES_PASSWORD -foo-secret: - - POSTGRES_USER - - DUMMY_VARIABLE - kibana-users-secret: type: Opaque data: From 6374ef8dde3fa4f9ff74ef484d52210413b4a778 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 18 Dec 2025 10:30:00 +0200 Subject: [PATCH 45/98] fix: Move dockerhub secret creation to deployment phase --- .github/workflows/github-to-k8s-sync-env.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index c457d76d..7749cc32 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -56,6 +56,23 @@ jobs: echo env_file=$ENV_FILE >> $GITHUB_ENV cat $ENV_FILE + - name: Map Dockerhub credentials if available + env: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME || '' }} + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN || '' }} + DOCKERHUB_SECRET_NAME: ${{ vars.DOCKERHUB_SECRET_NAME || 'dockerhub-credentials' }} + NAMSPACE_TEMPLATE: ${{ inputs.namespace_template }} + run: | + if [ -n "$DOCKERHUB_USERNAME" ] && [ -n "$DOCKERHUB_TOKEN" ] && [ "$NAMSPACE_TEMPLATE" == "opencrvs" ]; then + kubectl create secret docker-registry "$DOCKERHUB_SECRET_NAME" \ + --docker-server=https://index.docker.io/v1/ \ + --docker-username="$DOCKERHUB_USERNAME" \ + --docker-password="$DOCKERHUB_TOKEN" \ + --dry-run=client -o yaml > "k8s-secrets/$secret_name.yaml" + echo "✅ Generated Docker Registry Secret manifest: k8s-secrets/$secret_name.yaml + else + echo "ℹ️ Dockerhub credentials not provided, skipping Docker Registry Secret creation for $secret_name" + fi - name: Preprocess mapping into Secret YAMLs run: | set -euo pipefail From c974b88d5be4b9f68cfb3e589eb99bb590117aa6 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 18 Dec 2025 11:33:19 +0200 Subject: [PATCH 46/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 7749cc32..c457d76d 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -56,23 +56,6 @@ jobs: echo env_file=$ENV_FILE >> $GITHUB_ENV cat $ENV_FILE - - name: Map Dockerhub credentials if available - env: - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME || '' }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN || '' }} - DOCKERHUB_SECRET_NAME: ${{ vars.DOCKERHUB_SECRET_NAME || 'dockerhub-credentials' }} - NAMSPACE_TEMPLATE: ${{ inputs.namespace_template }} - run: | - if [ -n "$DOCKERHUB_USERNAME" ] && [ -n "$DOCKERHUB_TOKEN" ] && [ "$NAMSPACE_TEMPLATE" == "opencrvs" ]; then - kubectl create secret docker-registry "$DOCKERHUB_SECRET_NAME" \ - --docker-server=https://index.docker.io/v1/ \ - --docker-username="$DOCKERHUB_USERNAME" \ - --docker-password="$DOCKERHUB_TOKEN" \ - --dry-run=client -o yaml > "k8s-secrets/$secret_name.yaml" - echo "✅ Generated Docker Registry Secret manifest: k8s-secrets/$secret_name.yaml - else - echo "ℹ️ Dockerhub credentials not provided, skipping Docker Registry Secret creation for $secret_name" - fi - name: Preprocess mapping into Secret YAMLs run: | set -euo pipefail From 9a664f8bc82f23b723de2415b9c963319b7a9158 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 18 Dec 2025 13:34:34 +0200 Subject: [PATCH 47/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index c457d76d..4ff6f09d 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -13,7 +13,7 @@ on: - demo1 - production - staging - mapping_file: + namespace_template: description: "Secrets mapping template" default: "opencrvs" type: choice From f8435158269336408cc6ecc3b45bbd92f9793efe Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 18 Dec 2025 15:02:54 +0200 Subject: [PATCH 48/98] testing --- environments/production/opencrvs-services/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environments/production/opencrvs-services/values.yaml b/environments/production/opencrvs-services/values.yaml index 8d031129..f6a3ede1 100644 --- a/environments/production/opencrvs-services/values.yaml +++ b/environments/production/opencrvs-services/values.yaml @@ -30,7 +30,7 @@ mongodb: host: mongodb-0.mongodb.opencrvs-deps-production.svc.cluster.local redis: - auth_mode: acl + auth_mode: use_secret host: redis-0.redis.opencrvs-deps-production.svc.cluster.local postgres: From 203395a60ebcc934228440f181e77530277f4d5d Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 18 Dec 2025 15:10:40 +0200 Subject: [PATCH 49/98] testing --- environments/production/opencrvs-services/values.yaml | 4 ---- environments/staging/opencrvs-services/values.yaml | 3 --- 2 files changed, 7 deletions(-) diff --git a/environments/production/opencrvs-services/values.yaml b/environments/production/opencrvs-services/values.yaml index f6a3ede1..e3d4959a 100644 --- a/environments/production/opencrvs-services/values.yaml +++ b/environments/production/opencrvs-services/values.yaml @@ -51,7 +51,3 @@ countryconfig: - SMTP_PORT - SMTP_SECURE - SMTP_USERNAME - - -dashboards: - enabled: true diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index 08ad7ae1..b6944173 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -56,6 +56,3 @@ countryconfig: - SMTP_PORT - SMTP_SECURE - SMTP_USERNAME - -dashboards: - enabled: true From c1d52e0681de3fe1c6b7ce9fa1981246d5009641 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 18 Dec 2025 15:29:02 +0200 Subject: [PATCH 50/98] testing --- environments/staging/opencrvs-services/values.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index b6944173..d9197a51 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -45,8 +45,6 @@ imagePullSecrets: - name: dockerhub-credentials countryconfig: - env: - QA_ENV: false secrets: smtp-config: - ALERT_EMAIL From aa7b4ae499c27049f1abb6387174b38320b661bc Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 18 Dec 2025 15:33:05 +0200 Subject: [PATCH 51/98] testing --- environments/staging/opencrvs-services/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environments/staging/opencrvs-services/values.yaml b/environments/staging/opencrvs-services/values.yaml index d9197a51..b2737f12 100644 --- a/environments/staging/opencrvs-services/values.yaml +++ b/environments/staging/opencrvs-services/values.yaml @@ -13,7 +13,7 @@ hpa: env: APN_SERVICE_URL: "http://apm-server.opencrvs-deps-staging.svc.cluster.local:8200" - + QA_ENV: true influxdb: host: influxdb-0.influxdb.opencrvs-deps-staging.svc.cluster.local elasticsearch: From d6045a424ea0330675ccfce9c830398d0c4534ef Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Thu, 18 Dec 2025 18:29:15 +0200 Subject: [PATCH 52/98] feat: Manage backup/restore from environments:init --- .../secret-mapping-opencrvs-deps.yml | 12 + .github/workflows/deploy-opencrvs.yml | 1 + .../workflows/get-secret-from-environment.yml | 102 ++ .github/workflows/github-to-k8s-sync-env.yml | 71 +- .github/workflows/provision.yml | 2 + .../environments/derived-variables.ts | 156 ++++ infrastructure/environments/github.ts | 18 + infrastructure/environments/questions.ts | 417 +++++++++ .../environments/setup-environment.ts | 875 +++++------------- infrastructure/environments/ssh-keygen.ts | 6 + infrastructure/environments/utils.ts | 8 + .../server-setup/group_vars/all.yml | 2 - infrastructure/server-setup/k8s.yml | 2 - .../create-backup-server-credentials.yml | 19 +- .../server-setup/tasks/k8s/backup-secret.yml | 35 - package.json | 4 +- yarn.lock | 121 ++- 17 files changed, 1129 insertions(+), 722 deletions(-) create mode 100644 .github/workflows/get-secret-from-environment.yml create mode 100644 infrastructure/environments/derived-variables.ts create mode 100644 infrastructure/environments/questions.ts create mode 100644 infrastructure/environments/ssh-keygen.ts create mode 100644 infrastructure/environments/utils.ts delete mode 100644 infrastructure/server-setup/tasks/k8s/backup-secret.yml diff --git a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml index 28c33dba..9b241842 100644 --- a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml +++ b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml @@ -47,3 +47,15 @@ traefik-cert: data: - TRAEFIK_CERT: cert - TRAEFIK_KEY: key + +backup-server-ssh-credentials: + type: Opaque + data: + - BACKUP_SERVER_USER: user + - BACKUP_HOST_PRIVATE_KEY: ssh_key + - BACKUP_HOST: host + +backup-encryption-secret: + type: Opaque + data: + - BACKUP_ENCRYPTION_PASSPHRASE: backup_encryption_key diff --git a/.github/workflows/deploy-opencrvs.yml b/.github/workflows/deploy-opencrvs.yml index 05a1b09a..f5335fe3 100644 --- a/.github/workflows/deploy-opencrvs.yml +++ b/.github/workflows/deploy-opencrvs.yml @@ -58,6 +58,7 @@ jobs: uses: ./.github/workflows/github-to-k8s-sync-env.yml with: environment: ${{ inputs.environment }} + restore_environment: ${{ vars.RESTORE_ENVIRONMENT_NAME || 'false' }} secrets: inherit deploy: needs: github-to-k8s-sync-env diff --git a/.github/workflows/get-secret-from-environment.yml b/.github/workflows/get-secret-from-environment.yml new file mode 100644 index 00000000..7700e98e --- /dev/null +++ b/.github/workflows/get-secret-from-environment.yml @@ -0,0 +1,102 @@ +name: Reusable Fetch Secret Workflow +# TODO: Check if this workflow can be simplified +on: + workflow_call: + inputs: + secret_name: + required: true + type: string + env_name: + required: true + type: string + outputs: + secret_value: + description: 'Secret value, encrypted with the encryption key' + value: ${{ jobs.fetch-credentials.outputs.secret_value }} + environment_exists: + description: 'Whether the environment exists or not' + value: ${{ jobs.check-environment.outputs.environment_exists }} + secrets: + gh_token: + required: true + encryption_key: + required: true + # All secrets that are we want to allow access to need + # to be defined in this list + BACKUP_ENCRYPTION_PASSPHRASE: + required: false + BACKUP_HOST_PRIVATE_KEY: + required: false + BACKUP_HOST: + required: false + BACKUP_SERVER_USER: + required: false + +jobs: + check-environment: + name: Check if Environment Exists + runs-on: ubuntu-24.04 + outputs: + environment_exists: ${{ steps.check-env.outputs.exists }} + steps: + - name: Check if GITHUB_TOKEN is set + id: check-token + run: | + if [ -z "${{ secrets.gh_token }}" ]; then + echo "Environment secret GITHUB_TOKEN is not set. Make sure you add a correct Github API token before running this pipeline." + exit 1 + fi + + - name: Verify GitHub token validity + id: verify-token + run: | + RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer ${{ secrets.gh_token }}" \ + "https://api.github.com/user") + if [ "$RESPONSE" -ne 200 ]; then + echo "Invalid or expired GitHub token." + exit 1 + fi + echo "GitHub token is valid." + + - name: Check if environment exists + id: check-env + run: | + ENV_NAME="${{ inputs.env_name }}" + RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.gh_token }}" \ + "https://api.github.com/repos/${{ github.repository }}/environments/$ENV_NAME") + if echo "$RESPONSE" | grep -q '"name": "'$ENV_NAME'"'; then + echo "Environment $ENV_NAME exists." + echo "exists=true" >> $GITHUB_OUTPUT + else + echo "Environment $ENV_NAME does not exist." + echo "exists=false" >> $GITHUB_OUTPUT + fi + + fetch-credentials: + name: Fetch Secret + runs-on: ubuntu-24.04 + environment: ${{ inputs.env_name }} + needs: check-environment + # Without this Github actions will create the environment when it doesnt exist + if: needs.check-environment.outputs.environment_exists == 'true' + outputs: + secret_value: ${{ steps.fetch-credentials.outputs.secret_value }} + steps: + - name: Fetch the secret + id: fetch-credentials + env: + SECRET_NAME: ${{ inputs.secret_name }} + run: | + SECRET_VALUE="${{ secrets[env.SECRET_NAME] }}" + if [ -z "$SECRET_VALUE" ]; then + echo "Secret ${{ inputs.secret_name }} is empty. Usually this means you have not explicitly stated the secrets" + echo "in both the workflow file get-secrets-from-environment and in the file you are using the reusable workflow from." + echo "Please make sure you have added the secret to the workflow files and retry." + exit 1 + fi + echo -n "$SECRET_VALUE" | openssl enc -aes-256-cbc -pbkdf2 -salt -k "${{ secrets.encryption_key }}" -out encrypted_key.bin + ENCODED_ENCRYPTED_SECRET=$(base64 < encrypted_key.bin) + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "secret_value<<$EOF" >> $GITHUB_OUTPUT + echo "$ENCODED_ENCRYPTED_SECRET" >> $GITHUB_OUTPUT + echo "$EOF" >> $GITHUB_OUTPUT diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 4ff6f09d..f17b79c5 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -13,6 +13,11 @@ on: - demo1 - production - staging + restore_environment: + description: "Restore environment name" + required: false + default: "false" + type: string namespace_template: description: "Secrets mapping template" default: "opencrvs" @@ -27,10 +32,59 @@ on: default: dev namespace_template: type: string - default: opencrvs + default: opencrvs + restore_environment: + type: string + default: "false" jobs: + get-backup-user: + name: Get backup user + uses: ./.github/workflows/get-secret-from-environment.yml + with: + secret_name: 'BACKUP_SERVER_USER' + env_name: ${{ inputs.restore_environment }} + secrets: + gh_token: ${{ secrets.GH_TOKEN }} + encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + + get-backup-host: + name: Get backup host + uses: ./.github/workflows/get-secret-from-environment.yml + with: + secret_name: 'BACKUP_HOST' + env_name: ${{ inputs.restore_environment }} + secrets: + gh_token: ${{ secrets.GH_TOKEN }} + encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + + get-backup-ssh-key: + name: Get backup SSH key + uses: ./.github/workflows/get-secret-from-environment.yml + with: + secret_name: 'BACKUP_HOST_PRIVATE_KEY' + env_name: ${{ inputs.restore_environment }} + secrets: + gh_token: ${{ secrets.GH_TOKEN }} + encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + + get-backup-encryption-key: + name: Get backup encryption key + uses: ./.github/workflows/get-secret-from-environment.yml + with: + secret_name: 'BACKUP_ENCRYPTION_PASSPHRASE' + env_name: ${{ inputs.restore_environment }} + secrets: + gh_token: ${{ secrets.GH_TOKEN }} + encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + sync-env: + needs: + - get-backup-user + - get-backup-host + - get-backup-encryption-key + - get-backup-ssh-key + name: Sync GitHub env to Kubernetes environment: ${{ inputs.environment }} runs-on: - self-hosted @@ -55,6 +109,21 @@ jobs: echo env_file=$ENV_FILE >> $GITHUB_ENV cat $ENV_FILE + - name: Save secrets + if: needs.get-backup-user.outputs.environment_exists == 'true' + run: | + echo "${{ needs.get-backup-user.outputs.secret_value }}" | base64 --decode | \ + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_user + echo "${{ needs.get-backup-host.outputs.secret_value }}" | base64 --decode | \ + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_host + echo "${{ needs.get-backup-encryption-key.outputs.secret_value }}" | base64 --decode | \ + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_encryption_key + echo "${{ needs.get-backup-ssh-key.outputs.secret_value }}" | base64 --decode | \ + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_ssh_key + echo BACKUP_USER=$(cat /tmp/backup_user | base64) >> $env_file + echo BACKUP_HOST=$(cat /tmp/backup_host | base64) >> $env_file + echo BACKUP_ENCRYPTION_PASSPHRASE=$(cat /tmp/backup_encryption_key | base64) >> $env_file + echo BACKUP_HOST_PRIVATE_KEY=$(cat /tmp/backup_ssh_key | base64) >> $env_file - name: Preprocess mapping into Secret YAMLs run: | diff --git a/.github/workflows/provision.yml b/.github/workflows/provision.yml index 559649c2..832a6136 100644 --- a/.github/workflows/provision.yml +++ b/.github/workflows/provision.yml @@ -79,6 +79,8 @@ jobs: smtp_from: "team@opencrvs.org" smtp_password: ${{ secrets.SMTP_PASSWORD }} alert_email: ${{ secrets.ALERT_EMAIL }} + backup_host_public_key: ${{ secrets.BACKUP_HOST_PUBLIC_KEY }} + backup_server_user: ${{ secrets.BACKUP_SERVER_USER }} - name: checkout repository uses: actions/checkout@v6 - name: Run Ansible Playbook diff --git a/infrastructure/environments/derived-variables.ts b/infrastructure/environments/derived-variables.ts new file mode 100644 index 00000000..80e0373c --- /dev/null +++ b/infrastructure/environments/derived-variables.ts @@ -0,0 +1,156 @@ +export const derivedVariables = [ + { + name: 'ACTIVATE_USERS', + valueLabel: 'ACTIVATE_USERS', + valueType: 'VARIABLE', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'AUTH_HOST', + valueLabel: 'AUTH_HOST', + valueType: 'VARIABLE', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'COUNTRY_CONFIG_HOST', + valueLabel: 'COUNTRY_CONFIG_HOST', + valueType: 'VARIABLE', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'GATEWAY_HOST', + valueLabel: 'GATEWAY_HOST', + valueType: 'VARIABLE', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'CONTENT_SECURITY_POLICY_WILDCARD', + valueLabel: 'CONTENT_SECURITY_POLICY_WILDCARD', + valueType: 'VARIABLE', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'CLIENT_APP_URL', + valueLabel: 'CLIENT_APP_URL', + valueType: 'VARIABLE', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'LOGIN_URL', + valueLabel: 'LOGIN_URL', + valueType: 'VARIABLE', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'ELASTICSEARCH_SUPERUSER_PASSWORD', + valueLabel: 'ELASTICSEARCH_SUPERUSER_PASSWORD', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'KIBANA_SYSTEM_PASSWORD', + valueLabel: 'KIBANA_SYSTEM_PASSWORD', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'MINIO_ROOT_USER', + valueLabel: 'MINIO_ROOT_USER', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'MINIO_ROOT_PASSWORD', + valueLabel: 'MINIO_ROOT_PASSWORD', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'MONGODB_ADMIN_USER', + valueLabel: 'MONGODB_ADMIN_USER', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'MONGODB_ADMIN_PASSWORD', + valueLabel: 'MONGODB_ADMIN_PASSWORD', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'POSTGRES_USER', + valueLabel: 'POSTGRES_USER', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'POSTGRES_PASSWORD', + valueLabel: 'POSTGRES_PASSWORD', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'SUPER_USER_PASSWORD', + valueLabel: 'SUPER_USER_PASSWORD', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'ENCRYPTION_KEY', + valueLabel: 'ENCRYPTION_KEY', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'GH_ENCRYPTION_PASSWORD', + valueLabel: 'GH_ENCRYPTION_PASSWORD', + valueType: 'SECRET', + type: 'disabled', + scope: 'REPOSITORY' + }, + { + name: 'BACKUP_ENCRYPTION_PASSPHRASE', + valueLabel: 'BACKUP_ENCRYPTION_PASSPHRASE', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'BACKUP_HOST_PRIVATE_KEY', + valueLabel: 'BACKUP_HOST_PRIVATE_KEY', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'BACKUP_HOST_PUBLIC_KEY', + valueLabel: 'BACKUP_HOST_PUBLIC_KEY', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, + { + name: 'RESTORE_ENVIRONMENT_NAME', + valueLabel: 'RESTORE_ENVIRONMENT_NAME', + valueType: 'SECRET', + type: 'disabled', + scope: 'ENVIRONMENT' + }, +] as const; \ No newline at end of file diff --git a/infrastructure/environments/github.ts b/infrastructure/environments/github.ts index 2b27921d..ce51f0e4 100644 --- a/infrastructure/environments/github.ts +++ b/infrastructure/environments/github.ts @@ -235,6 +235,24 @@ export async function createRepositorySecret( ) } +export async function getRepositoryEnvironments( + octokit: Octokit, + githubOrganisation: string, + repository: string +): Promise { + + const response = await octokit.request('GET /repos/{githubOrganisation}/{repository}/environments', { + githubOrganisation, + repository, + }); + + // Safe access with fallback to empty array if undefined + const environments = (response.data.environments ?? []).map( + (env: { name: string }) => env.name + ); + return environments; +} + export async function createEnvironment( octokit: Octokit, environment: string, diff --git a/infrastructure/environments/questions.ts b/infrastructure/environments/questions.ts new file mode 100644 index 00000000..2de694a4 --- /dev/null +++ b/infrastructure/environments/questions.ts @@ -0,0 +1,417 @@ +import kleur from 'kleur' +import { generateLongPassword } from './utils' + + +const notEmpty = (value: string | number) => + value.toString().trim().length > 0 ? true : 'Please enter a value' + +export const environmentQuestions = [ + { + name: 'type', + type: 'select' as const, + scope: 'ENVIRONMENT' as const, + message: 'Purpose for the environment?', + choices: [ + { title: 'Development/Quality assurance/Testing (no PII data)', value: 'non-production' }, + { title: 'Staging/Production (hosts PII data, requires frequent backups)', value: 'production' }, + ] + }, + { + name: 'environment', + type: 'text' as const, + message: 'What is the name of your environment?', + validate: notEmpty, + initial: process.env.ENV, + scope: 'REPOSITORY' as const + } +] +export const dockerhubQuestions = [ + { + name: 'dockerhubOrganisation', + type: 'text' as const, + message: 'What is the name of your Docker Hub organisation?', + valueType: 'SECRET' as const, + valueLabel: 'DOCKERHUB_ACCOUNT', + validate: notEmpty, + initial: process.env.DOCKER_ORGANISATION, + scope: 'REPOSITORY' as const + }, + { + name: 'dockerhubRepository', + type: 'text' as const, + message: 'What is the name of your private Docker Hub repository?', + valueType: 'SECRET' as const, + valueLabel: 'DOCKERHUB_REPO', + validate: notEmpty, + initial: process.env.DOCKER_REPO, + scope: 'REPOSITORY' as const + }, + { + name: 'dockerhubUsername', + type: 'text' as const, + message: + 'What is the Docker Hub username the the target server should be using?', + valueType: 'SECRET' as const, + valueLabel: 'DOCKER_USERNAME', + validate: notEmpty, + initial: process.env.DOCKER_USERNAME, + scope: 'REPOSITORY' as const + }, + { + name: 'dockerhubToken', + type: 'text' as const, + message: 'What is the token of this Docker Hub account?', + valueType: 'SECRET' as const, + valueLabel: 'DOCKER_TOKEN', + validate: notEmpty, + initial: process.env.DOCKER_TOKEN, + scope: 'REPOSITORY' as const + } +] + +export const githubQuestions = [ + { + name: 'githubOrganisation', + type: 'text' as const, + message: 'What is the name of your Github organisation?', + validate: notEmpty, + initial: process.env.GITHUB_ORGANISATION, + scope: 'REPOSITORY' as const + }, + { + name: 'githubRepository', + type: 'text' as const, + message: 'What is your Github infrastructure repository?', + validate: notEmpty, + initial: process.env.GITHUB_REPOSITORY, + scope: 'REPOSITORY' as const + }, +] +export const githubOtherQuestions = [ + { + name: 'githubApprovers', + type: 'text' as const, + message: 'Please provide/update list of production approvers?', + initial: process.env.GH_APPROVERS, + valueType: 'VARIABLE' as const, + valueLabel: 'GH_APPROVERS', + scope: 'REPOSITORY' as const + }, + { + name: 'approvalRequired', + type: 'select' as const, + message: 'Would you like to enable approvals process for GitHub action workflows?', + choices: [ + { + title: 'True', + value: 'true' + }, + { + title: 'False', + value: 'false' + } + ], + valueType: 'VARIABLE' as const, + validate: notEmpty, + valueLabel: 'APPROVAL_REQUIRED', + initial: process.env.APPROVAL_REQUIRED, + scope: 'ENVIRONMENT' as const + }, +] +export const githubTokenQuestion = [ + { + name: 'githubToken', + type: 'text' as const, + message: 'What is your Github token?', + validate: notEmpty, + initial: process.env.GITHUB_TOKEN, + valueType: 'SECRET' as const, + scope: 'REPOSITORY' as const, + valueLabel: 'GH_TOKEN' + } +] + +export const countryQuestions = [ + { + name: 'country', + type: 'text' as const, + message: + 'What is the ISO 3166-1 alpha-3 country-code? (e.g. "NZL" for New Zealand) Reference: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3', + valueType: 'VARIABLE' as const, + valueLabel: 'COUNTRY', + initial: process.env.COUNTRY, + scope: 'REPOSITORY' as const + } +] + +export const infrastructureQuestions = [ + { + name: 'domain', + type: 'text' as const, + message: 'What is the web domain applied after all subdomains in URLs?', + valueType: 'VARIABLE' as const, + validate: notEmpty, + valueLabel: 'DOMAIN', + initial: process.env.DOMAIN, + scope: 'ENVIRONMENT' as const + }, + { + name: 'kubeAPIHost', + type: 'text' as const, + message: + `Please enter host/IP to expose Kubernetes API endpoint, (default: Master first IP address):`, + valueType: 'VARIABLE' as const, + // validate: notEmpty, + valueLabel: 'KUBE_API_HOST', + initial: process.env.KUBE_API_HOST || '', + scope: 'ENVIRONMENT' as const + }, + { + name: 'workerNodes', + type: 'text' as const, + message: + `Please enter Kubernetes workers hosts/IP addresses (comma-separated), (default: no workers):`, + valueType: 'VARIABLE' as const, + // validate: notEmpty, + valueLabel: 'WORKER_NODES', + initial: process.env.WORKER_NODES || '', + scope: 'ENVIRONMENT' as const, + }, +] + +export const backupQuestions = [ + { + name: 'backupHost', + type: 'text' as const, + message: + `Please enter backup server host/IP address, (default: no backup):`, + valueType: 'SECRET' as const, + // validate: notEmpty, + valueLabel: 'BACKUP_HOST', + initial: process.env.BACKUP_HOST || '', + scope: 'ENVIRONMENT' as const, + }, + { + name: 'backupUser', + type: 'text' as const, + message: + `Please enter backup server user name:`, + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'BACKUP_SERVER_USER', + initial: process.env.BACKUP_SERVER_USER || 'backup', + scope: 'ENVIRONMENT' as const, + }, +] + +export const diskQuestions = [ + { + name: 'diskSpace', + type: 'text' as const, + message: `What is the amount of diskspace that should be dedicated to OpenCRVS data and will become the size of an encrypted cryptfs data directory. + \n${kleur.red('DO NOT USE ALL DISKSPACE FOR OPENCRVS!')} + \nLeave at least 50g available for OS use.`, + valueType: 'VARIABLE' as const, + validate: notEmpty, + valueLabel: 'DISK_SPACE', + initial: process.env.DISK_SPACE || '200g', + scope: 'ENVIRONMENT' as const, + }, +] + +export const databaseAndMonitoringQuestions = [ + { + name: 'kibanaUsername', + type: 'text' as const, + message: 'Input the username for logging in to Kibana', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'KIBANA_USERNAME', + initial: process.env.KIBANA_USERNAME || 'opencrvs-admin', + scope: 'ENVIRONMENT' as const + }, + { + name: 'kibanaPassword', + type: 'text' as const, + message: 'Input the password for logging in to Kibana', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'KIBANA_PASSWORD', + initial: process.env.KIBANA_PASSWORD || generateLongPassword(), + scope: 'ENVIRONMENT' as const + } +] + +export const notificationTransportQuestions = [ + { + name: 'notificationTransport', + type: 'select' as const, + message: 'Notification transport for 2FA, informant and user messaging', + choices: [ + { + title: 'Email (with SMTP details)', + value: 'email' + }, + { + title: 'SMS (Infobip)', + value: 'sms' + } + ], + valueLabel: 'NOTIFICATION_TRANSPORT', + valueType: 'VARIABLE' as const, + scope: 'ENVIRONMENT' as const, + initial: process.env.NOTIFICATION_TRANSPORT + } +] + +export const smsQuestions = [ + { + name: 'infobipApiKey', + type: 'text' as const, + message: 'What is your Infobip API key?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'INFOBIP_API_KEY', + initial: process.env.INFOBIP_API_KEY, + scope: 'ENVIRONMENT' as const + }, + { + name: 'infobipGatewayEndpoint', + type: 'text' as const, + message: 'What is your Infobip gateway endpoint?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'INFOBIP_GATEWAY_ENDPOINT', + initial: process.env.INFOBIP_GATEWAY_ENDPOINT, + scope: 'ENVIRONMENT' as const + }, + { + name: 'infobipSenderId', + type: 'text' as const, + message: 'What is your Infobip sender ID?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'INFOBIP_SENDER_ID', + initial: process.env.INFOBIP_SENDER_ID, + scope: 'ENVIRONMENT' as const + } +] + +export const emailQuestions = [ + { + name: 'smtpHost', + type: 'text' as const, + message: 'What is your SMTP host?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'SMTP_HOST', + initial: process.env.SMTP_HOST, + scope: 'ENVIRONMENT' as const + }, + { + name: 'smtpUsername', + type: 'text' as const, + message: 'What is your SMTP username?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'SMTP_USERNAME', + initial: process.env.SMTP_USERNAME, + scope: 'ENVIRONMENT' as const + }, + { + name: 'smtpPassword', + type: 'text' as const, + message: 'What is your SMTP password?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'SMTP_PASSWORD', + initial: process.env.SMTP_PASSWORD, + scope: 'ENVIRONMENT' as const + }, + { + name: 'smtpPort', + type: 'text' as const, + message: 'What is your SMTP port?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'SMTP_PORT', + initial: process.env.SMTP_PORT, + scope: 'ENVIRONMENT' as const + }, + { + name: 'smtpSecure', + type: 'select' as const, + message: 'Is the SMTP connection made securely using TLS?', + choices: [ + { + title: 'True', + value: 'true' + }, + { + title: 'False', + value: 'false' + } + ], + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'SMTP_SECURE', + initial: process.env.SMTP_SECURE, + scope: 'ENVIRONMENT' as const + }, + { + name: 'senderEmailAddress', + type: 'text' as const, + message: 'What is your sender email address?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'SENDER_EMAIL_ADDRESS', + initial: process.env.SENDER_EMAIL_ADDRESS, + scope: 'ENVIRONMENT' as const + }, + { + name: 'alertEmail', + type: 'text' as const, + message: + 'What is the email address to receive alert emails or a Slack channel email link?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'ALERT_EMAIL', + initial: process.env.ALERT_EMAIL, + scope: 'ENVIRONMENT' as const + } +] + +export const sentryQuestions = [ + { + name: 'sentryDsn', + type: 'text' as const, + message: 'What is your Sentry DSN?', + valueType: 'SECRET' as const, + validate: notEmpty, + valueLabel: 'SENTRY_DSN', + initial: process.env.SENTRY_DSN, + scope: 'ENVIRONMENT' as const + } +] + +export const metabaseAdminQuestions = [ + { + valueType: 'SECRET' as const, + name: 'OPENCRVS_METABASE_ADMIN_EMAIL', + type: 'text' as const, + message: + 'Email for Metabase super admin. Used as a username when logging in to the dashboard', + valueLabel: 'OPENCRVS_METABASE_ADMIN_EMAIL', + scope: 'ENVIRONMENT' as const, + initial: 'user@opencrvs.org' + }, + { + valueType: 'SECRET' as const, + name: 'OPENCRVS_METABASE_ADMIN_PASSWORD', + type: 'text' as const, + message: 'Password for Metabase super admin.', + valueLabel: 'OPENCRVS_METABASE_ADMIN_PASSWORD', + scope: 'ENVIRONMENT' as const, + initial: generateLongPassword() + } +] diff --git a/infrastructure/environments/setup-environment.ts b/infrastructure/environments/setup-environment.ts index 35eedf50..7b23a389 100644 --- a/infrastructure/environments/setup-environment.ts +++ b/infrastructure/environments/setup-environment.ts @@ -16,16 +16,36 @@ import { listRepositorySecrets, listRepositoryVariables, updateEnvironmentVariable, - updateRepositoryVariable + updateRepositoryVariable, + getRepositoryEnvironments } from './github' +import { derivedVariables } from './derived-variables' +import { generateLongPassword } from './utils' + import { readFileSync, writeFileSync } from 'fs' import { error, info, log, success, warn } from './logger' import { generateInventory, copyChartsValues } from './templates' import { updateWorkflowEnvironments } from './update-workflows'; +import { generateSSHKeyPair } from "./ssh-keygen"; +import { + environmentQuestions, + dockerhubQuestions, + githubQuestions, + githubTokenQuestion, + githubOtherQuestions, + infrastructureQuestions, + countryQuestions, + databaseAndMonitoringQuestions, + diskQuestions, + sentryQuestions, + notificationTransportQuestions, + smsQuestions, + emailQuestions, + metabaseAdminQuestions, + backupQuestions, +} from './questions'; -const notEmpty = (value: string | number) => - value.toString().trim().length > 0 ? true : 'Please enter a value' type Question = PromptObject & { name: T @@ -79,6 +99,64 @@ function questionToPrompt({ const ALL_QUESTIONS: Array> = [] const ALL_ANSWERS: Array> = [] +function getAnswers(existingValues: (Secret | Variable)[]): Answers { + return ALL_ANSWERS.flatMap((answerObject) => { + const questionsThatAreSecretsOrVariables = Object.entries( + answerObject + ).filter(([key, value]) => { + if (value === '') { + return false + } + const existingQuestion = ALL_QUESTIONS.find( + (question) => question.name === key + ) + const valueType = existingQuestion?.valueType + return valueType === 'VARIABLE' || valueType === 'SECRET' + }) + + return questionsThatAreSecretsOrVariables.map(([key, value]) => { + const existingQuestion = ALL_QUESTIONS.find( + (question) => question.name === key + ) + const valueType = existingQuestion!.valueType! + + if (valueType === 'SECRET') { + const existingSecret = findExistingValue( + existingQuestion!.valueLabel!, + 'SECRET', + existingQuestion?.scope!, + existingValues + ) + return { + type: valueType, + name: existingQuestion?.valueLabel!, + value: value.toString(), + didExist: existingSecret, + scope: existingQuestion!.scope! + } + } + const existingVariable = findExistingValue( + existingQuestion?.valueLabel!, + valueType, + existingQuestion?.scope!, + existingValues + ) + return { + type: valueType, + name: existingQuestion?.valueLabel!, + didExist: findExistingValue( + existingQuestion?.valueLabel!, + valueType, + existingQuestion?.scope!, + existingValues + ), + value: value.toString() || existingVariable?.value || '', + scope: existingQuestion!.scope! + } + }) + }) +} + function findExistingValue( name: string, type: T, @@ -199,14 +277,6 @@ async function promptAndStoreAnswer( return { ...Object.fromEntries(existingValuesForQuestions), ...result } } -function generateLongPassword() { - const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' - let result = '' - for (let i = 16; i > 0; --i) - result += chars[Math.floor(Math.random() * chars.length)] - return result -} - function storeSecrets(environment: string, answers: Answers) { let envConfig: Record = {} try { @@ -229,520 +299,8 @@ function storeSecrets(environment: string, answers: Answers) { writeFileSync(`.env.${environment}`, allLines.join('\n')) } -const githubQuestions = [ - { - name: 'githubOrganisation', - type: 'text' as const, - message: 'What is the name of your Github organisation?', - validate: notEmpty, - initial: process.env.GITHUB_ORGANISATION, - scope: 'REPOSITORY' as const - }, - { - name: 'githubRepository', - type: 'text' as const, - message: 'What is your Github infrastructure repository?', - validate: notEmpty, - initial: process.env.GITHUB_REPOSITORY, - scope: 'REPOSITORY' as const - }, -] -const githubOtherQuestions = [ - { - name: 'githubApprovers', - type: 'text' as const, - message: 'Please provide/update list of production approvers?', - initial: process.env.GH_APPROVERS, - valueType: 'VARIABLE' as const, - valueLabel: 'GH_APPROVERS', - scope: 'REPOSITORY' as const - }, - { - name: 'approvalRequired', - type: 'select' as const, - message: 'Would you like to enable approvals process for GitHub action workflows?', - choices: [ - { - title: 'True', - value: 'true' - }, - { - title: 'False', - value: 'false' - } - ], - valueType: 'VARIABLE' as const, - validate: notEmpty, - valueLabel: 'APPROVAL_REQUIRED', - initial: process.env.APPROVAL_REQUIRED, - scope: 'ENVIRONMENT' as const - }, -] -const githubTokenQuestion = [ - { - name: 'githubToken', - type: 'text' as const, - message: 'What is your Github token?', - validate: notEmpty, - initial: process.env.GITHUB_TOKEN, - valueType: 'SECRET' as const, - scope: 'REPOSITORY' as const, - valueLabel: 'GH_TOKEN' - } -] - -const dockerhubQuestions = [ - { - name: 'dockerhubOrganisation', - type: 'text' as const, - message: 'What is the name of your Docker Hub organisation?', - valueType: 'SECRET' as const, - valueLabel: 'DOCKERHUB_ACCOUNT', - validate: notEmpty, - initial: process.env.DOCKER_ORGANISATION, - scope: 'REPOSITORY' as const - }, - { - name: 'dockerhubRepository', - type: 'text' as const, - message: 'What is the name of your private Docker Hub repository?', - valueType: 'SECRET' as const, - valueLabel: 'DOCKERHUB_REPO', - validate: notEmpty, - initial: process.env.DOCKER_REPO, - scope: 'REPOSITORY' as const - }, - { - name: 'dockerhubUsername', - type: 'text' as const, - message: - 'What is the Docker Hub username the the target server should be using?', - valueType: 'SECRET' as const, - valueLabel: 'DOCKER_USERNAME', - validate: notEmpty, - initial: process.env.DOCKER_USERNAME, - scope: 'REPOSITORY' as const - }, - { - name: 'dockerhubToken', - type: 'text' as const, - message: 'What is the token of this Docker Hub account?', - valueType: 'SECRET' as const, - valueLabel: 'DOCKER_TOKEN', - validate: notEmpty, - initial: process.env.DOCKER_TOKEN, - scope: 'REPOSITORY' as const - } -] - -const countryQuestions = [ - { - name: 'country', - type: 'text' as const, - message: - 'What is the ISO 3166-1 alpha-3 country-code? (e.g. "NZL" for New Zealand) Reference: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3', - valueType: 'VARIABLE' as const, - valueLabel: 'COUNTRY', - initial: process.env.COUNTRY, - scope: 'REPOSITORY' as const - } -] - -const infrastructureQuestions = [ - { - name: 'domain', - type: 'text' as const, - message: 'What is the web domain applied after all subdomains in URLs?', - valueType: 'VARIABLE' as const, - validate: notEmpty, - valueLabel: 'DOMAIN', - initial: process.env.DOMAIN, - scope: 'ENVIRONMENT' as const - }, - { - name: 'kubeAPIHost', - type: 'text' as const, - message: - `Please enter host/IP to expose Kubernetes API endpoint, (default: Master first IP address):`, - valueType: 'VARIABLE' as const, - // validate: notEmpty, - valueLabel: 'KUBE_API_HOST', - initial: process.env.KUBE_API_HOST || '', - scope: 'ENVIRONMENT' as const - }, - { - name: 'workerNodes', - type: 'text' as const, - message: - `Please enter Kubernetes workers hosts/IP addresses (comma-separated), (default: no workers):`, - valueType: 'VARIABLE' as const, - // validate: notEmpty, - valueLabel: 'WORKER_NODES', - initial: process.env.WORKER_NODES || '', - scope: 'ENVIRONMENT' as const, - }, - { - name: 'backupHost', - type: 'text' as const, - message: - `Please enter backup server host/IP address, (default: no backup):`, - valueType: 'VARIABLE' as const, - // validate: , - valueLabel: 'BACKUP_HOST', - initial: process.env.BACKUP_HOST || '', - scope: 'ENVIRONMENT' as const, - }, -] - -const diskQuestions = [ - { - name: 'diskSpace', - type: 'text' as const, - message: `What is the amount of diskspace that should be dedicated to OpenCRVS data and will become the size of an encrypted cryptfs data directory. - \n${kleur.red('DO NOT USE ALL DISKSPACE FOR OPENCRVS!')} - \nLeave at least 50g available for OS use.`, - valueType: 'VARIABLE' as const, - validate: notEmpty, - valueLabel: 'DISK_SPACE', - initial: process.env.DISK_SPACE || '200g', - scope: 'ENVIRONMENT' as const, - }, -] - -const databaseAndMonitoringQuestions = [ - { - name: 'kibanaUsername', - type: 'text' as const, - message: 'Input the username for logging in to Kibana', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'KIBANA_USERNAME', - initial: process.env.KIBANA_USERNAME || 'opencrvs-admin', - scope: 'ENVIRONMENT' as const - }, - { - name: 'kibanaPassword', - type: 'text' as const, - message: 'Input the password for logging in to Kibana', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'KIBANA_PASSWORD', - initial: process.env.KIBANA_PASSWORD || generateLongPassword(), - scope: 'ENVIRONMENT' as const - } -] - -const notificationTransportQuestions = [ - { - name: 'notificationTransport', - type: 'select' as const, - message: 'Notification transport for 2FA, informant and user messaging', - choices: [ - { - title: 'Email (with SMTP details)', - value: 'email' - }, - { - title: 'SMS (Infobip)', - value: 'sms' - } - ], - valueLabel: 'NOTIFICATION_TRANSPORT', - valueType: 'VARIABLE' as const, - scope: 'ENVIRONMENT' as const, - initial: process.env.NOTIFICATION_TRANSPORT - } -] - -const smsQuestions = [ - { - name: 'infobipApiKey', - type: 'text' as const, - message: 'What is your Infobip API key?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'INFOBIP_API_KEY', - initial: process.env.INFOBIP_API_KEY, - scope: 'ENVIRONMENT' as const - }, - { - name: 'infobipGatewayEndpoint', - type: 'text' as const, - message: 'What is your Infobip gateway endpoint?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'INFOBIP_GATEWAY_ENDPOINT', - initial: process.env.INFOBIP_GATEWAY_ENDPOINT, - scope: 'ENVIRONMENT' as const - }, - { - name: 'infobipSenderId', - type: 'text' as const, - message: 'What is your Infobip sender ID?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'INFOBIP_SENDER_ID', - initial: process.env.INFOBIP_SENDER_ID, - scope: 'ENVIRONMENT' as const - } -] - -const emailQuestions = [ - { - name: 'smtpHost', - type: 'text' as const, - message: 'What is your SMTP host?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'SMTP_HOST', - initial: process.env.SMTP_HOST, - scope: 'ENVIRONMENT' as const - }, - { - name: 'smtpUsername', - type: 'text' as const, - message: 'What is your SMTP username?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'SMTP_USERNAME', - initial: process.env.SMTP_USERNAME, - scope: 'ENVIRONMENT' as const - }, - { - name: 'smtpPassword', - type: 'text' as const, - message: 'What is your SMTP password?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'SMTP_PASSWORD', - initial: process.env.SMTP_PASSWORD, - scope: 'ENVIRONMENT' as const - }, - { - name: 'smtpPort', - type: 'text' as const, - message: 'What is your SMTP port?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'SMTP_PORT', - initial: process.env.SMTP_PORT, - scope: 'ENVIRONMENT' as const - }, - { - name: 'smtpSecure', - type: 'select' as const, - message: 'Is the SMTP connection made securely using TLS?', - choices: [ - { - title: 'True', - value: 'true' - }, - { - title: 'False', - value: 'false' - } - ], - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'SMTP_SECURE', - initial: process.env.SMTP_SECURE, - scope: 'ENVIRONMENT' as const - }, - { - name: 'senderEmailAddress', - type: 'text' as const, - message: 'What is your sender email address?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'SENDER_EMAIL_ADDRESS', - initial: process.env.SENDER_EMAIL_ADDRESS, - scope: 'ENVIRONMENT' as const - }, - { - name: 'alertEmail', - type: 'text' as const, - message: - 'What is the email address to receive alert emails or a Slack channel email link?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'ALERT_EMAIL', - initial: process.env.ALERT_EMAIL, - scope: 'ENVIRONMENT' as const - } -] - -const sentryQuestions = [ - { - name: 'sentryDsn', - type: 'text' as const, - message: 'What is your Sentry DSN?', - valueType: 'SECRET' as const, - validate: notEmpty, - valueLabel: 'SENTRY_DSN', - initial: process.env.SENTRY_DSN, - scope: 'ENVIRONMENT' as const - } -] - -const derivedVariables = [ - { - name: 'ACTIVATE_USERS', - valueLabel: 'ACTIVATE_USERS', - valueType: 'VARIABLE', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'AUTH_HOST', - valueLabel: 'AUTH_HOST', - valueType: 'VARIABLE', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'COUNTRY_CONFIG_HOST', - valueLabel: 'COUNTRY_CONFIG_HOST', - valueType: 'VARIABLE', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'GATEWAY_HOST', - valueLabel: 'GATEWAY_HOST', - valueType: 'VARIABLE', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'CONTENT_SECURITY_POLICY_WILDCARD', - valueLabel: 'CONTENT_SECURITY_POLICY_WILDCARD', - valueType: 'VARIABLE', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'CLIENT_APP_URL', - valueLabel: 'CLIENT_APP_URL', - valueType: 'VARIABLE', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'LOGIN_URL', - valueLabel: 'LOGIN_URL', - valueType: 'VARIABLE', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'ELASTICSEARCH_SUPERUSER_PASSWORD', - valueLabel: 'ELASTICSEARCH_SUPERUSER_PASSWORD', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'KIBANA_SYSTEM_PASSWORD', - valueLabel: 'KIBANA_SYSTEM_PASSWORD', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'MINIO_ROOT_USER', - valueLabel: 'MINIO_ROOT_USER', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'MINIO_ROOT_PASSWORD', - valueLabel: 'MINIO_ROOT_PASSWORD', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'MONGODB_ADMIN_USER', - valueLabel: 'MONGODB_ADMIN_USER', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'MONGODB_ADMIN_PASSWORD', - valueLabel: 'MONGODB_ADMIN_PASSWORD', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'POSTGRES_USER', - valueLabel: 'POSTGRES_USER', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'POSTGRES_PASSWORD', - valueLabel: 'POSTGRES_PASSWORD', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'SUPER_USER_PASSWORD', - valueLabel: 'SUPER_USER_PASSWORD', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'ENCRYPTION_KEY', - valueLabel: 'ENCRYPTION_KEY', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - }, - { - name: 'GH_ENCRYPTION_PASSWORD', - valueLabel: 'GH_ENCRYPTION_PASSWORD', - valueType: 'SECRET', - type: 'disabled', - scope: 'REPOSITORY' - }, - { - name: 'BACKUP_ENCRYPTION_PASSPHRASE', - valueLabel: 'BACKUP_ENCRYPTION_PASSPHRASE', - valueType: 'SECRET', - type: 'disabled', - scope: 'ENVIRONMENT' - } -] as const - -const metabaseAdminQuestions = [ - { - valueType: 'SECRET' as const, - name: 'OPENCRVS_METABASE_ADMIN_EMAIL', - type: 'text' as const, - message: - 'Email for Metabase super admin. Used as a username when logging in to the dashboard', - valueLabel: 'OPENCRVS_METABASE_ADMIN_EMAIL', - scope: 'ENVIRONMENT' as const, - initial: 'user@opencrvs.org' - }, - { - valueType: 'SECRET' as const, - name: 'OPENCRVS_METABASE_ADMIN_PASSWORD', - type: 'text' as const, - message: 'Password for Metabase super admin.', - valueLabel: 'OPENCRVS_METABASE_ADMIN_PASSWORD', - scope: 'ENVIRONMENT' as const, - initial: generateLongPassword() - } -] - ALL_QUESTIONS.push( + ...environmentQuestions, ...githubTokenQuestion, ...githubOtherQuestions, ...dockerhubQuestions, @@ -760,38 +318,12 @@ ALL_QUESTIONS.push( ; (async () => { - const { type: environment_type } = await prompts( - [ - { - name: 'type', - type: 'select' as const, - scope: 'ENVIRONMENT' as const, - message: 'Purpose for the environment?', - choices: [ - { title: 'Development/Quality assurance/Testing (no PII data)', value: 'non-production' }, - { title: 'Staging/Production (hosts PII data, requires frequent backups)', value: 'production' }, - ] - } - ].map(questionToPrompt) - ) - const { environment } = await prompts( - [ - { - name: 'environment', - type: 'text' as const, - message: 'What is the name of your environment?', - validate: notEmpty, - initial: process.env.ENV, - scope: 'REPOSITORY' as const - } - ].map(questionToPrompt), - { - onCancel: () => { - process.exit(1) - } + const { environment_type, environment } = await prompts(environmentQuestions.map(questionToPrompt), { + onCancel: () => { + process.exit(1) } - ) + }) // Read users .env file based on the environment name they gave above, e.g. .env.production dotenv.config({ @@ -810,7 +342,7 @@ ALL_QUESTIONS.push( ) const { githubToken } = await promptAndStoreAnswer( - environment, + '', githubTokenQuestion, [] ) @@ -819,6 +351,8 @@ ALL_QUESTIONS.push( auth: githubToken }) + let existingEnvironments = await getRepositoryEnvironments(octokit, githubOrganisation, githubRepository); + await createEnvironment( octokit, environment, @@ -869,8 +403,8 @@ ALL_QUESTIONS.push( log( '\nEnvironment with the name', environment, - 'already exists in Github.\n', - 'Found', + 'already exists in Github.', + '\nFound', existingEnvironmentVariables.length, 'existing variables and', existingEnvironmentSecrets.length, @@ -900,32 +434,99 @@ ALL_QUESTIONS.push( const workerNodes = infrastructure.workerNodes ? infrastructure.workerNodes.split(',').map((ip: string) => ip.trim()) : [] - const backupHost = infrastructure.backupHost || '' - log('\n', kleur.bold().underline('Running configuration files updates')) - generateInventory( - environment, - { - worker_nodes: workerNodes, - backup_host: backupHost, - kube_api_host: infrastructure.kubeAPIHost || '' - } + + log('\n', kleur.bold().underline('Backup configuration')) + const backupHost = findExistingValue( + 'BACKUP_HOST', + 'VARIABLE', + 'ENVIRONMENT', + existingValues ) - copyChartsValues( + let configureBackup = backupHost ? true : false + if (!backupHost) { + configureBackup = (await prompts( + [ + { + name: 'configureBackup', + type: 'confirm' as const, + message: 'Do you want to configure backup?', + scope: 'ENVIRONMENT' as const, + initial: Boolean(process.env.CONFIGURE_BACKUP) + } + ].map(questionToPrompt) + )).configureBackup + } + let backupHostPrivateKeyExists = findExistingValue( + 'BACKUP_HOST_PRIVATE_KEY', + 'SECRET', + 'ENVIRONMENT', + existingValues + ) + let backupHostPrivateKey = '' + let backupHostPublicKey = '' + + if (configureBackup) { + const { backupHost } = await promptAndStoreAnswer( environment, - { - env: environment, - environment_type: environment_type, - // FIXME: In general that should be environment_type, - // Hardcode like this blocks us from being generic: - // https://github.com/opencrvs/opencrvs-core/issues/11171 - is_qa_env: environment !== 'production' ? "true" : "false" - } + backupQuestions, + existingValues ) - await updateWorkflowEnvironments(); + + if (backupHost && !backupHostPrivateKeyExists) { + const { publicKey, privateKey } = generateSSHKeyPair(); + backupHostPublicKey = publicKey; + backupHostPrivateKey = privateKey; + log(kleur.bold().green('✔'), kleur.bold().yellow(`Generated SSH key pair for backup host: ${backupHost}`)) + } + } + + log('\n', kleur.bold().underline('Restore configuration')) + let restoreEnvironmentName = findExistingValue( + 'RESTORE_ENVIRONMENT_NAME', + 'VARIABLE', + 'ENVIRONMENT', + existingValues + )?.value + + if (!restoreEnvironmentName) { + let configureRestore = (await prompts( + [ + { + name: 'configureRestore', + type: 'confirm' as const, + message: 'Do you want to configure restore?', + scope: 'ENVIRONMENT' as const, + initial: Boolean(process.env.CONFIGURE_RESTORE) + } + ].map(questionToPrompt) + )).configureRestore + if (configureRestore) { + const env_list_filtered = existingEnvironments.filter(env => env !== environment); + restoreEnvironmentName = (await prompts( + [ + { + name: 'restoreEnvironmentName', + type: 'autocomplete' as const, + message: 'What is the name of your environment to restore?', + scope: 'ENVIRONMENT' as const, + choices: env_list_filtered.map(env => ({ + title: env, + value: env + })), + initial: '', + validate: (input: string) => + env_list_filtered.includes(input) ? true : 'Please select a valid environment.' + } + ].map(questionToPrompt) + )).restoreEnvironmentName + } + } else { + log('\n', kleur.bold().green('✔'), kleur.bold().yellow('Restore environment is already set to'), kleur.bold().blue(restoreEnvironmentName)) + } log('\n', kleur.bold().underline('Databases & monitoring')) - var enableEncryption = true + let enableEncryption = true const encryption_key_defined = findExistingValue( 'ENCRYPTION_KEY', 'SECRET', @@ -1333,9 +934,29 @@ ALL_QUESTIONS.push( existingValues ), scope: 'ENVIRONMENT' as const - } + }, ] + if (restoreEnvironmentName) { + applicationServerUpdates.push({ + type: 'VARIABLE' as const, + name: 'RESTORE_ENVIRONMENT_NAME', + value: answerOrExisting(restoreEnvironmentName, findExistingValue( + 'RESTORE_ENVIRONMENT_NAME', + 'VARIABLE', + 'ENVIRONMENT', + existingValues + ), (val) => val || ''), + didExist: findExistingValue( + 'RESTORE_ENVIRONMENT_NAME', + 'VARIABLE', + 'ENVIRONMENT', + existingValues + ), + scope: 'ENVIRONMENT' as const + + }) + } if (enableEncryption) { applicationServerUpdates.push({ name: 'ENCRYPTION_KEY', @@ -1356,6 +977,23 @@ ALL_QUESTIONS.push( }) } + if (configureBackup) { + applicationServerUpdates.push({ + name: 'BACKUP_HOST_PRIVATE_KEY', + type: 'SECRET' as const, + didExist: undefined, + value: backupHostPrivateKey, + scope: 'ENVIRONMENT' as const + }) + applicationServerUpdates.push({ + name: 'BACKUP_HOST_PUBLIC_KEY', + type: 'SECRET' as const, + didExist: undefined, + value: backupHostPublicKey, + scope: 'ENVIRONMENT' as const + }) + } + derivedUpdates.push(...applicationServerUpdates) @@ -1623,6 +1261,28 @@ ALL_QUESTIONS.push( ) ) + log('\n', kleur.bold().underline('Running configuration files updates')) + generateInventory( + environment, + { + worker_nodes: workerNodes, + backup_host: backupHost, + kube_api_host: infrastructure.kubeAPIHost || '' + } + ) + copyChartsValues( + environment, + { + env: environment, + environment_type: environment_type, + // FIXME: In general that should be environment_type, + // Hardcode like this blocks us from being generic: + // https://github.com/opencrvs/opencrvs-core/issues/11171 + is_qa_env: environment !== 'production' ? "true" : "false" + } + ) + await updateWorkflowEnvironments(); + const worker_message = workerNodes.length > 0 ? ` ----------------------- @@ -1633,7 +1293,7 @@ ALL_QUESTIONS.push( curl -sfL https://raw.githubusercontent.com/opencrvs/infrastructure/refs/heads/develop/scripts/bootstrap/opencrvs-bootstrap.sh -o opencrvs-bootstrap.sh && \\ bash opencrvs-bootstrap.sh --ssh-public-key ${kleur.bold('[PUT PROVISION USER PUBLIC KEY FROM MASTER NODE]')}` : '' - const backup_message = backupHost && backupHost !== "" ? + const backup_message = backupHost && backupHost.name !== "" ? ` ----------------------- ➡️ ${kleur.bold().yellow('COPY the SSH public key from the master VM to your clipboard')} @@ -1665,60 +1325,3 @@ ${kleur.yellow('━━━━━━━━━━━━━━━━━━━━━ log(kleur.bold().yellow('DO NOT COMMIT THIS FILE TO GIT!')) })() -function getAnswers(existingValues: (Secret | Variable)[]): Answers { - return ALL_ANSWERS.flatMap((answerObject) => { - const questionsThatAreSecretsOrVariables = Object.entries( - answerObject - ).filter(([key, value]) => { - if (value === '') { - return false - } - const existingQuestion = ALL_QUESTIONS.find( - (question) => question.name === key - ) - const valueType = existingQuestion?.valueType - return valueType === 'VARIABLE' || valueType === 'SECRET' - }) - - return questionsThatAreSecretsOrVariables.map(([key, value]) => { - const existingQuestion = ALL_QUESTIONS.find( - (question) => question.name === key - ) - const valueType = existingQuestion!.valueType! - - if (valueType === 'SECRET') { - const existingSecret = findExistingValue( - existingQuestion!.valueLabel!, - 'SECRET', - existingQuestion?.scope!, - existingValues - ) - return { - type: valueType, - name: existingQuestion?.valueLabel!, - value: value.toString(), - didExist: existingSecret, - scope: existingQuestion!.scope! - } - } - const existingVariable = findExistingValue( - existingQuestion?.valueLabel!, - valueType, - existingQuestion?.scope!, - existingValues - ) - return { - type: valueType, - name: existingQuestion?.valueLabel!, - didExist: findExistingValue( - existingQuestion?.valueLabel!, - valueType, - existingQuestion?.scope!, - existingValues - ), - value: value.toString() || existingVariable?.value || '', - scope: existingQuestion!.scope! - } - }) - }) -} diff --git a/infrastructure/environments/ssh-keygen.ts b/infrastructure/environments/ssh-keygen.ts new file mode 100644 index 00000000..3f131604 --- /dev/null +++ b/infrastructure/environments/ssh-keygen.ts @@ -0,0 +1,6 @@ +import { utils } from "ssh2"; + +export function generateSSHKeyPair(): { publicKey: string; privateKey: string } { + let keys = utils.generateKeyPairSync('ed25519'); + return { publicKey: keys.public.toString(), privateKey: keys.private.toString() }; +} diff --git a/infrastructure/environments/utils.ts b/infrastructure/environments/utils.ts new file mode 100644 index 00000000..9a1eedb0 --- /dev/null +++ b/infrastructure/environments/utils.ts @@ -0,0 +1,8 @@ + +export function generateLongPassword() { + const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + let result = '' + for (let i = 16; i > 0; --i) + result += chars[Math.floor(Math.random() * chars.length)] + return result +} \ No newline at end of file diff --git a/infrastructure/server-setup/group_vars/all.yml b/infrastructure/server-setup/group_vars/all.yml index 6ceaf752..173ca7ac 100644 --- a/infrastructure/server-setup/group_vars/all.yml +++ b/infrastructure/server-setup/group_vars/all.yml @@ -11,8 +11,6 @@ ansible_python_interpreter: /usr/bin/python3 crontab_user: root provisioning_user: provision -# Kubernetes secret in opencrvs-deps- namespace -backup_server_ssh_credentials_secret: "backup-server-ssh-credentials" # Path on backup server where to private key is stored backup_ssh_key_path: /home/backup/.ssh/id_ed25519 # User for ssh connection to backup server diff --git a/infrastructure/server-setup/k8s.yml b/infrastructure/server-setup/k8s.yml index 9883c04f..179512f8 100644 --- a/infrastructure/server-setup/k8s.yml +++ b/infrastructure/server-setup/k8s.yml @@ -95,8 +95,6 @@ include_tasks: tasks/k8s/metrics-server.yml - name: Install k8s self-hosted runner include_tasks: tasks/k8s/self-hosted-runner.yml - - name: Create backup server secret - include_tasks: tasks/k8s/backup-secret.yml - name: Additional configuration become: yes diff --git a/infrastructure/server-setup/tasks/backups/create-backup-server-credentials.yml b/infrastructure/server-setup/tasks/backups/create-backup-server-credentials.yml index 064c38ae..5239ba3c 100644 --- a/infrastructure/server-setup/tasks/backups/create-backup-server-credentials.yml +++ b/infrastructure/server-setup/tasks/backups/create-backup-server-credentials.yml @@ -6,29 +6,12 @@ owner: backup group: backup -- name: Generate an ed25519 SSH keypair for backup user if not present - openssh_keypair: - path: "{{ backup_ssh_key_path }}" - type: ed25519 - owner: backup - group: backup - mode: '0600' - force: false - register: backup_keypair_result - - name: Add public key to authorized_keys ansible.builtin.lineinfile: path: /home/backup/.ssh/authorized_keys - line: "{{ backup_keypair_result.public_key }}" + line: "{{ backup_host_public_key }}" create: yes owner: backup group: backup mode: 0600 when: backup_ssh_key_path is defined - -- name: Fetch private key to control/master node - fetch: - src: /home/backup/.ssh/id_ed25519 - dest: "/tmp/id_ed25519_backup" - flat: yes - mode: '0600' diff --git a/infrastructure/server-setup/tasks/k8s/backup-secret.yml b/infrastructure/server-setup/tasks/k8s/backup-secret.yml deleted file mode 100644 index 0806ba24..00000000 --- a/infrastructure/server-setup/tasks/k8s/backup-secret.yml +++ /dev/null @@ -1,35 +0,0 @@ -- name: Check if /tmp/id_ed25519_backup exists - stat: - path: /tmp/id_ed25519_backup - register: backup_key_file -- name: Read the backup SSH key file - ansible.builtin.slurp: - src: /tmp/id_ed25519_backup - register: ssh_key_file - when: backup_key_file.stat.exists -- name: Ensure namespace opencrvs-deps-{{ k8s_cluster_env }} exists - kubernetes.core.k8s: - api_version: v1 - kind: Namespace - name: opencrvs-deps-{{ k8s_cluster_env }} - state: present - when: backup_key_file.stat.exists -- name: Ensure the Kubernetes secret for backup exists - kubernetes.core.k8s: - kubeconfig: ~/.kube/config - state: present - namespace: "opencrvs-deps-{{ k8s_cluster_env }}" - definition: - apiVersion: v1 - kind: Secret - metadata: - name: "{{ backup_server_ssh_credentials_secret }}" - type: Opaque - data: - ssh_key: "{{ ssh_key_file.content | default('') }}" - user: "{{ backup_server_user | b64encode }}" - host: "{{ hostvars[groups['backup'][0]]['ansible_host'] | b64encode }}" - when: - - "'backup' in groups" - - "groups['backup'] | length > 0" - - backup_key_file.stat.exists \ No newline at end of file diff --git a/package.json b/package.json index 413eb7ba..e33c87d3 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@types/libsodium-wrappers": "^0.7.10", "@types/prompts": "^2.4.9", "@types/js-yaml": "4.0.9", + "@types/ssh2": "^1.15.5", "husky": "9.1.7", "kleur": "^4.1.5", "libsodium-wrappers": "^0.7.13", @@ -32,6 +33,7 @@ "dependencies": { "@types/node": "^24.0.0", "dotenv": "^16.4.5", - "prompts": "^2.4.2" + "prompts": "^2.4.2", + "ssh2": "^1.17.0" } } diff --git a/yarn.lock b/yarn.lock index a9c4f069..7e22ede2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -121,9 +121,9 @@ "@octokit/openapi-types" "^18.0.0" "@tsconfig/node10@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" - integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== + version "1.0.12" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.12.tgz#be57ceac1e4692b41be9de6be8c32a106636dba4" + integrity sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ== "@tsconfig/node12@^1.0.7": version "1.0.11" @@ -151,16 +151,23 @@ integrity sha512-5Kv68fXuXK0iDuUir1WPGw2R9fOZUlYlSAa0ztMcL0s0BfIDTqg9GXz8K30VJpPP3sxWhbolnQma2x+/TfkzDQ== "@types/node@*": - version "24.5.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.5.1.tgz#dab6917c47113eb4502d27d06e89a407ec0eff95" - integrity sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q== + version "25.0.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-25.0.3.tgz#79b9ac8318f373fbfaaf6e2784893efa9701f269" + integrity sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA== + dependencies: + undici-types "~7.16.0" + +"@types/node@^18.11.18": + version "18.19.130" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.130.tgz#da4c6324793a79defb7a62cba3947ec5add00d59" + integrity sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg== dependencies: - undici-types "~7.12.0" + undici-types "~5.26.4" "@types/node@^24.0.0": - version "24.9.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.9.1.tgz#b7360b3c789089e57e192695a855aa4f6981a53c" - integrity sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg== + version "24.10.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.4.tgz#9d27c032a1b2c42a4eab8fb65c5856a8b8e098c4" + integrity sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg== dependencies: undici-types "~7.16.0" @@ -172,6 +179,13 @@ "@types/node" "*" kleur "^3.0.3" +"@types/ssh2@^1.15.5": + version "1.15.5" + resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-1.15.5.tgz#6d8f45db2f39519b8d9377268fa71ed77d969686" + integrity sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ== + dependencies: + "@types/node" "^18.11.18" + acorn-walk@^8.1.1: version "8.3.4" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" @@ -216,11 +230,30 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +asn1@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +bcrypt-pbkdf@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + before-after-hook@^2.2.0: version "2.2.3" resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== +buildcheck@~0.0.6: + version "0.0.7" + resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.7.tgz#07a5e76c10ead8fa67d9e4c587b68f49e8f29d61" + integrity sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA== + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -233,6 +266,14 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +cpu-features@~0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.10.tgz#9aae536db2710c7254d7ed67cb3cbc7d29ad79c5" + integrity sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA== + dependencies: + buildcheck "~0.0.6" + nan "^2.19.0" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -354,9 +395,9 @@ libsodium@^0.7.15: integrity sha512-sZwRknt/tUpE2AwzHq3jEyUU5uvIZHtSssktXq7owd++3CSgn8RGrv6UZJJBpP7+iBghBqe7Z06/2M31rI2NKw== lru-cache@^11.0.0: - version "11.2.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.2.2.tgz#40fd37edffcfae4b2940379c0722dc6eeaa75f24" - integrity sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg== + version "11.2.4" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.2.4.tgz#ecb523ebb0e6f4d837c807ad1abaea8e0619770d" + integrity sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg== make-error@^1.1.1: version "1.3.6" @@ -364,9 +405,9 @@ make-error@^1.1.1: integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== minimatch@^10.0.3: - version "10.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" - integrity sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw== + version "10.1.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.1.1.tgz#e6e61b9b0c1dcab116b5a7d1458e8b6ae9e73a55" + integrity sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ== dependencies: "@isaacs/brace-expansion" "^5.0.0" @@ -375,6 +416,11 @@ minipass@^7.1.2: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== +nan@^2.19.0, nan@^2.23.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.24.0.tgz#a8919b36e692aa5b260831910e4f81419fc0a283" + integrity sha512-Vpf9qnVW1RaDkoNKFUvfxqAbtI8ncb8OJlqZ9wwpXzWPEsvsB1nvdUi6oYrHIkQ1Y/tMDnr1h4nczS0VB9Xykg== + node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -400,9 +446,9 @@ path-key@^3.1.0: integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-scurry@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" - integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.1.tgz#4b6572376cfd8b811fca9cd1f5c24b3cbac0fe10" + integrity sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA== dependencies: lru-cache "^11.0.0" minipass "^7.1.2" @@ -415,6 +461,11 @@ prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" +safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -437,6 +488,17 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +ssh2@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.17.0.tgz#dc686e8e3abdbd4ad95d46fa139615903c12258c" + integrity sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ== + dependencies: + asn1 "^0.2.6" + bcrypt-pbkdf "^1.0.2" + optionalDependencies: + cpu-features "~0.0.10" + nan "^2.23.0" + "string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -509,15 +571,20 @@ ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +tweetnacl@^0.14.3: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + typescript@^5.1.6: - version "5.9.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" - integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== - -undici-types@~7.12.0: - version "7.12.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.12.0.tgz#15c5c7475c2a3ba30659529f5cdb4674b622fafb" - integrity sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ== + version "5.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" + integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== undici-types@~7.16.0: version "7.16.0" From af64974a9199ec1346fccb7ac9de25c3820eb66d Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Mon, 5 Jan 2026 12:46:23 +0200 Subject: [PATCH 53/98] fix: Add backward compatibility logic to helm chart --- .../templates/postgres-on-update-analytics-job.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/opencrvs-services/templates/postgres-on-update-analytics-job.yaml b/charts/opencrvs-services/templates/postgres-on-update-analytics-job.yaml index 01c86f53..bdd21a3d 100644 --- a/charts/opencrvs-services/templates/postgres-on-update-analytics-job.yaml +++ b/charts/opencrvs-services/templates/postgres-on-update-analytics-job.yaml @@ -29,7 +29,7 @@ spec: - -c - > [[ -d /assets/postgres/ ]] && cp -R /assets/postgres/* /data-assets/ || - cp -LR /scripts/* /data-assets/; + cp -R /scripts/* /data-assets/; chmod +x /data-assets/*.sh || true volumeMounts: - name: assets From 3f10bcc963675ddddbfb2ae10ae25ffa6514f0f6 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Mon, 5 Jan 2026 16:28:42 +0200 Subject: [PATCH 54/98] testing --- .../templates/postgres-on-update-analytics-job.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/opencrvs-services/templates/postgres-on-update-analytics-job.yaml b/charts/opencrvs-services/templates/postgres-on-update-analytics-job.yaml index bdd21a3d..551b4b22 100644 --- a/charts/opencrvs-services/templates/postgres-on-update-analytics-job.yaml +++ b/charts/opencrvs-services/templates/postgres-on-update-analytics-job.yaml @@ -28,9 +28,8 @@ spec: - sh - -c - > - [[ -d /assets/postgres/ ]] && cp -R /assets/postgres/* /data-assets/ || - cp -R /scripts/* /data-assets/; - chmod +x /data-assets/*.sh || true + [[ -d /assets/postgres/ ]] && cp -Rv /assets/postgres/* /data-assets/ || + cp -Rv /scripts/* /data-assets/; volumeMounts: - name: assets mountPath: /data-assets @@ -39,7 +38,8 @@ spec: name: postgres-on-update-script containers: - name: postgres-on-update-analytics - command: ["bash", "-c", "/data-assets/setup-analytics.sh"] + # command: ["bash", "-c", "/data-assets/setup-analytics.sh"] + command: ["sleep", "3600"] image: postgres:17 env: - name: POSTGRES_HOST From be37f57bde91d4a9b81cb7b6c287d93f80a8358a Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:06:40 +0200 Subject: [PATCH 55/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 118 +++++++++---------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index f17b79c5..4d388639 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -38,52 +38,52 @@ on: default: "false" jobs: - get-backup-user: - name: Get backup user - uses: ./.github/workflows/get-secret-from-environment.yml - with: - secret_name: 'BACKUP_SERVER_USER' - env_name: ${{ inputs.restore_environment }} - secrets: - gh_token: ${{ secrets.GH_TOKEN }} - encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} - - get-backup-host: - name: Get backup host - uses: ./.github/workflows/get-secret-from-environment.yml - with: - secret_name: 'BACKUP_HOST' - env_name: ${{ inputs.restore_environment }} - secrets: - gh_token: ${{ secrets.GH_TOKEN }} - encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} - - get-backup-ssh-key: - name: Get backup SSH key - uses: ./.github/workflows/get-secret-from-environment.yml - with: - secret_name: 'BACKUP_HOST_PRIVATE_KEY' - env_name: ${{ inputs.restore_environment }} - secrets: - gh_token: ${{ secrets.GH_TOKEN }} - encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} - - get-backup-encryption-key: - name: Get backup encryption key - uses: ./.github/workflows/get-secret-from-environment.yml - with: - secret_name: 'BACKUP_ENCRYPTION_PASSPHRASE' - env_name: ${{ inputs.restore_environment }} - secrets: - gh_token: ${{ secrets.GH_TOKEN }} - encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + # get-backup-user: + # name: Get backup user + # uses: ./.github/workflows/get-secret-from-environment.yml + # with: + # secret_name: 'BACKUP_SERVER_USER' + # env_name: ${{ inputs.restore_environment }} + # secrets: + # gh_token: ${{ secrets.GH_TOKEN }} + # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + + # get-backup-host: + # name: Get backup host + # uses: ./.github/workflows/get-secret-from-environment.yml + # with: + # secret_name: 'BACKUP_HOST' + # env_name: ${{ inputs.restore_environment }} + # secrets: + # gh_token: ${{ secrets.GH_TOKEN }} + # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + + # get-backup-ssh-key: + # name: Get backup SSH key + # uses: ./.github/workflows/get-secret-from-environment.yml + # with: + # secret_name: 'BACKUP_HOST_PRIVATE_KEY' + # env_name: ${{ inputs.restore_environment }} + # secrets: + # gh_token: ${{ secrets.GH_TOKEN }} + # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + + # get-backup-encryption-key: + # name: Get backup encryption key + # uses: ./.github/workflows/get-secret-from-environment.yml + # with: + # secret_name: 'BACKUP_ENCRYPTION_PASSPHRASE' + # env_name: ${{ inputs.restore_environment }} + # secrets: + # gh_token: ${{ secrets.GH_TOKEN }} + # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} sync-env: - needs: - - get-backup-user - - get-backup-host - - get-backup-encryption-key - - get-backup-ssh-key + # needs: + # - get-backup-user + # - get-backup-host + # - get-backup-encryption-key + # - get-backup-ssh-key name: Sync GitHub env to Kubernetes environment: ${{ inputs.environment }} runs-on: @@ -109,21 +109,21 @@ jobs: echo env_file=$ENV_FILE >> $GITHUB_ENV cat $ENV_FILE - - name: Save secrets - if: needs.get-backup-user.outputs.environment_exists == 'true' - run: | - echo "${{ needs.get-backup-user.outputs.secret_value }}" | base64 --decode | \ - openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_user - echo "${{ needs.get-backup-host.outputs.secret_value }}" | base64 --decode | \ - openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_host - echo "${{ needs.get-backup-encryption-key.outputs.secret_value }}" | base64 --decode | \ - openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_encryption_key - echo "${{ needs.get-backup-ssh-key.outputs.secret_value }}" | base64 --decode | \ - openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_ssh_key - echo BACKUP_USER=$(cat /tmp/backup_user | base64) >> $env_file - echo BACKUP_HOST=$(cat /tmp/backup_host | base64) >> $env_file - echo BACKUP_ENCRYPTION_PASSPHRASE=$(cat /tmp/backup_encryption_key | base64) >> $env_file - echo BACKUP_HOST_PRIVATE_KEY=$(cat /tmp/backup_ssh_key | base64) >> $env_file + # - name: Save secrets + # if: needs.get-backup-user.outputs.environment_exists == 'true' + # run: | + # echo "${{ needs.get-backup-user.outputs.secret_value }}" | base64 --decode | \ + # openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_user + # echo "${{ needs.get-backup-host.outputs.secret_value }}" | base64 --decode | \ + # openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_host + # echo "${{ needs.get-backup-encryption-key.outputs.secret_value }}" | base64 --decode | \ + # openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_encryption_key + # echo "${{ needs.get-backup-ssh-key.outputs.secret_value }}" | base64 --decode | \ + # openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_ssh_key + # echo BACKUP_USER=$(cat /tmp/backup_user | base64) >> $env_file + # echo BACKUP_HOST=$(cat /tmp/backup_host | base64) >> $env_file + # echo BACKUP_ENCRYPTION_PASSPHRASE=$(cat /tmp/backup_encryption_key | base64) >> $env_file + # echo BACKUP_HOST_PRIVATE_KEY=$(cat /tmp/backup_ssh_key | base64) >> $env_file - name: Preprocess mapping into Secret YAMLs run: | From 6d03032e9c41a429570e228d03522ab8c513bb2f Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:09:42 +0200 Subject: [PATCH 56/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 4d388639..3525ea96 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -7,16 +7,15 @@ on: environment: description: "Target environment" required: true - default: "development" + default: "staging" type: choice options: - - demo1 - production - staging restore_environment: description: "Restore environment name" required: false - default: "false" + default: "production" type: string namespace_template: description: "Secrets mapping template" @@ -38,6 +37,20 @@ on: default: "false" jobs: + get-restore-env-name: + name: Determine restore environment name + outputs: + restore_env_name: ${{ steps.set-restore-env.outputs.restore-env-name }} + runs-on: ubuntu-24.04 + environment: ${{ inputs.environment }} + steps: + - name: Set restore environment name + id: set-restore-env + run: | + if [ "${{ vars.RESTORE_ENVIRONMENT_NAME }}" = "false" ] || [ -z "${{ inputs.restore_environment }}" ]; then + echo "restore-env-name=${{ inputs.environment }}" >> $GITHUB_OUTPUT + fi + echo "restore-env-name=${{ inputs.environment }}" # get-backup-user: # name: Get backup user # uses: ./.github/workflows/get-secret-from-environment.yml From 29f60545f7040872a61c6e1ca6dcd8b23149f07b Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:10:48 +0200 Subject: [PATCH 57/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 3525ea96..33064483 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -48,9 +48,9 @@ jobs: id: set-restore-env run: | if [ "${{ vars.RESTORE_ENVIRONMENT_NAME }}" = "false" ] || [ -z "${{ inputs.restore_environment }}" ]; then - echo "restore-env-name=${{ inputs.environment }}" >> $GITHUB_OUTPUT + echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" >> $GITHUB_OUTPUT fi - echo "restore-env-name=${{ inputs.environment }}" + echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" # get-backup-user: # name: Get backup user # uses: ./.github/workflows/get-secret-from-environment.yml From 8e2dd69fe073d3de457d3543b2fef2ca0cdf3cca Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:13:43 +0200 Subject: [PATCH 58/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 33064483..ee387d3c 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -12,11 +12,11 @@ on: options: - production - staging - restore_environment: - description: "Restore environment name" - required: false - default: "production" - type: string + # restore_environment: + # description: "Restore environment name" + # required: false + # default: "production" + # type: string namespace_template: description: "Secrets mapping template" default: "opencrvs" @@ -47,7 +47,7 @@ jobs: - name: Set restore environment name id: set-restore-env run: | - if [ "${{ vars.RESTORE_ENVIRONMENT_NAME }}" = "false" ] || [ -z "${{ inputs.restore_environment }}" ]; then + if [ "${{ vars.RESTORE_ENVIRONMENT_NAME }}" = "false" ]; then echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" >> $GITHUB_OUTPUT fi echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" From e0a65758b62745d28b54085b28edcc46524bb941 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:15:47 +0200 Subject: [PATCH 59/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index ee387d3c..14e62aa9 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -51,6 +51,18 @@ jobs: echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" >> $GITHUB_OUTPUT fi echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" + get-secrets: + needs: get-restore-env-name + if: needs.get-restore-env-name.outputs.restore_env_name != 'false' + name: Get secrets for restore environment + runs-on: ubuntu-24.04 + environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} + steps: + - name: Fetch secrets for restore environment + run: | + echo "Fetching secrets for environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} ${{toJSON(secrets)}}}}" + + # Add commands here to fetch and store secrets as needed # get-backup-user: # name: Get backup user # uses: ./.github/workflows/get-secret-from-environment.yml From 332ff0ad26db89f82fed25730f03091a9411b423 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:17:21 +0200 Subject: [PATCH 60/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 14e62aa9..bfb6fe9f 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -61,7 +61,7 @@ jobs: - name: Fetch secrets for restore environment run: | echo "Fetching secrets for environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} ${{toJSON(secrets)}}}}" - + echo "${{ toJSON(vars) }}" # Add commands here to fetch and store secrets as needed # get-backup-user: # name: Get backup user From 4f04e91c15b06d55a47ba7743ffbc4b4117ff10c Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:22:10 +0200 Subject: [PATCH 61/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index bfb6fe9f..13878c36 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -47,10 +47,11 @@ jobs: - name: Set restore environment name id: set-restore-env run: | - if [ "${{ vars.RESTORE_ENVIRONMENT_NAME }}" = "false" ]; then + if [ "${{ vars.RESTORE_ENVIRONMENT_NAME }}" != "false" ]; then + echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" >> $GITHUB_OUTPUT fi - echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" + get-secrets: needs: get-restore-env-name if: needs.get-restore-env-name.outputs.restore_env_name != 'false' From 093bb470ded07bd32e84d8d6c3e0cad31dea48d7 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:28:25 +0200 Subject: [PATCH 62/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 13878c36..ab6bff26 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -12,11 +12,6 @@ on: options: - production - staging - # restore_environment: - # description: "Restore environment name" - # required: false - # default: "production" - # type: string namespace_template: description: "Secrets mapping template" default: "opencrvs" @@ -32,9 +27,6 @@ on: namespace_template: type: string default: opencrvs - restore_environment: - type: string - default: "false" jobs: get-restore-env-name: @@ -51,13 +43,21 @@ jobs: echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" >> $GITHUB_OUTPUT fi - + - name: "Env name: ${{ steps.set-restore-env.outputs.restore-env-name }}" + environement: ${{ steps.set-restore-env.outputs.restore-env-name }} + run: | + echo "Determined restore environment name: ${{ steps.set-restore-env.outputs.restore-env-name }}" get-secrets: needs: get-restore-env-name if: needs.get-restore-env-name.outputs.restore_env_name != 'false' - name: Get secrets for restore environment + name: Get secrets for restore environment ${{ needs.get-restore-env-name.outputs.restore_env_name}} runs-on: ubuntu-24.04 environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} + outputs: + BACKUP_ENCRYPTION_PASSPHRASE: ${{ steps.fetch-secrets.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} + BACKUP_HOST_PRIVATE_KEY: ${{ steps.fetch-secrets.outputs.BACKUP_HOST_PRIVATE_KEY }} + BACKUP_HOST: ${{ steps.fetch-secrets.outputs.BACKUP_HOST }} + BACKUP_SERVER_USER: ${{ steps.fetch-secrets.outputs.BACKUP_SERVER_USER }} steps: - name: Fetch secrets for restore environment run: | From 220331a9db6ae479549f86f58719bcf8dd1944d4 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:29:00 +0200 Subject: [PATCH 63/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index ab6bff26..41a34b33 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -44,7 +44,7 @@ jobs: echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" >> $GITHUB_OUTPUT fi - name: "Env name: ${{ steps.set-restore-env.outputs.restore-env-name }}" - environement: ${{ steps.set-restore-env.outputs.restore-env-name }} + environment: ${{ steps.set-restore-env.outputs.restore-env-name }} run: | echo "Determined restore environment name: ${{ steps.set-restore-env.outputs.restore-env-name }}" get-secrets: From 4af47dd9f5ccb282413a40d9aa799e8444ada474 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:30:14 +0200 Subject: [PATCH 64/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 41a34b33..c985bc3a 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -29,6 +29,7 @@ on: default: opencrvs jobs: + environment: ${{ inputs.environment }} get-restore-env-name: name: Determine restore environment name outputs: @@ -44,7 +45,6 @@ jobs: echo "restore-env-name=${{ vars.RESTORE_ENVIRONMENT_NAME }}" >> $GITHUB_OUTPUT fi - name: "Env name: ${{ steps.set-restore-env.outputs.restore-env-name }}" - environment: ${{ steps.set-restore-env.outputs.restore-env-name }} run: | echo "Determined restore environment name: ${{ steps.set-restore-env.outputs.restore-env-name }}" get-secrets: @@ -52,7 +52,7 @@ jobs: if: needs.get-restore-env-name.outputs.restore_env_name != 'false' name: Get secrets for restore environment ${{ needs.get-restore-env-name.outputs.restore_env_name}} runs-on: ubuntu-24.04 - environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} + environment: ${{ vars.RESTORE_ENVIRONMENT_NAME }} outputs: BACKUP_ENCRYPTION_PASSPHRASE: ${{ steps.fetch-secrets.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} BACKUP_HOST_PRIVATE_KEY: ${{ steps.fetch-secrets.outputs.BACKUP_HOST_PRIVATE_KEY }} From 3ba271a87d80a923aa8eea70b00354afb3fdf76c Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:30:45 +0200 Subject: [PATCH 65/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index c985bc3a..755ab00e 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -28,8 +28,9 @@ on: type: string default: opencrvs +environment: ${{ inputs.environment }} + jobs: - environment: ${{ inputs.environment }} get-restore-env-name: name: Determine restore environment name outputs: From 48d1a8f14fb598627127a27424e948484b07680f Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:35:53 +0200 Subject: [PATCH 66/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 60 +++----------------- 1 file changed, 8 insertions(+), 52 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 755ab00e..2fc8736c 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -28,11 +28,9 @@ on: type: string default: opencrvs -environment: ${{ inputs.environment }} - jobs: get-restore-env-name: - name: Determine restore environment name + name: Determine backup source environment name outputs: restore_env_name: ${{ steps.set-restore-env.outputs.restore-env-name }} runs-on: ubuntu-24.04 @@ -50,67 +48,25 @@ jobs: echo "Determined restore environment name: ${{ steps.set-restore-env.outputs.restore-env-name }}" get-secrets: needs: get-restore-env-name - if: needs.get-restore-env-name.outputs.restore_env_name != 'false' + if: needs.get-restore-env-name.outputs.restore_env_name name: Get secrets for restore environment ${{ needs.get-restore-env-name.outputs.restore_env_name}} runs-on: ubuntu-24.04 environment: ${{ vars.RESTORE_ENVIRONMENT_NAME }} outputs: - BACKUP_ENCRYPTION_PASSPHRASE: ${{ steps.fetch-secrets.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} - BACKUP_HOST_PRIVATE_KEY: ${{ steps.fetch-secrets.outputs.BACKUP_HOST_PRIVATE_KEY }} - BACKUP_HOST: ${{ steps.fetch-secrets.outputs.BACKUP_HOST }} - BACKUP_SERVER_USER: ${{ steps.fetch-secrets.outputs.BACKUP_SERVER_USER }} + BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} + BACKUP_HOST_PRIVATE_KEY: ${{ secrets.BACKUP_HOST_PRIVATE_KEY }} + BACKUP_HOST: ${{ secrets.BACKUP_HOST }} + BACKUP_SERVER_USER: ${{ secrets.BACKUP_SERVER_USER }} steps: - name: Fetch secrets for restore environment run: | echo "Fetching secrets for environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} ${{toJSON(secrets)}}}}" echo "${{ toJSON(vars) }}" # Add commands here to fetch and store secrets as needed - # get-backup-user: - # name: Get backup user - # uses: ./.github/workflows/get-secret-from-environment.yml - # with: - # secret_name: 'BACKUP_SERVER_USER' - # env_name: ${{ inputs.restore_environment }} - # secrets: - # gh_token: ${{ secrets.GH_TOKEN }} - # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} - - # get-backup-host: - # name: Get backup host - # uses: ./.github/workflows/get-secret-from-environment.yml - # with: - # secret_name: 'BACKUP_HOST' - # env_name: ${{ inputs.restore_environment }} - # secrets: - # gh_token: ${{ secrets.GH_TOKEN }} - # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} - - # get-backup-ssh-key: - # name: Get backup SSH key - # uses: ./.github/workflows/get-secret-from-environment.yml - # with: - # secret_name: 'BACKUP_HOST_PRIVATE_KEY' - # env_name: ${{ inputs.restore_environment }} - # secrets: - # gh_token: ${{ secrets.GH_TOKEN }} - # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} - - # get-backup-encryption-key: - # name: Get backup encryption key - # uses: ./.github/workflows/get-secret-from-environment.yml - # with: - # secret_name: 'BACKUP_ENCRYPTION_PASSPHRASE' - # env_name: ${{ inputs.restore_environment }} - # secrets: - # gh_token: ${{ secrets.GH_TOKEN }} - # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} sync-env: - # needs: - # - get-backup-user - # - get-backup-host - # - get-backup-encryption-key - # - get-backup-ssh-key + needs: + - get-secrets name: Sync GitHub env to Kubernetes environment: ${{ inputs.environment }} runs-on: From f7f359077a89b89b9a0959ae03a5331d80b69132 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:49:32 +0200 Subject: [PATCH 67/98] testing --- .../secret-mapping-opencrvs-deps.yml | 17 +++++++-------- .github/workflows/github-to-k8s-sync-env.yml | 21 +++---------------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml index 9b241842..0a3352f8 100644 --- a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml +++ b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml @@ -1,11 +1,3 @@ - -backup-encryption-secret: - type: Opaque - data: - # This is the password that is used to encrypt all the backups that OpenCRVS creates from - # a production server and that are stored on the backup server. Use this passphrase to decrypt the backups. - - BACKUP_ENCRYPTION_PASSPHRASE:backup_encryption_key - elasticsearch-admin-user: type: Opaque data: @@ -58,4 +50,11 @@ backup-server-ssh-credentials: backup-encryption-secret: type: Opaque data: - - BACKUP_ENCRYPTION_PASSPHRASE: backup_encryption_key + # This is the password that is used to encrypt all the backups that OpenCRVS creates from + # a production server and that are stored on the backup server. Use this passphrase to decrypt the backups. + - BACKUP_ENCRYPTION_PASSPHRASE: backup_encryption_key + +restore-encryption-secret: + type: Opaque + data: + - RESTORE_ENCRYPTION_PASSPHRASE: backup_encryption_key diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 2fc8736c..1dba81b1 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -54,9 +54,6 @@ jobs: environment: ${{ vars.RESTORE_ENVIRONMENT_NAME }} outputs: BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} - BACKUP_HOST_PRIVATE_KEY: ${{ secrets.BACKUP_HOST_PRIVATE_KEY }} - BACKUP_HOST: ${{ secrets.BACKUP_HOST }} - BACKUP_SERVER_USER: ${{ secrets.BACKUP_SERVER_USER }} steps: - name: Fetch secrets for restore environment run: | @@ -92,21 +89,9 @@ jobs: echo env_file=$ENV_FILE >> $GITHUB_ENV cat $ENV_FILE - # - name: Save secrets - # if: needs.get-backup-user.outputs.environment_exists == 'true' - # run: | - # echo "${{ needs.get-backup-user.outputs.secret_value }}" | base64 --decode | \ - # openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_user - # echo "${{ needs.get-backup-host.outputs.secret_value }}" | base64 --decode | \ - # openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_host - # echo "${{ needs.get-backup-encryption-key.outputs.secret_value }}" | base64 --decode | \ - # openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_encryption_key - # echo "${{ needs.get-backup-ssh-key.outputs.secret_value }}" | base64 --decode | \ - # openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_ssh_key - # echo BACKUP_USER=$(cat /tmp/backup_user | base64) >> $env_file - # echo BACKUP_HOST=$(cat /tmp/backup_host | base64) >> $env_file - # echo BACKUP_ENCRYPTION_PASSPHRASE=$(cat /tmp/backup_encryption_key | base64) >> $env_file - # echo BACKUP_HOST_PRIVATE_KEY=$(cat /tmp/backup_ssh_key | base64) >> $env_file + - name: Save restore (backup source) environment secrets + run: | + echo RESTORE_ENCRYPTION_PASSPHRASE=${{ needs.get-secrets.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} >> $env_file - name: Preprocess mapping into Secret YAMLs run: | From 2ba30d023bac2d55ea4c68f25b036572efc68cc9 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 17:53:38 +0200 Subject: [PATCH 68/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 1dba81b1..20260e8c 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -51,7 +51,7 @@ jobs: if: needs.get-restore-env-name.outputs.restore_env_name name: Get secrets for restore environment ${{ needs.get-restore-env-name.outputs.restore_env_name}} runs-on: ubuntu-24.04 - environment: ${{ vars.RESTORE_ENVIRONMENT_NAME }} + environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} outputs: BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} steps: From e792b2cdf32665580d5d4516dea48f399bc45503 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:01:03 +0200 Subject: [PATCH 69/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 20260e8c..7fc5d5a7 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -53,11 +53,12 @@ jobs: runs-on: ubuntu-24.04 environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} outputs: - BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} + BACKUP_ENCRYPTION_PASSPHRASE: ${{ steps.fetch-secrets.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} steps: - name: Fetch secrets for restore environment + id: fetch-secrets run: | - echo "Fetching secrets for environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} ${{toJSON(secrets)}}}}" + echo "BACKUP_ENCRYPTION_PASSPHRASE=${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }}" >> $GITHUB_OUTPUT echo "${{ toJSON(vars) }}" # Add commands here to fetch and store secrets as needed From 481e5edef3efb013b9a454a81e2722a8082bbfd0 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:12:46 +0200 Subject: [PATCH 70/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 25 ++++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 7fc5d5a7..434269fb 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -46,21 +46,20 @@ jobs: - name: "Env name: ${{ steps.set-restore-env.outputs.restore-env-name }}" run: | echo "Determined restore environment name: ${{ steps.set-restore-env.outputs.restore-env-name }}" - get-secrets: + + get-restore-encryption-key: needs: get-restore-env-name if: needs.get-restore-env-name.outputs.restore_env_name - name: Get secrets for restore environment ${{ needs.get-restore-env-name.outputs.restore_env_name}} - runs-on: ubuntu-24.04 - environment: ${{ needs.get-restore-env-name.outputs.restore_env_name }} - outputs: - BACKUP_ENCRYPTION_PASSPHRASE: ${{ steps.fetch-secrets.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} - steps: - - name: Fetch secrets for restore environment - id: fetch-secrets - run: | - echo "BACKUP_ENCRYPTION_PASSPHRASE=${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }}" >> $GITHUB_OUTPUT - echo "${{ toJSON(vars) }}" - # Add commands here to fetch and store secrets as needed + name: Get production backup encryption key + uses: ./.github/workflows/get-secret-from-environment.yml + with: + secret_name: 'BACKUP_ENCRYPTION_PASSPHRASE' + env_name: ${{ needs.get-restore-env-name.outputs.restore_env_name}} + # secrets: + # gh_token: ${{ secrets.GH_TOKEN }} + # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + # BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} + sync-env: needs: From 3a42d0dc9815a10d1ba4a7f933001b9c7a12f606 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:13:38 +0200 Subject: [PATCH 71/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 434269fb..e8f8196b 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -63,7 +63,7 @@ jobs: sync-env: needs: - - get-secrets + - get-restore-encryption-key name: Sync GitHub env to Kubernetes environment: ${{ inputs.environment }} runs-on: @@ -91,7 +91,7 @@ jobs: cat $ENV_FILE - name: Save restore (backup source) environment secrets run: | - echo RESTORE_ENCRYPTION_PASSPHRASE=${{ needs.get-secrets.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} >> $env_file + echo RESTORE_ENCRYPTION_PASSPHRASE=${{ needs.get-restore-encryption-key.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} >> $env_file - name: Preprocess mapping into Secret YAMLs run: | From a398133ab996a65e7c84090e734a06e46bd9d05c Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:14:28 +0200 Subject: [PATCH 72/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index e8f8196b..a347a5fd 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -55,8 +55,8 @@ jobs: with: secret_name: 'BACKUP_ENCRYPTION_PASSPHRASE' env_name: ${{ needs.get-restore-env-name.outputs.restore_env_name}} - # secrets: - # gh_token: ${{ secrets.GH_TOKEN }} + secrets: + gh_token: ${{ secrets.GH_TOKEN }} # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} # BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} From d5e0a63125af840b35d12f3628a303fdb7693682 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:15:13 +0200 Subject: [PATCH 73/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index a347a5fd..d57630e4 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -57,7 +57,7 @@ jobs: env_name: ${{ needs.get-restore-env-name.outputs.restore_env_name}} secrets: gh_token: ${{ secrets.GH_TOKEN }} - # encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} # BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} From 3dba77f6a430396ce42a149b127bbb16b9cffa10 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:16:41 +0200 Subject: [PATCH 74/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index d57630e4..cac900dc 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -49,16 +49,17 @@ jobs: get-restore-encryption-key: needs: get-restore-env-name + environment: ${{ inputs.environment }} if: needs.get-restore-env-name.outputs.restore_env_name name: Get production backup encryption key uses: ./.github/workflows/get-secret-from-environment.yml with: secret_name: 'BACKUP_ENCRYPTION_PASSPHRASE' - env_name: ${{ needs.get-restore-env-name.outputs.restore_env_name}} + env_name: ${{ needs.get-restore-env-name.outputs.restore_env_name }} secrets: gh_token: ${{ secrets.GH_TOKEN }} encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} - # BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} + BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} sync-env: From 25963533603a77f3422e27166c7fabc8776613bd Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:17:31 +0200 Subject: [PATCH 75/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index cac900dc..ef988990 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -49,7 +49,6 @@ jobs: get-restore-encryption-key: needs: get-restore-env-name - environment: ${{ inputs.environment }} if: needs.get-restore-env-name.outputs.restore_env_name name: Get production backup encryption key uses: ./.github/workflows/get-secret-from-environment.yml From 784e548df88a28f677dcc3afead978590bf863b3 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:20:09 +0200 Subject: [PATCH 76/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index ef988990..c5fb28c4 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -92,6 +92,7 @@ jobs: - name: Save restore (backup source) environment secrets run: | echo RESTORE_ENCRYPTION_PASSPHRASE=${{ needs.get-restore-encryption-key.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} >> $env_file + grep RESTORE_ENCRYPTION_PASSPHRASE $env_file || echo "No restore encryption passphrase to add" - name: Preprocess mapping into Secret YAMLs run: | From b70a5041d40cb853a7b7b4455721ae9ed14e8e80 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:22:32 +0200 Subject: [PATCH 77/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index c5fb28c4..1d6b54f4 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -91,7 +91,7 @@ jobs: cat $ENV_FILE - name: Save restore (backup source) environment secrets run: | - echo RESTORE_ENCRYPTION_PASSPHRASE=${{ needs.get-restore-encryption-key.outputs.BACKUP_ENCRYPTION_PASSPHRASE }} >> $env_file + echo RESTORE_ENCRYPTION_PASSPHRASE=${{ needs.get-restore-encryption-key.outputs.secret_value }} >> $env_file grep RESTORE_ENCRYPTION_PASSPHRASE $env_file || echo "No restore encryption passphrase to add" - name: Preprocess mapping into Secret YAMLs From 341b26b6c924b828fa0f76dc6b5e16c210b16f17 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:26:49 +0200 Subject: [PATCH 78/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 1d6b54f4..3fe631ea 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -91,7 +91,10 @@ jobs: cat $ENV_FILE - name: Save restore (backup source) environment secrets run: | - echo RESTORE_ENCRYPTION_PASSPHRASE=${{ needs.get-restore-encryption-key.outputs.secret_value }} >> $env_file + echo "${{ needs.get-restore-encryption-key.outputs.secret_value }}" | base64 --decode | \ + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/encryption_key + echo RESTORE_ENCRYPTION_PASSPHRASE=$(< /tmp/encryption_key) >> $env_file + rm /tmp/encryption_key grep RESTORE_ENCRYPTION_PASSPHRASE $env_file || echo "No restore encryption passphrase to add" - name: Preprocess mapping into Secret YAMLs From 8197a2728aaa0e7f5fcf83d93a51d439bb1f4024 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:34:18 +0200 Subject: [PATCH 79/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 3fe631ea..3ce5b9fb 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -88,13 +88,12 @@ jobs: ' > $ENV_FILE echo env_file=$ENV_FILE >> $GITHUB_ENV - cat $ENV_FILE + cat $ENV_FILE | cut -d\= -f1 - name: Save restore (backup source) environment secrets run: | - echo "${{ needs.get-restore-encryption-key.outputs.secret_value }}" | base64 --decode | \ - openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/encryption_key - echo RESTORE_ENCRYPTION_PASSPHRASE=$(< /tmp/encryption_key) >> $env_file - rm /tmp/encryption_key + RESTORE_ENCRYPTION_PASSPHRASE=$(echo "${{ needs.get-restore-encryption-key.outputs.secret_value }}" | base64 --decode | \ + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) + echo RESTORE_ENCRYPTION_PASSPHRASE=$RESTORE_ENCRYPTION_PASSPHRASE >> $env_file grep RESTORE_ENCRYPTION_PASSPHRASE $env_file || echo "No restore encryption passphrase to add" - name: Preprocess mapping into Secret YAMLs From 61f3036e0b4f3f14de948625cc31127d44dd40b4 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 18:38:35 +0200 Subject: [PATCH 80/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 3ce5b9fb..7a7dd776 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -59,7 +59,18 @@ jobs: gh_token: ${{ secrets.GH_TOKEN }} encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} - + get-restore-ssh-key: + needs: get-restore-env-name + if: needs.get-restore-env-name.outputs.restore_env_name + name: Get backup server ssh key + uses: ./.github/workflows/get-secret-from-environment.yml + with: + secret_name: 'BACKUP_HOST_PRIVATE_KEY' + env_name: ${{ needs.get-restore-env-name.outputs.restore_env_name }} + secrets: + gh_token: ${{ secrets.GH_TOKEN }} + encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + BACKUP_HOST_PRIVATE_KEY: ${{ secrets.BACKUP_HOST_PRIVATE_KEY }} sync-env: needs: @@ -93,7 +104,10 @@ jobs: run: | RESTORE_ENCRYPTION_PASSPHRASE=$(echo "${{ needs.get-restore-encryption-key.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) + BACKUP_HOST_PRIVATE_KEY=$(echo "${{ needs.get-restore-ssh-key.outputs.secret_value }}" | base64 --decode | \ + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) echo RESTORE_ENCRYPTION_PASSPHRASE=$RESTORE_ENCRYPTION_PASSPHRASE >> $env_file + echo BACKUP_HOST_PRIVATE_KEY=$BACKUP_HOST_PRIVATE_KEY >> $env_file grep RESTORE_ENCRYPTION_PASSPHRASE $env_file || echo "No restore encryption passphrase to add" - name: Preprocess mapping into Secret YAMLs From b5139fcfc177b116342783203be6e77a14861809 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:06:06 +0200 Subject: [PATCH 81/98] testing --- .../secret-mapping-opencrvs-deps.yml | 1 + .github/workflows/github-to-k8s-sync-env.yml | 35 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml index 0a3352f8..c3f63588 100644 --- a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml +++ b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml @@ -54,6 +54,7 @@ backup-encryption-secret: # a production server and that are stored on the backup server. Use this passphrase to decrypt the backups. - BACKUP_ENCRYPTION_PASSPHRASE: backup_encryption_key +# github-to-k8s-sync-env.yml: restore-encryption-secret: type: Opaque data: diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 7a7dd776..a8644965 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -71,7 +71,30 @@ jobs: gh_token: ${{ secrets.GH_TOKEN }} encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} BACKUP_HOST_PRIVATE_KEY: ${{ secrets.BACKUP_HOST_PRIVATE_KEY }} - + get-restore-host: + needs: get-restore-env-name + if: needs.get-restore-env-name.outputs.restore_env_name + name: Get backup server host + uses: ./.github/workflows/get-secret-from-environment.yml + with: + secret_name: 'BACKUP_HOST' + env_name: ${{ needs.get-restore-env-name.outputs.restore_env_name }} + secrets: + gh_token: ${{ secrets.GH_TOKEN }} + encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + BACKUP_HOST: ${{ secrets.BACKUP_HOST }} + get-restore-ssh-user: + needs: get-restore-env-name + if: needs.get-restore-env-name.outputs.restore_env_name + name: Get backup server ssh user + uses: ./.github/workflows/get-secret-from-environment.yml + with: + secret_name: 'BACKUP_SERVER_USER' + env_name: ${{ needs.get-restore-env-name.outputs.restore_env_name }} + secrets: + gh_token: ${{ secrets.GH_TOKEN }} + encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} + BACKUP_SERVER_USER: ${{ secrets.BACKUP_SERVER_USER }} sync-env: needs: - get-restore-encryption-key @@ -104,10 +127,20 @@ jobs: run: | RESTORE_ENCRYPTION_PASSPHRASE=$(echo "${{ needs.get-restore-encryption-key.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) + + BACKUP_HOST=$(echo "${{ needs.get-restore-host.outputs.secret_value }}" | base64 --decode | \ + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) + BACKUP_HOST_PRIVATE_KEY=$(echo "${{ needs.get-restore-ssh-key.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) + + BACKUP_SERVER_USER=$(echo "${{ needs.get-restore-ssh-user.outputs.secret_value }}" | base64 --decode | \ + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) + echo RESTORE_ENCRYPTION_PASSPHRASE=$RESTORE_ENCRYPTION_PASSPHRASE >> $env_file + echo BACKUP_HOST=$BACKUP_HOST >> $env_file echo BACKUP_HOST_PRIVATE_KEY=$BACKUP_HOST_PRIVATE_KEY >> $env_file + echo BACKUP_SERVER_USER=$BACKUP_SERVER_USER >> $env_file grep RESTORE_ENCRYPTION_PASSPHRASE $env_file || echo "No restore encryption passphrase to add" - name: Preprocess mapping into Secret YAMLs From ff5f51c36d7de584ec217b82c899d97f9d69cbbf Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:10:56 +0200 Subject: [PATCH 82/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index a8644965..00e0878b 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -97,6 +97,9 @@ jobs: BACKUP_SERVER_USER: ${{ secrets.BACKUP_SERVER_USER }} sync-env: needs: + - get-restore-ssh-key + - get-restore-host + - get-restore-ssh-user - get-restore-encryption-key name: Sync GitHub env to Kubernetes environment: ${{ inputs.environment }} From 22362fa25762699d401cdbbab956ce928ac8bb7c Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:12:15 +0200 Subject: [PATCH 83/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 00e0878b..fe1440c9 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -30,7 +30,7 @@ on: jobs: get-restore-env-name: - name: Determine backup source environment name + name: Get restore environment name outputs: restore_env_name: ${{ steps.set-restore-env.outputs.restore-env-name }} runs-on: ubuntu-24.04 @@ -50,7 +50,7 @@ jobs: get-restore-encryption-key: needs: get-restore-env-name if: needs.get-restore-env-name.outputs.restore_env_name - name: Get production backup encryption key + name: Get backup encryption key uses: ./.github/workflows/get-secret-from-environment.yml with: secret_name: 'BACKUP_ENCRYPTION_PASSPHRASE' @@ -62,7 +62,7 @@ jobs: get-restore-ssh-key: needs: get-restore-env-name if: needs.get-restore-env-name.outputs.restore_env_name - name: Get backup server ssh key + name: Get backup ssh key uses: ./.github/workflows/get-secret-from-environment.yml with: secret_name: 'BACKUP_HOST_PRIVATE_KEY' @@ -74,7 +74,7 @@ jobs: get-restore-host: needs: get-restore-env-name if: needs.get-restore-env-name.outputs.restore_env_name - name: Get backup server host + name: Get backup host uses: ./.github/workflows/get-secret-from-environment.yml with: secret_name: 'BACKUP_HOST' @@ -86,7 +86,7 @@ jobs: get-restore-ssh-user: needs: get-restore-env-name if: needs.get-restore-env-name.outputs.restore_env_name - name: Get backup server ssh user + name: Get backup ssh user uses: ./.github/workflows/get-secret-from-environment.yml with: secret_name: 'BACKUP_SERVER_USER' From f75960594b6856da7aa9485c959826198683d561 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:13:20 +0200 Subject: [PATCH 84/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index fe1440c9..9c898627 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -30,6 +30,7 @@ on: jobs: get-restore-env-name: + if: ${{ inputs.namespace_template == 'opencrvs-deps' }} name: Get restore environment name outputs: restore_env_name: ${{ steps.set-restore-env.outputs.restore-env-name }} From 26f1f271986e2a2f4e46bd9a5475ca80069b647c Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:23:57 +0200 Subject: [PATCH 85/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 9c898627..514acde9 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -145,7 +145,7 @@ jobs: echo BACKUP_HOST=$BACKUP_HOST >> $env_file echo BACKUP_HOST_PRIVATE_KEY=$BACKUP_HOST_PRIVATE_KEY >> $env_file echo BACKUP_SERVER_USER=$BACKUP_SERVER_USER >> $env_file - grep RESTORE_ENCRYPTION_PASSPHRASE $env_file || echo "No restore encryption passphrase to add" + grep BACKUP_HOST_PRIVATE_KEY $env_file || echo "No restore encryption passphrase to add" - name: Preprocess mapping into Secret YAMLs run: | From 089098dc8b60a86972b2f891e5b9daef4a9e9566 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:27:44 +0200 Subject: [PATCH 86/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 514acde9..a4fafc87 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -136,7 +136,7 @@ jobs: openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) BACKUP_HOST_PRIVATE_KEY=$(echo "${{ needs.get-restore-ssh-key.outputs.secret_value }}" | base64 --decode | \ - openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64 | sed 's/ //g') BACKUP_SERVER_USER=$(echo "${{ needs.get-restore-ssh-user.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) From 2928c118591d35782a904f06f0bec000304989a8 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:29:11 +0200 Subject: [PATCH 87/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index a4fafc87..2d0f702b 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -136,7 +136,7 @@ jobs: openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) BACKUP_HOST_PRIVATE_KEY=$(echo "${{ needs.get-restore-ssh-key.outputs.secret_value }}" | base64 --decode | \ - openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64 | sed 's/ //g') + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64 | sed 's/\n//g') BACKUP_SERVER_USER=$(echo "${{ needs.get-restore-ssh-user.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) From 5d0e4a0f7be792fb79f89fd737273014b979d561 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:33:59 +0200 Subject: [PATCH 88/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 2d0f702b..baf5e64b 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -136,7 +136,7 @@ jobs: openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) BACKUP_HOST_PRIVATE_KEY=$(echo "${{ needs.get-restore-ssh-key.outputs.secret_value }}" | base64 --decode | \ - openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64 | sed 's/\n//g') + openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64 | tr -d ' \n') BACKUP_SERVER_USER=$(echo "${{ needs.get-restore-ssh-user.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) From 7e046a0080711eb64440e676d3f4919a25821f10 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:37:50 +0200 Subject: [PATCH 89/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index baf5e64b..71f0cd8a 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -131,15 +131,19 @@ jobs: run: | RESTORE_ENCRYPTION_PASSPHRASE=$(echo "${{ needs.get-restore-encryption-key.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) - + echo "::add-mask::$RESTORE_ENCRYPTION_PASSPHRASE" + BACKUP_HOST=$(echo "${{ needs.get-restore-host.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) + echo "::add-mask::$BACKUP_HOST" BACKUP_HOST_PRIVATE_KEY=$(echo "${{ needs.get-restore-ssh-key.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64 | tr -d ' \n') + echo "::add-mask::$BACKUP_HOST_PRIVATE_KEY" BACKUP_SERVER_USER=$(echo "${{ needs.get-restore-ssh-user.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) + echo "::add-mask::$BACKUP_SERVER_USER" echo RESTORE_ENCRYPTION_PASSPHRASE=$RESTORE_ENCRYPTION_PASSPHRASE >> $env_file echo BACKUP_HOST=$BACKUP_HOST >> $env_file From b9caf62e2ef10559620dadb56cb7665b9e585def Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:44:19 +0200 Subject: [PATCH 90/98] testing --- .github/TEMPLATES/secret-mapping-opencrvs-deps.yml | 6 +++++- .github/workflows/github-to-k8s-sync-env.yml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml index c3f63588..16abd61c 100644 --- a/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml +++ b/.github/TEMPLATES/secret-mapping-opencrvs-deps.yml @@ -40,6 +40,8 @@ traefik-cert: - TRAEFIK_CERT: cert - TRAEFIK_KEY: key +# If backup is configured then workflow will use GitHub secrets for current environment +# If restore is configured then workflow will fetch secrets from source environment (usually production) backup-server-ssh-credentials: type: Opaque data: @@ -54,7 +56,9 @@ backup-encryption-secret: # a production server and that are stored on the backup server. Use this passphrase to decrypt the backups. - BACKUP_ENCRYPTION_PASSPHRASE: backup_encryption_key -# github-to-k8s-sync-env.yml: + +# RESTORE_ENCRYPTION_PASSPHRASE is fetched from source environment (usually production) +# Check workflow: github-to-k8s-sync-env.yml restore-encryption-secret: type: Opaque data: diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 71f0cd8a..f4d2479a 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -114,7 +114,7 @@ jobs: # to store GitHub Secrets and Variables (base64 encoded) # Making those values base64 encoded allows us to avoid further complex escaping issues # with special characters and multiline values when generating Kubernetes Secret manifests - - name: Export all secrets and environment variables + - name: Export all secrets and environment variables from GitHub run: | ENV_FILE=$(mktemp) jq -n -r ' From e16b86b37083180121befdaffaa887ff16e3f70b Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:55:12 +0200 Subject: [PATCH 91/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index f4d2479a..79b263a6 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -30,7 +30,6 @@ on: jobs: get-restore-env-name: - if: ${{ inputs.namespace_template == 'opencrvs-deps' }} name: Get restore environment name outputs: restore_env_name: ${{ steps.set-restore-env.outputs.restore-env-name }} From c9eb4db1600cb0585889e21db890e8285c0a2f4a Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:57:06 +0200 Subject: [PATCH 92/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 79b263a6..bd35fdc2 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -97,6 +97,7 @@ jobs: BACKUP_SERVER_USER: ${{ secrets.BACKUP_SERVER_USER }} sync-env: needs: + - get-restore-env-name - get-restore-ssh-key - get-restore-host - get-restore-ssh-user @@ -127,6 +128,7 @@ jobs: echo env_file=$ENV_FILE >> $GITHUB_ENV cat $ENV_FILE | cut -d\= -f1 - name: Save restore (backup source) environment secrets + if: needs.get-restore-env-name.outputs.restore_env_name run: | RESTORE_ENCRYPTION_PASSPHRASE=$(echo "${{ needs.get-restore-encryption-key.outputs.secret_value }}" | base64 --decode | \ openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" | base64) From 4c9d44aaa9458fe0913abbc07d6cb2c3a769fb6f Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 6 Jan 2026 22:59:15 +0200 Subject: [PATCH 93/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index bd35fdc2..e34614b9 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -49,7 +49,7 @@ jobs: get-restore-encryption-key: needs: get-restore-env-name - if: needs.get-restore-env-name.outputs.restore_env_name + # if: needs.get-restore-env-name.outputs.restore_env_name name: Get backup encryption key uses: ./.github/workflows/get-secret-from-environment.yml with: @@ -61,7 +61,7 @@ jobs: BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} get-restore-ssh-key: needs: get-restore-env-name - if: needs.get-restore-env-name.outputs.restore_env_name + # if: needs.get-restore-env-name.outputs.restore_env_name name: Get backup ssh key uses: ./.github/workflows/get-secret-from-environment.yml with: @@ -73,7 +73,7 @@ jobs: BACKUP_HOST_PRIVATE_KEY: ${{ secrets.BACKUP_HOST_PRIVATE_KEY }} get-restore-host: needs: get-restore-env-name - if: needs.get-restore-env-name.outputs.restore_env_name + # if: needs.get-restore-env-name.outputs.restore_env_name name: Get backup host uses: ./.github/workflows/get-secret-from-environment.yml with: @@ -85,7 +85,7 @@ jobs: BACKUP_HOST: ${{ secrets.BACKUP_HOST }} get-restore-ssh-user: needs: get-restore-env-name - if: needs.get-restore-env-name.outputs.restore_env_name + # if: needs.get-restore-env-name.outputs.restore_env_name name: Get backup ssh user uses: ./.github/workflows/get-secret-from-environment.yml with: From 7c9426776e667b66b70e29a9904fd119a480e737 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 7 Jan 2026 11:19:01 +0200 Subject: [PATCH 94/98] testing --- .github/workflows/deploy-opencrvs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deploy-opencrvs.yml b/.github/workflows/deploy-opencrvs.yml index f5335fe3..05a1b09a 100644 --- a/.github/workflows/deploy-opencrvs.yml +++ b/.github/workflows/deploy-opencrvs.yml @@ -58,7 +58,6 @@ jobs: uses: ./.github/workflows/github-to-k8s-sync-env.yml with: environment: ${{ inputs.environment }} - restore_environment: ${{ vars.RESTORE_ENVIRONMENT_NAME || 'false' }} secrets: inherit deploy: needs: github-to-k8s-sync-env From 7382aa73acbe6d82703cb66fcf0dd92181d5724c Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 7 Jan 2026 12:11:35 +0200 Subject: [PATCH 95/98] testing --- .github/workflows/github-to-k8s-sync-env.yml | 1 + environments/staging/dependencies/values.yaml | 15 +++++++++------ infrastructure/environments/setup-environment.ts | 5 ++++- .../charts-values/dependencies/values.yaml | 16 ++++++++++++++++ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index e34614b9..63cb310e 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -10,6 +10,7 @@ on: default: "staging" type: choice options: + - demo1 - production - staging namespace_template: diff --git a/environments/staging/dependencies/values.yaml b/environments/staging/dependencies/values.yaml index f89bc415..77905417 100644 --- a/environments/staging/dependencies/values.yaml +++ b/environments/staging/dependencies/values.yaml @@ -1,6 +1,6 @@ storage_type: host_path -environment_type: production +environment_type: undefined minio: use_default_credentials: false @@ -24,15 +24,18 @@ elastalert: env: HTTP_POST2_ALERT_URL: http://countryconfig.opencrvs-staging.svc.cluster.local:3040/email +# Backup configuration +backup: + enabled: false + schedule: "0 1 * * *" + backup_server_secret: backup-server-ssh-credentials + backup_server_dir: /home/backup/staging + + # Restore configuration restore: enabled: true - # Schedule job schedule: "0 0 * * *" - # Secret to store backup server connection configuration: - # - user, backup server username - # - host, hostname / IP of backup server - # - ssh_key, ssh key for passwordless connection backup_server_secret: backup-server-ssh-credentials backup_server_dir: /home/backup/production backup_encryption_secret: restore-encryption-secret \ No newline at end of file diff --git a/infrastructure/environments/setup-environment.ts b/infrastructure/environments/setup-environment.ts index 7b23a389..4a3585e1 100644 --- a/infrastructure/environments/setup-environment.ts +++ b/infrastructure/environments/setup-environment.ts @@ -1278,7 +1278,10 @@ ALL_QUESTIONS.push( // FIXME: In general that should be environment_type, // Hardcode like this blocks us from being generic: // https://github.com/opencrvs/opencrvs-core/issues/11171 - is_qa_env: environment !== 'production' ? "true" : "false" + is_qa_env: environment !== 'production' ? "true" : "false", + backup_enabled: configureBackup ? "true" : "false", + restore_enabled: restoreEnvironmentName ? "true" : "false", + restore_environment_name: restoreEnvironmentName || "" } ) await updateWorkflowEnvironments(); diff --git a/infrastructure/environments/templates/charts-values/dependencies/values.yaml b/infrastructure/environments/templates/charts-values/dependencies/values.yaml index 468c1738..0d04e11e 100644 --- a/infrastructure/environments/templates/charts-values/dependencies/values.yaml +++ b/infrastructure/environments/templates/charts-values/dependencies/values.yaml @@ -23,3 +23,19 @@ monitoring: elastalert: env: HTTP_POST2_ALERT_URL: http://countryconfig.opencrvs-{{env}}.svc.cluster.local:3040/email + +# Backup configuration +backup: + enabled: {{backup_enabled}} + schedule: "0 1 * * *" + backup_server_secret: backup-server-ssh-credentials + backup_server_dir: /home/backup/{{env}} + + +# Restore configuration +restore: + enabled: {{restore_enabled}} + schedule: "0 0 * * *" + backup_server_secret: backup-server-ssh-credentials + backup_server_dir: /home/backup/{{restore_environment_name}} + backup_encryption_secret: restore-encryption-secret \ No newline at end of file From 45aae3072fa301cbb2d16b93baae503f1131e9fd Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 13 Jan 2026 13:04:49 +0200 Subject: [PATCH 96/98] testing --- .../environments/derived-variables.ts | 2 +- infrastructure/environments/questions.ts | 2 +- .../environments/setup-environment.ts | 47 +++++++++++++++---- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/infrastructure/environments/derived-variables.ts b/infrastructure/environments/derived-variables.ts index 80e0373c..881d2c8f 100644 --- a/infrastructure/environments/derived-variables.ts +++ b/infrastructure/environments/derived-variables.ts @@ -149,7 +149,7 @@ export const derivedVariables = [ { name: 'RESTORE_ENVIRONMENT_NAME', valueLabel: 'RESTORE_ENVIRONMENT_NAME', - valueType: 'SECRET', + valueType: 'VARIABLE', type: 'disabled', scope: 'ENVIRONMENT' }, diff --git a/infrastructure/environments/questions.ts b/infrastructure/environments/questions.ts index 2de694a4..15b2cd4b 100644 --- a/infrastructure/environments/questions.ts +++ b/infrastructure/environments/questions.ts @@ -7,7 +7,7 @@ const notEmpty = (value: string | number) => export const environmentQuestions = [ { - name: 'type', + name: 'environment_type', type: 'select' as const, scope: 'ENVIRONMENT' as const, message: 'Purpose for the environment?', diff --git a/infrastructure/environments/setup-environment.ts b/infrastructure/environments/setup-environment.ts index 4a3585e1..585cee9c 100644 --- a/infrastructure/environments/setup-environment.ts +++ b/infrastructure/environments/setup-environment.ts @@ -502,7 +502,8 @@ ALL_QUESTIONS.push( )).configureRestore if (configureRestore) { const env_list_filtered = existingEnvironments.filter(env => env !== environment); - restoreEnvironmentName = (await prompts( + restoreEnvironmentName = (await promptAndStoreAnswer( + environment, [ { name: 'restoreEnvironmentName', @@ -517,7 +518,8 @@ ALL_QUESTIONS.push( validate: (input: string) => env_list_filtered.includes(input) ? true : 'Please select a valid environment.' } - ].map(questionToPrompt) + ], + existingValues )).restoreEnvironmentName } } else { @@ -935,10 +937,19 @@ ALL_QUESTIONS.push( ), scope: 'ENVIRONMENT' as const }, - ] - - if (restoreEnvironmentName) { - applicationServerUpdates.push({ + { + type: 'VARIABLE' as const, + name: 'LOGIN_URL', + value: allAnswers.restoreEnvironmentName, + didExist: findExistingValue( + 'LOGIN_URL', + 'VARIABLE', + 'ENVIRONMENT', + existingValues + ), + scope: 'ENVIRONMENT' as const + }, + { type: 'VARIABLE' as const, name: 'RESTORE_ENVIRONMENT_NAME', value: answerOrExisting(restoreEnvironmentName, findExistingValue( @@ -954,9 +965,29 @@ ALL_QUESTIONS.push( existingValues ), scope: 'ENVIRONMENT' as const + } + ] + + // if (restoreEnvironmentName) { + // applicationServerUpdates.push({ + // type: 'VARIABLE' as const, + // name: 'RESTORE_ENVIRONMENT_NAME', + // value: answerOrExisting(restoreEnvironmentName, findExistingValue( + // 'RESTORE_ENVIRONMENT_NAME', + // 'VARIABLE', + // 'ENVIRONMENT', + // existingValues + // ), (val) => val || ''), + // didExist: findExistingValue( + // 'RESTORE_ENVIRONMENT_NAME', + // 'VARIABLE', + // 'ENVIRONMENT', + // existingValues + // ), + // scope: 'ENVIRONMENT' as const - }) - } + // }) + // } if (enableEncryption) { applicationServerUpdates.push({ name: 'ENCRYPTION_KEY', From bf13547de7e8647ea5fc5b69ede22dea7bb3d1e1 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Tue, 13 Jan 2026 18:33:14 +0200 Subject: [PATCH 97/98] fix: Make fetch secret execution optional --- .github/workflows/github-to-k8s-sync-env.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/github-to-k8s-sync-env.yml b/.github/workflows/github-to-k8s-sync-env.yml index 63cb310e..774d1164 100644 --- a/.github/workflows/github-to-k8s-sync-env.yml +++ b/.github/workflows/github-to-k8s-sync-env.yml @@ -50,7 +50,7 @@ jobs: get-restore-encryption-key: needs: get-restore-env-name - # if: needs.get-restore-env-name.outputs.restore_env_name + if: needs.get-restore-env-name.outputs.restore_env_name name: Get backup encryption key uses: ./.github/workflows/get-secret-from-environment.yml with: @@ -62,7 +62,7 @@ jobs: BACKUP_ENCRYPTION_PASSPHRASE: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }} get-restore-ssh-key: needs: get-restore-env-name - # if: needs.get-restore-env-name.outputs.restore_env_name + if: needs.get-restore-env-name.outputs.restore_env_name name: Get backup ssh key uses: ./.github/workflows/get-secret-from-environment.yml with: @@ -74,7 +74,7 @@ jobs: BACKUP_HOST_PRIVATE_KEY: ${{ secrets.BACKUP_HOST_PRIVATE_KEY }} get-restore-host: needs: get-restore-env-name - # if: needs.get-restore-env-name.outputs.restore_env_name + if: needs.get-restore-env-name.outputs.restore_env_name name: Get backup host uses: ./.github/workflows/get-secret-from-environment.yml with: @@ -86,7 +86,7 @@ jobs: BACKUP_HOST: ${{ secrets.BACKUP_HOST }} get-restore-ssh-user: needs: get-restore-env-name - # if: needs.get-restore-env-name.outputs.restore_env_name + if: needs.get-restore-env-name.outputs.restore_env_name name: Get backup ssh user uses: ./.github/workflows/get-secret-from-environment.yml with: @@ -97,6 +97,7 @@ jobs: encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }} BACKUP_SERVER_USER: ${{ secrets.BACKUP_SERVER_USER }} sync-env: + if: always() needs: - get-restore-env-name - get-restore-ssh-key From 554e848e979e5cd6473c8372cae65a3666ef3c90 Mon Sep 17 00:00:00 2001 From: Vadym Mudryi Date: Wed, 14 Jan 2026 16:57:11 +0200 Subject: [PATCH 98/98] fix: error message when no weak DH ciphers found --- infrastructure/server-setup/tasks/all/users.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infrastructure/server-setup/tasks/all/users.yml b/infrastructure/server-setup/tasks/all/users.yml index 518d4d9c..66af1505 100644 --- a/infrastructure/server-setup/tasks/all/users.yml +++ b/infrastructure/server-setup/tasks/all/users.yml @@ -144,15 +144,15 @@ - name: Check short Diffie-Hellman keys ansible.builtin.shell: | - awk '$5 < 3071' /etc/ssh/moduli | grep -q . + awk '$5 < 3071' /etc/ssh/moduli | grep -q . && echo "found" || echo "none" register: short_dh_keys - ignore_errors: yes + changed_when: false - name: Remove short Diffie-Hellman keys ansible.builtin.shell: | awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.safe mv /etc/ssh/moduli.safe /etc/ssh/moduli - when: short_dh_keys.rc == 0 + when: '"found" in short_dh_keys.stdout' become: yes # Cleanup weak server keys