Files
devops-infra-helm-charts-gcp/docs/platform/procedures/onboard-app-to-cluster.md
T
2026-08-26 03:39:42 +05:30

7.2 KiB

Procedure — Onboard a new app to an existing cluster

Layer: Layer 1 — Agent-Writable. Blast radius: one new Helm release on one cluster. Approval: app owner + cluster owner.

This procedure adds a new infrastructure-tooling Helm release to a cluster that already exists in helm-overrides/. It covers the slice owned by devops-infra-helm-charts. The matching Argo Application lives in github.com/Meesho/devops-infra-argo-config and must be paired.


Inputs

Input Example
Chart name (must exist in helm-templates/) kube-state-metrics
Target cluster directory k8s-supply-prd-ase1
Release name kube-state-metrics (matches chart name; may be different for variants)
Workload namespace monitoring
Image tag v2.10.1
Sized resources (CPU/memory requests + limits) 250m / 512Mi
Node-pool key (per cluster) dedicated: monitoring
Whether this needs a sidecar external-dns Service yes / no

Pre-conditions

  • The chart exists in helm-templates/<chart>/ with a current Chart.yaml.
  • The cluster directory exists in helm-overrides/<cluster>/.
  • The chart is appropriate for an infra release (services don't go here — they live in devops-argo-config).
  • The matching sister-repo Application PR is drafted (or will be drafted in parallel).
  • CMR ticket open if required by BU policy.

Steps

1. Verify the chart renders with a sibling cluster's values

Pick a cluster that already runs this chart and use its values as a starting point:

sibling=$(find helm-overrides -maxdepth 2 -type d -name '<chart>' | head -1)
helm template <chart> helm-templates/<chart> -f "$sibling/custom-values.yaml" | head -60

If the render errors → the chart's dependencies may be unresolved. Run helm dependency update helm-templates/<chart> first.

2. Identify the cluster's scheduling profile

# Standard GKE: uses 'dedicated:' keys
grep -rh 'dedicated:' helm-overrides/<cluster>/*/custom-values.yaml | sort -u

# GKE Autopilot: uses 'cloud.google.com/compute-class' keys
grep -rh 'cloud.google.com/compute-class' helm-overrides/<cluster>/*/custom-values.yaml | sort -u

For Contour, cross-reference contour-nodeselector-tolerations-summary.md. For others, copy from a sibling app on the same cluster — never from the same app on a different cluster (SANCTITY_RULES R5).

3. Create the directory and custom-values.yaml

mkdir -p helm-overrides/<cluster>/<app>
$EDITOR helm-overrides/<cluster>/<app>/custom-values.yaml

Author from scratch using custom-values-schema.md and the cluster's scheduling profile from step 2. Do not copy a sibling cluster's values verbatim.

Skeleton:

image:
  registry: asia-southeast1-docker.pkg.dev
  repository: meesho-devops-admin-0622/admin/sre/<image>
  tag: <tag>

replicaCount: <N>

resources:
  requests: {cpu: <c>, memory: <m>}
  limits:   {cpu: <c>, memory: <m>}

nodeSelector:
  <pool-key>: <pool-value>
tolerations:
  - {key: <pool-key>, value: <pool-value>, effect: NoSchedule}

4. (If needed) Add sidecar raw manifests

If the app needs sidecar resources (e.g. external-dns Service, ComputeClass, ExternalSecret), drop them in the same directory under a subfolder:

helm-overrides/<cluster>/<app>/
  custom-values.yaml
  external-dns-services/<svc>.yaml
  computeclass/<name>-cc.yaml

See raw-manifest-sidecar-schema.md.

5. Validate locally

yamllint helm-overrides/<cluster>/<app>/custom-values.yaml

# Render
helm template <release> helm-templates/<chart> \
  -f helm-overrides/<cluster>/<app>/custom-values.yaml | head -60

# Optional: dry-run diff against the live cluster (requires kubectl context + helm-diff plugin)
helm diff upgrade <release> helm-templates/<chart> \
  -f helm-overrides/<cluster>/<app>/custom-values.yaml \
  --kube-context=<context>

6. Open the sister-repo PR

In github.com/Meesho/devops-infra-argo-config, draft an Application (or add to an existing ApplicationSet):

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: <release>-<cluster>
spec:
  destination:
    name: <cluster>
    namespace: <workload-namespace>
  source:
    repoURL: https://github.com/Meesho/devops-infra-helm-charts.git
    targetRevision: main
    path: helm-overrides/<cluster>/<app>
    helm:
      valueFiles: [custom-values.yaml]
  syncPolicy:
    syncOptions: [CreateNamespace=true]
    # Most infra apps DO NOT use automated sync — see ADR-A5

7. Open the values-side PR (this repo)

git checkout -b onboard/<chart>-on-<cluster>
git add helm-overrides/<cluster>/<app>/
git commit
# pre-commit hook runs TruffleHog
git push origin onboard/<chart>-on-<cluster>
gh pr create --base main --title "Onboard <chart> to <cluster>"

PR description:

  • Procedure followed: this file.
  • App owner approver tag.
  • Cluster owner approver tag.
  • Sister-repo PR link (devops-infra-argo-config#<n>).
  • CMR ticket reference (if applicable).
  • Confirmation that the chart renders cleanly and helm diff (if run) showed only additions.

8. After both merge — sync in Argo CD

devops-infra-argo-config's reconciler will create the Application resource on the cluster's Argo CD. Most infra apps are manual sync (ADR-A5), so the workload deploy is a separate step:

  1. Open the cluster's Argo CD UI.
  2. Search for the new Application.
  3. Verify the manifest renders (Diff view shows the chart's resources).
  4. Click Sync.
  5. Watch the rollout: kubectl --context=<context> get pods -n <ns> -w.

Anti-patterns

  1. Copying the entire helm-overrides/<sibling-cluster>/<app>/ directory verbatim. Per-cluster scheduling differs.
  2. Bundling onboarding with a chart-version bump. Two separate PRs.
  3. Skipping the sister-repo PR. Without an Application, the values do nothing.
  4. Setting automated.{prune,selfHeal}: true in the sister-repo Application "to make life easier." Manual sync is the default safety property.
  5. Inlining secrets in custom-values.yaml. Use ExternalSecret.

Rollback

If the merge causes a problem before Sync:

  • Revert the values-side PR (and the sister-repo PR).
  • Argo CD will prune the Application resource on next reconcile of the sister repo.

If Sync was clicked and the workload broke:

  • Click Rollback in Argo CD UI to the previous synced revision (if there is one).
  • Or revert both PRs and re-Sync — the previous state had no Application, so the workload is removed.