From ec9f9b09007afdbf4f56216e36323d201a8b825d Mon Sep 17 00:00:00 2001 From: Kanwar Ujjaval Singh <4216199+kanwarujjaval@users.noreply.github.com> Date: Fri, 8 May 2026 19:21:17 +0530 Subject: [PATCH 1/2] enable optional TLS for canaries with configurable secret --- .../applications/07-v2-new-tls.yaml | 50 +++++++++++++++++++ .../applicationsets/06-canary-web-ui.yaml | 3 ++ .../templates/ingress.yaml | 15 +++--- charts/countly-web-ui-canary/values.yaml | 9 ++-- 4 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 argocd/countly-hosted/applications/07-v2-new-tls.yaml diff --git a/argocd/countly-hosted/applications/07-v2-new-tls.yaml b/argocd/countly-hosted/applications/07-v2-new-tls.yaml new file mode 100644 index 0000000..869aaa5 --- /dev/null +++ b/argocd/countly-hosted/applications/07-v2-new-tls.yaml @@ -0,0 +1,50 @@ +# ArgoCD Application that deploys the cert-manager bootstrap manifests +# (selfsigned Issuer + internal CA + wildcard Cert) for v2-new's canaries. +# +# Layout split (mirrors the canary ApplicationSet pattern): +# - manifests: countly-deployment/argocd/bootstrap/v2-new-tls/ +# - this wrapper: helm/argocd/countly-hosted/applications/07-v2-new-tls.yaml +# +# Lives here because the root countly-hosted-bootstrap Application +# (helm/argocd/countly-hosted/root-application.yaml) recursively syncs +# everything in helm/argocd/countly-hosted/, so dropping this file in +# applications/ is enough for ArgoCD to pick it up. +# +# Destination is hardcoded to v2-new — TLS bootstrap can never land on +# any other cluster. +# +# Project countly-customers allows namespace `countly` and includes +# Issuer/Certificate in namespaceResourceWhitelist (`*/*`). All resources +# created here live in the countly namespace — no cluster-scoped objects. +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: v2-new-canary-tls + namespace: argocd + labels: + app.kubernetes.io/part-of: countly + app.kubernetes.io/component: canary-tls +spec: + project: countly-customers + source: + repoURL: https://github.com/Countly/countly-deployment.git + targetRevision: main + path: argocd/bootstrap/v2-new-tls + directory: + recurse: false + destination: + server: https://34.62.8.139 + namespace: countly + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=false + - ServerSideApply=true + retry: + limit: 5 + backoff: + duration: 10s + factor: 2 + maxDuration: 2m diff --git a/argocd/countly-hosted/applicationsets/06-canary-web-ui.yaml b/argocd/countly-hosted/applicationsets/06-canary-web-ui.yaml index fd70966..14cfdac 100644 --- a/argocd/countly-hosted/applicationsets/06-canary-web-ui.yaml +++ b/argocd/countly-hosted/applicationsets/06-canary-web-ui.yaml @@ -56,6 +56,9 @@ spec: values: | imagePullSecrets: - name: countly-registry + ingress: + tls: + secretName: v2-count-ly-wildcard-tls - repoURL: https://github.com/Countly/countly-deployment.git targetRevision: main ref: values diff --git a/charts/countly-web-ui-canary/templates/ingress.yaml b/charts/countly-web-ui-canary/templates/ingress.yaml index 5b5f22a..164b991 100644 --- a/charts/countly-web-ui-canary/templates/ingress.yaml +++ b/charts/countly-web-ui-canary/templates/ingress.yaml @@ -11,16 +11,17 @@ metadata: labels: {{- include "canary.labels" . | nindent 4 }} annotations: - # No TLS on canaries: F5 NIC's hardcoded HTTP→HTTPS redirect plus its - # mergeable-ingress requirement (master/minion annotations on both the - # canary Ingress and cert-manager's solver Ingress) make HTTP-01 unworkable - # without splitting the canary Ingress into master/minion or setting up - # DNS-01 with Cloud DNS IAM. Canaries are dev-only previews; serving - # http:// is acceptable here. Switch back to TLS once a wildcard cert - # for *.v2.count.ly is provisioned (DNS-01 wildcard or external cert). {{- include "canary.ingressAnnotations" . | nindent 4 }} spec: ingressClassName: {{ .Values.ingress.className }} + {{- with .Values.ingress.tls }} + {{- if .secretName }} + tls: + - hosts: + - {{ include "canary.hostname" $ | quote }} + secretName: {{ .secretName | quote }} + {{- end }} + {{- end }} rules: - host: {{ include "canary.hostname" . | quote }} http: diff --git a/charts/countly-web-ui-canary/values.yaml b/charts/countly-web-ui-canary/values.yaml index 07c4627..082c3d1 100644 --- a/charts/countly-web-ui-canary/values.yaml +++ b/charts/countly-web-ui-canary/values.yaml @@ -24,12 +24,11 @@ backend: ingress: className: nginx - # No TLS for canaries (HTTP-only). Canaries are dev-only previews; F5 NIC - # mergeable-ingress requirements make per-canary HTTP-01 unworkable without - # significant chart restructuring. To re-enable TLS later, provision a - # wildcard cert for *.v2.count.ly (DNS-01 ClusterIssuer or external) and - # add a tls section back to templates/ingress.yaml referencing the shared Secret. annotations: {} + # TLS off by default — chart stays generic. Cluster-specific override + # comes via ApplicationSet helm.values (see canary-web-ui ApplicationSet). + tls: {} + # secretName: # set per cluster resources: requests: From dd5f9086a54625e7ecf144440663efbad26b0111 Mon Sep 17 00:00:00 2001 From: Kanwar Ujjaval Singh <4216199+kanwarujjaval@users.noreply.github.com> Date: Fri, 8 May 2026 19:27:20 +0530 Subject: [PATCH 2/2] convert cert-manager resources to ApplicationSet and restrict to v2-new --- .../applications/07-v2-new-tls.yaml | 88 +++++++++++-------- .../applicationsets/06-canary-web-ui.yaml | 51 ++++++----- 2 files changed, 79 insertions(+), 60 deletions(-) diff --git a/argocd/countly-hosted/applications/07-v2-new-tls.yaml b/argocd/countly-hosted/applications/07-v2-new-tls.yaml index 869aaa5..bf689ef 100644 --- a/argocd/countly-hosted/applications/07-v2-new-tls.yaml +++ b/argocd/countly-hosted/applications/07-v2-new-tls.yaml @@ -1,23 +1,20 @@ -# ArgoCD Application that deploys the cert-manager bootstrap manifests +# ApplicationSet that deploys the cert-manager bootstrap manifests # (selfsigned Issuer + internal CA + wildcard Cert) for v2-new's canaries. # -# Layout split (mirrors the canary ApplicationSet pattern): -# - manifests: countly-deployment/argocd/bootstrap/v2-new-tls/ -# - this wrapper: helm/argocd/countly-hosted/applications/07-v2-new-tls.yaml +# Layout split (mirrors all other AppSets in this dir): +# - manifests: countly-deployment/argocd/bootstrap/v2-new-tls/ +# - cluster info: countly-deployment/customers/v2-new.yaml (server URL, project) +# - this wrapper: helm/argocd/countly-hosted/applications/07-v2-new-tls.yaml # -# Lives here because the root countly-hosted-bootstrap Application -# (helm/argocd/countly-hosted/root-application.yaml) recursively syncs -# everything in helm/argocd/countly-hosted/, so dropping this file in -# applications/ is enough for ArgoCD to pick it up. +# Single-file generator on customers/v2-new.yaml restricts deployment to +# v2-new only — TLS bootstrap can't land on any other cluster. The server +# URL and project come from that customer file, so rotating either does +# not require touching this AppSet. # -# Destination is hardcoded to v2-new — TLS bootstrap can never land on -# any other cluster. -# -# Project countly-customers allows namespace `countly` and includes -# Issuer/Certificate in namespaceResourceWhitelist (`*/*`). All resources -# created here live in the countly namespace — no cluster-scoped objects. +# All resources created here live in the countly namespace +# (Issuer, Certificate). No cluster-scoped objects. apiVersion: argoproj.io/v1alpha1 -kind: Application +kind: ApplicationSet metadata: name: v2-new-canary-tls namespace: argocd @@ -25,26 +22,41 @@ metadata: app.kubernetes.io/part-of: countly app.kubernetes.io/component: canary-tls spec: - project: countly-customers - source: - repoURL: https://github.com/Countly/countly-deployment.git - targetRevision: main - path: argocd/bootstrap/v2-new-tls - directory: - recurse: false - destination: - server: https://34.62.8.139 - namespace: countly - syncPolicy: - automated: - prune: true - selfHeal: true - syncOptions: - - CreateNamespace=false - - ServerSideApply=true - retry: - limit: 5 - backoff: - duration: 10s - factor: 2 - maxDuration: 2m + goTemplate: true + goTemplateOptions: ["missingkey=error"] + generators: + - git: + repoURL: https://github.com/Countly/countly-deployment.git + revision: main + files: + - path: customers/v2-new.yaml + template: + metadata: + name: '{{ .customer }}-canary-tls' + labels: + app.kubernetes.io/part-of: countly + app.kubernetes.io/component: canary-tls + spec: + project: '{{ .project }}' + source: + repoURL: https://github.com/Countly/countly-deployment.git + targetRevision: main + path: argocd/bootstrap/v2-new-tls + directory: + recurse: false + destination: + server: '{{ .server }}' + namespace: countly + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=false + - ServerSideApply=true + retry: + limit: 5 + backoff: + duration: 10s + factor: 2 + maxDuration: 2m diff --git a/argocd/countly-hosted/applicationsets/06-canary-web-ui.yaml b/argocd/countly-hosted/applicationsets/06-canary-web-ui.yaml index 14cfdac..33cfeae 100644 --- a/argocd/countly-hosted/applicationsets/06-canary-web-ui.yaml +++ b/argocd/countly-hosted/applicationsets/06-canary-web-ui.yaml @@ -1,24 +1,23 @@ # ApplicationSet that creates one ArgoCD Application per countly-web-ui canary. # # Layout split: -# - chart: helm/charts/countly-web-ui-canary/ (this repo) -# - per-canary values: countly-deployment/argocd/canaries//values.yaml -# - cert-manager bootstrap App + ClusterIssuer: countly-deployment/argocd/{applications,bootstrap}/ +# - chart: helm/charts/countly-web-ui-canary/ (this repo) +# - per-canary values: countly-deployment/argocd/canaries//values.yaml +# - cluster (server URL, project): countly-deployment/customers/v2-new.yaml # -# This file lives in helm/ because the root `countly-bootstrap` Application -# (helm/argocd/root-application.yaml) auto-syncs everything in helm/argocd/. -# Putting it here means the ApplicationSet is git-discovered without any -# ArgoCD UI step. +# This file lives in helm/ because the root countly-hosted-bootstrap App +# recursively syncs helm/argocd/countly-hosted/. Putting it here means the +# ApplicationSet is git-discovered without any ArgoCD UI step. # -# Generator: scans countly-deployment/argocd/canaries/*/values.yaml and -# produces one Application per file. Pipeline B (countly-web-ui's -# canary-build-deploy.yml) writes/deletes those files. +# Generator: matrix of two git generators — +# 1. customers/v2-new.yaml — produces {{ .server }}, {{ .project }}, etc. +# pathParamPrefix=customer so its `path` becomes .customerPath.* and +# doesn't collide with the canary path below. +# 2. argocd/canaries/*/values.yaml — one entry per canary; provides +# .path.basename (the canary slug) plus the per-canary values. # -# Sources (multi-source): the chart comes from helm.git, the per-canary -# values file comes from countly-deployment.git via the $values alias. -# -# Destination: hardcoded to v2-new (https://34.62.8.139). No matrix or -# cluster fan-out — canaries can never land on other clusters. +# Restricting to v2-new is by explicit single-file generator (customers/v2-new.yaml) +# rather than a customers/*.yaml glob, because canaries never land on other clusters. apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: @@ -31,11 +30,19 @@ spec: goTemplate: true goTemplateOptions: ["missingkey=error"] generators: - - git: - repoURL: https://github.com/Countly/countly-deployment.git - revision: main - files: - - path: argocd/canaries/*/values.yaml + - matrix: + generators: + - git: + repoURL: https://github.com/Countly/countly-deployment.git + revision: main + files: + - path: customers/v2-new.yaml + pathParamPrefix: customer + - git: + repoURL: https://github.com/Countly/countly-deployment.git + revision: main + files: + - path: argocd/canaries/*/values.yaml template: metadata: name: 'canary-ui-{{ .path.basename }}' @@ -44,7 +51,7 @@ spec: app.kubernetes.io/component: canary-web-ui countly.io/canary: '{{ .path.basename }}' spec: - project: countly-customers + project: '{{ .project }}' sources: - repoURL: https://github.com/Countly/helm.git targetRevision: main @@ -63,7 +70,7 @@ spec: targetRevision: main ref: values destination: - server: https://34.62.8.139 + server: '{{ .server }}' namespace: countly syncPolicy: automated: