205 lines
7.2 KiB
Markdown
205 lines
7.2 KiB
Markdown
# 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:
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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](../../../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](../../global/SANCTITY_RULES.md)).
|
|
|
|
### 3. Create the directory and `custom-values.yaml`
|
|
|
|
```bash
|
|
mkdir -p helm-overrides/<cluster>/<app>
|
|
$EDITOR helm-overrides/<cluster>/<app>/custom-values.yaml
|
|
```
|
|
|
|
Author from scratch using [custom-values-schema.md](../schemas/custom-values-schema.md) and the cluster's scheduling profile from step 2. Do **not** copy a sibling cluster's values verbatim.
|
|
|
|
Skeleton:
|
|
|
|
```yaml
|
|
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](../schemas/raw-manifest-sidecar-schema.md).
|
|
|
|
### 5. Validate locally
|
|
|
|
```bash
|
|
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`):
|
|
|
|
```yaml
|
|
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)
|
|
|
|
```bash
|
|
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](../../../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md)), 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.
|
|
|
|
---
|
|
|
|
## Related
|
|
|
|
- Schema: [custom-values-schema.md](../schemas/custom-values-schema.md), [raw-manifest-sidecar-schema.md](../schemas/raw-manifest-sidecar-schema.md).
|
|
- Procedure: [update-chart-version.md](update-chart-version.md) for bumping after onboarding.
|
|
- Procedure: [deboard-app.md](deboard-app.md) for retirement.
|
|
- Skill: [skills/infra/onboard-app.md](../../../skills/infra/onboard-app.md) — agent-callable wrapper.
|
|
- ADR: [ADR-A3-per-cluster-scheduling.md](../../../wiki/analyses/ADR-A3-per-cluster-scheduling.md).
|