From ae1844616d26f10e46aa738a9e1a4c0aacf5a062 Mon Sep 17 00:00:00 2001 From: Melvin GABALI Date: Tue, 20 Jan 2026 06:05:03 +0100 Subject: [PATCH] Change namespace certificates --- apps/applicationset-certificates.yaml | 2 +- ...plicationset-tls-secrets-sync.yaml.disable | 49 ++++++++++++++ docs/TLS-SECRETS-SYNC.md | 62 +++++++++++++++++ helm/.tls-secrets-sync/ops/Chart.yaml | 5 ++ helm/.tls-secrets-sync/ops/README.md | 50 ++++++++++++++ .../ops/templates/namespace-certificates.yaml | 9 +++ .../ops/templates/rbac-secret-sync.yaml | 30 +++++++++ .../ops/templates/secret-homarr-dev.yaml | 16 +++++ .../ops/templates/sync-job-homarr-dev.yaml | 66 +++++++++++++++++++ helm/.tls-secrets-sync/ops/values.yaml | 8 +++ .../homarr/certificate-homarr-dev.yaml | 2 +- .../ops/templates/namespace-certificates.yaml | 9 +++ scripts/sync-all-tls-secrets.sh | 26 ++++++++ scripts/sync-tls-secret.sh | 60 +++++++++++++++++ 14 files changed, 392 insertions(+), 2 deletions(-) create mode 100644 apps/applicationset-tls-secrets-sync.yaml.disable create mode 100644 docs/TLS-SECRETS-SYNC.md create mode 100644 helm/.tls-secrets-sync/ops/Chart.yaml create mode 100644 helm/.tls-secrets-sync/ops/README.md create mode 100644 helm/.tls-secrets-sync/ops/templates/namespace-certificates.yaml create mode 100644 helm/.tls-secrets-sync/ops/templates/rbac-secret-sync.yaml create mode 100644 helm/.tls-secrets-sync/ops/templates/secret-homarr-dev.yaml create mode 100644 helm/.tls-secrets-sync/ops/templates/sync-job-homarr-dev.yaml create mode 100644 helm/.tls-secrets-sync/ops/values.yaml create mode 100644 helm/certificates/ops/templates/namespace-certificates.yaml create mode 100644 scripts/sync-all-tls-secrets.sh create mode 100644 scripts/sync-tls-secret.sh diff --git a/apps/applicationset-certificates.yaml b/apps/applicationset-certificates.yaml index 0ac9863..79f1568 100644 --- a/apps/applicationset-certificates.yaml +++ b/apps/applicationset-certificates.yaml @@ -35,7 +35,7 @@ spec: destination: # Déploie uniquement sur le cluster OPS name: '{{name}}' - namespace: default + namespace: certificates-{{path.basename}} syncPolicy: automated: prune: true diff --git a/apps/applicationset-tls-secrets-sync.yaml.disable b/apps/applicationset-tls-secrets-sync.yaml.disable new file mode 100644 index 0000000..b79ca4f --- /dev/null +++ b/apps/applicationset-tls-secrets-sync.yaml.disable @@ -0,0 +1,49 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: tls-secrets-sync + namespace: argocd-ops +spec: + generators: + # Génère une application pour chaque secret TLS à synchroniser + # depuis OPS vers les clusters DEV, RCT, PRD + - list: + elements: + # Homarr DEV : synchroniser depuis OPS vers DEV + - app: homarr + env: dev + secretName: homarr-dev-tls + sourceNamespace: certificates-ops + sourceCluster: cluster-ops + targetNamespace: homarr-dev + targetCluster: cluster-dev + template: + metadata: + name: 'tls-secret-sync-{{app}}-{{env}}' + spec: + project: default + source: + repoURL: https://git.gkdomaine.fr/kubernetes/argocd.git + targetRevision: main + path: helm/tls-secrets-sync/ops + helm: + valueFiles: + - values.yaml + values: | + app: {{app}} + env: {{env}} + secretName: {{secretName}} + sourceNamespace: {{sourceNamespace}} + sourceCluster: {{sourceCluster}} + targetNamespace: {{targetNamespace}} + targetCluster: {{targetCluster}} + destination: + # Les Jobs de synchronisation s'exécutent dans OPS + name: '{{sourceCluster}}' + namespace: '{{sourceNamespace}}' + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true diff --git a/docs/TLS-SECRETS-SYNC.md b/docs/TLS-SECRETS-SYNC.md new file mode 100644 index 0000000..ae40a6e --- /dev/null +++ b/docs/TLS-SECRETS-SYNC.md @@ -0,0 +1,62 @@ +# Synchronisation des Secrets TLS Multi-Cluster + +## Architecture + +Les certificats Let's Encrypt sont générés dans le cluster OPS (qui a cert-manager et accès Internet). Les secrets TLS doivent ensuite être synchronisés vers les clusters DEV, RCT et PRD où les applications sont déployées. + +## Solution actuelle + +La solution actuelle utilise des Jobs Kubernetes pour copier les secrets, mais nécessite une configuration manuelle des contextes kubectl. + +## Solution recommandée : Utiliser ArgoCD avec des Applications + +### Option 1 : Synchronisation manuelle via script + +Créez un script qui copie les secrets depuis OPS vers les autres clusters : + +```bash +#!/bin/bash +# sync-tls-secrets.sh + +SECRET_NAME="homarr-dev-tls" +SOURCE_CLUSTER="cluster-ops" +SOURCE_NS="certificates-ops" +TARGET_CLUSTER="cluster-dev" +TARGET_NS="homarr-dev" + +# Récupérer le secret depuis OPS +kubectl get secret $SECRET_NAME -n $SOURCE_NS --context=$SOURCE_CLUSTER -o yaml > /tmp/secret.yaml + +# Modifier les métadonnées +sed -i '/^ uid:/d' /tmp/secret.yaml +sed -i '/^ resourceVersion:/d' /tmp/secret.yaml +sed -i '/^ selfLink:/d' /tmp/secret.yaml +sed -i '/^ creationTimestamp:/d' /tmp/secret.yaml +sed -i "s/namespace: $SOURCE_NS/namespace: $TARGET_NS/" /tmp/secret.yaml + +# Appliquer sur le cluster cible +kubectl apply -f /tmp/secret.yaml --context=$TARGET_CLUSTER + +echo "Secret $SECRET_NAME synchronisé de $SOURCE_CLUSTER vers $TARGET_CLUSTER" +``` + +### Option 2 : Utiliser External Secrets Operator (Recommandé) + +External Secrets Operator peut synchroniser les secrets depuis un backend (comme Kubernetes secrets dans OPS) vers les autres clusters. + +### Option 3 : Utiliser un CronJob pour synchronisation automatique + +Créez un CronJob qui synchronise automatiquement les secrets toutes les heures ou à chaque changement. + +## Configuration actuelle + +- **Source** : Namespace `certificates-ops` sur cluster OPS +- **Destination** : Namespaces des applications sur clusters DEV/RCT/PRD +- **Mécanisme** : Jobs Kubernetes (nécessite configuration manuelle) + +## Prochaines étapes + +1. Configurer les contextes kubectl pour accéder aux différents clusters +2. Tester la synchronisation manuelle +3. Automatiser via CronJob ou External Secrets Operator + diff --git a/helm/.tls-secrets-sync/ops/Chart.yaml b/helm/.tls-secrets-sync/ops/Chart.yaml new file mode 100644 index 0000000..78c7fd8 --- /dev/null +++ b/helm/.tls-secrets-sync/ops/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: tls-secrets-sync +description: Synchronisation des secrets TLS depuis OPS vers les autres clusters +type: application +version: 1.0.0 diff --git a/helm/.tls-secrets-sync/ops/README.md b/helm/.tls-secrets-sync/ops/README.md new file mode 100644 index 0000000..adac1a2 --- /dev/null +++ b/helm/.tls-secrets-sync/ops/README.md @@ -0,0 +1,50 @@ +# Synchronisation des Secrets TLS + +Ce chart gère la synchronisation des secrets TLS depuis le cluster OPS vers les autres clusters (DEV, RCT, PRD). + +## Structure + +- `Chart.yaml` : Définition du chart Helm +- `values.yaml` : Configuration par défaut +- `templates/` : Templates Kubernetes + - `namespace-certificates.yaml` : Namespace pour les certificats sur OPS + - `secret-*.yaml` : Secrets de référence (optionnel) + - `sync-job-*.yaml` : Jobs de synchronisation + - `rbac-secret-sync.yaml` : RBAC pour les Jobs + +## Utilisation + +### Option 1 : Synchronisation manuelle via script (Recommandée) + +Utilisez le script `scripts/sync-tls-secret.sh` : + +```bash +./scripts/sync-tls-secret.sh homarr-dev-tls cluster-ops certificates-ops cluster-dev homarr-dev +``` + +### Option 2 : Synchronisation automatique via Jobs + +Les Jobs Kubernetes tentent de synchroniser automatiquement, mais nécessitent que les contextes kubectl soient configurés dans le pod. + +### Option 3 : Synchronisation via CronJob + +Créez un CronJob qui exécute le script de synchronisation périodiquement. + +## Configuration + +Les secrets sont synchronisés depuis : +- **Source** : Namespace `certificates-ops` sur cluster OPS +- **Destination** : Namespaces des applications sur clusters DEV/RCT/PRD + +## Ajout d'un nouveau secret à synchroniser + +1. Ajoutez une entrée dans `apps/applicationset-tls-secrets-sync.yaml` +2. Créez un template `sync-job--.yaml` si nécessaire +3. Ou utilisez directement le script `sync-tls-secret.sh` + +## Notes importantes + +- Les contextes kubectl doivent être configurés pour accéder aux différents clusters +- Le namespace de destination doit exister sur le cluster cible +- Les secrets sont copiés avec leurs données, mais les métadonnées sont nettoyées + diff --git a/helm/.tls-secrets-sync/ops/templates/namespace-certificates.yaml b/helm/.tls-secrets-sync/ops/templates/namespace-certificates.yaml new file mode 100644 index 0000000..9173a5c --- /dev/null +++ b/helm/.tls-secrets-sync/ops/templates/namespace-certificates.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: certificates-ops + labels: + name: certificates-ops + managed-by: argocd + purpose: tls-certificates + diff --git a/helm/.tls-secrets-sync/ops/templates/rbac-secret-sync.yaml b/helm/.tls-secrets-sync/ops/templates/rbac-secret-sync.yaml new file mode 100644 index 0000000..3cf077c --- /dev/null +++ b/helm/.tls-secrets-sync/ops/templates/rbac-secret-sync.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: secret-sync-sa + namespace: certificates-ops +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: secret-sync-role + namespace: certificates-ops +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: secret-sync-rolebinding + namespace: certificates-ops +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: secret-sync-role +subjects: +- kind: ServiceAccount + name: secret-sync-sa + namespace: certificates-ops + diff --git a/helm/.tls-secrets-sync/ops/templates/secret-homarr-dev.yaml b/helm/.tls-secrets-sync/ops/templates/secret-homarr-dev.yaml new file mode 100644 index 0000000..0dc5ca4 --- /dev/null +++ b/helm/.tls-secrets-sync/ops/templates/secret-homarr-dev.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Secret +metadata: + name: homarr-dev-tls + namespace: homarr-dev + labels: + app: homarr + environment: dev + managed-by: argocd + source-cluster: ops + source-namespace: certificates-ops +type: kubernetes.io/tls +# Les données seront copiées depuis le secret dans OPS +# Ce template sert de référence - le secret réel sera synchronisé via un Job ou script +data: {} + diff --git a/helm/.tls-secrets-sync/ops/templates/sync-job-homarr-dev.yaml b/helm/.tls-secrets-sync/ops/templates/sync-job-homarr-dev.yaml new file mode 100644 index 0000000..3cc32e8 --- /dev/null +++ b/helm/.tls-secrets-sync/ops/templates/sync-job-homarr-dev.yaml @@ -0,0 +1,66 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: sync-tls-secret-homarr-dev + namespace: certificates-ops + annotations: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation +spec: + template: + spec: + serviceAccountName: secret-sync-sa + containers: + - name: kubectl + image: bitnami/kubectl:latest + command: + - /bin/sh + - -c + - | + set -e + echo "=== Synchronisation du secret TLS homarr-dev-tls ===" + echo "Source: cluster-ops, namespace: certificates-ops" + echo "Destination: cluster-dev, namespace: homarr-dev" + + # Récupérer le secret depuis OPS (cluster actuel) + echo "1. Récupération du secret depuis OPS..." + kubectl get secret homarr-dev-tls -n certificates-ops -o yaml > /tmp/secret-source.yaml + + if [ ! -s /tmp/secret-source.yaml ]; then + echo "❌ Erreur: Le secret homarr-dev-tls n'existe pas dans certificates-ops sur OPS" + exit 1 + fi + + # Modifier les métadonnées pour la destination + echo "2. Préparation du secret pour DEV..." + cat /tmp/secret-source.yaml | \ + sed '/^ uid:/d' | \ + sed '/^ resourceVersion:/d' | \ + sed '/^ selfLink:/d' | \ + sed '/^ creationTimestamp:/d' | \ + sed 's/namespace: certificates-ops/namespace: homarr-dev/' > /tmp/secret-dest.yaml + + # Appliquer le secret sur DEV + # Note: Cela nécessite que kubectl soit configuré avec les contextes des clusters + echo "3. Application du secret sur DEV..." + + # Vérifier si le contexte cluster-dev existe + if kubectl config get-contexts cluster-dev &>/dev/null; then + # Créer le namespace s'il n'existe pas + kubectl create namespace homarr-dev --context=cluster-dev --dry-run=client -o yaml | kubectl apply --context=cluster-dev -f - || true + + # Appliquer le secret + kubectl apply -f /tmp/secret-dest.yaml --context=cluster-dev + + echo "✅ Secret synchronisé vers cluster-dev" + else + echo "⚠️ Le contexte cluster-dev n'est pas configuré dans kubectl" + echo " Pour synchroniser manuellement, exécutez :" + echo " kubectl apply -f /tmp/secret-dest.yaml --context=cluster-dev" + echo "" + echo " Ou utilisez le script :" + echo " ./scripts/sync-tls-secret.sh homarr-dev-tls cluster-ops certificates-ops cluster-dev homarr-dev" + fi + restartPolicy: Never + backoffLimit: 3 + diff --git a/helm/.tls-secrets-sync/ops/values.yaml b/helm/.tls-secrets-sync/ops/values.yaml new file mode 100644 index 0000000..5205528 --- /dev/null +++ b/helm/.tls-secrets-sync/ops/values.yaml @@ -0,0 +1,8 @@ +# Valeurs par défaut - seront surchargées par l'ApplicationSet +app: homarr +env: dev +secretName: homarr-dev-tls +sourceNamespace: certificates-ops +sourceCluster: cluster-ops +targetNamespace: homarr-dev +targetCluster: cluster-dev diff --git a/helm/certificates/ops/templates/homarr/certificate-homarr-dev.yaml b/helm/certificates/ops/templates/homarr/certificate-homarr-dev.yaml index 9392f8b..fc0b2f4 100644 --- a/helm/certificates/ops/templates/homarr/certificate-homarr-dev.yaml +++ b/helm/certificates/ops/templates/homarr/certificate-homarr-dev.yaml @@ -2,7 +2,7 @@ apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: homarr-dev-tls - namespace: homarr-dev + namespace: certificates-ops spec: secretName: homarr-dev-tls issuerRef: diff --git a/helm/certificates/ops/templates/namespace-certificates.yaml b/helm/certificates/ops/templates/namespace-certificates.yaml new file mode 100644 index 0000000..9173a5c --- /dev/null +++ b/helm/certificates/ops/templates/namespace-certificates.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: certificates-ops + labels: + name: certificates-ops + managed-by: argocd + purpose: tls-certificates + diff --git a/scripts/sync-all-tls-secrets.sh b/scripts/sync-all-tls-secrets.sh new file mode 100644 index 0000000..131fa87 --- /dev/null +++ b/scripts/sync-all-tls-secrets.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Script pour synchroniser tous les secrets TLS depuis OPS vers les autres clusters + +set -e + +echo "=== Synchronisation de tous les secrets TLS ===" +echo "" + +# Liste des secrets à synchroniser +# Format: secret_name:source_ns:target_cluster:target_ns +SECRETS=( + "homarr-dev-tls:certificates-ops:cluster-dev:homarr-dev" + # Ajoutez d'autres secrets ici + # "nextcloud-dev-tls:certificates-ops:cluster-dev:nextcloud-dev" +) + +for secret_config in "${SECRETS[@]}"; do + IFS=':' read -r secret_name source_ns target_cluster target_ns <<< "$secret_config" + + echo "Synchronisation de $secret_name vers $target_cluster..." + ./scripts/sync-tls-secret.sh "$secret_name" "cluster-ops" "$source_ns" "$target_cluster" "$target_ns" + echo "" +done + +echo "=== Toutes les synchronisations terminées ===" + diff --git a/scripts/sync-tls-secret.sh b/scripts/sync-tls-secret.sh new file mode 100644 index 0000000..65ea6ed --- /dev/null +++ b/scripts/sync-tls-secret.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Script pour synchroniser un secret TLS depuis OPS vers un autre cluster + +set -e + +# Configuration +SECRET_NAME="${1:-homarr-dev-tls}" +SOURCE_CLUSTER="${2:-cluster-ops}" +SOURCE_NS="${3:-certificates-ops}" +TARGET_CLUSTER="${4:-cluster-dev}" +TARGET_NS="${5:-homarr-dev}" + +echo "=== Synchronisation du secret TLS ===" +echo "Secret: $SECRET_NAME" +echo "Source: $SOURCE_CLUSTER (namespace: $SOURCE_NS)" +echo "Destination: $TARGET_CLUSTER (namespace: $TARGET_NS)" +echo "" + +# Vérifier que le secret existe dans la source +echo "1. Vérification du secret source..." +if ! kubectl get secret "$SECRET_NAME" -n "$SOURCE_NS" --context="$SOURCE_CLUSTER" &>/dev/null; then + echo "❌ Erreur: Le secret $SECRET_NAME n'existe pas dans $SOURCE_NS sur $SOURCE_CLUSTER" + exit 1 +fi + +# Récupérer le secret +echo "2. Récupération du secret depuis $SOURCE_CLUSTER..." +kubectl get secret "$SECRET_NAME" -n "$SOURCE_NS" --context="$SOURCE_CLUSTER" -o yaml > /tmp/secret-sync.yaml + +# Modifier les métadonnées +echo "3. Préparation du secret pour $TARGET_CLUSTER..." +sed -i.bak '/^ uid:/d' /tmp/secret-sync.yaml +sed -i.bak '/^ resourceVersion:/d' /tmp/secret-sync.yaml +sed -i.bak '/^ selfLink:/d' /tmp/secret-sync.yaml +sed -i.bak '/^ creationTimestamp:/d' /tmp/secret-sync.yaml +sed -i.bak "s/namespace: $SOURCE_NS/namespace: $TARGET_NS/" /tmp/secret-sync.yaml + +# Créer le namespace s'il n'existe pas +echo "4. Vérification/création du namespace $TARGET_NS sur $TARGET_CLUSTER..." +kubectl create namespace "$TARGET_NS" --context="$TARGET_CLUSTER" --dry-run=client -o yaml | kubectl apply --context="$TARGET_CLUSTER" -f - + +# Appliquer le secret +echo "5. Application du secret sur $TARGET_CLUSTER..." +kubectl apply -f /tmp/secret-sync.yaml --context="$TARGET_CLUSTER" + +# Vérification +echo "6. Vérification..." +if kubectl get secret "$SECRET_NAME" -n "$TARGET_NS" --context="$TARGET_CLUSTER" &>/dev/null; then + echo "✅ Secret $SECRET_NAME synchronisé avec succès vers $TARGET_CLUSTER" +else + echo "❌ Erreur: Le secret n'a pas été créé sur $TARGET_CLUSTER" + exit 1 +fi + +# Nettoyage +rm -f /tmp/secret-sync.yaml /tmp/secret-sync.yaml.bak + +echo "" +echo "=== Synchronisation terminée ===" +