Files
devops-infra-helm-charts-gcp/skills/infra/onboard-app.md
T
2026-08-26 03:39:42 +05:30

204 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Skill — `onboard-app`
> **Layer:** Layer 1 — agent generates diff(s) and opens PR(s); humans review and Sync.
> **Scope:** the slice that lives in `devops-infra-helm-charts`. The matching Argo `Application` slice is in `github.com/Meesho/devops-infra-argo-config` and is paired but separate.
This skill is the agent-callable form of [docs/platform/procedures/onboard-app-to-cluster.md](../../docs/platform/procedures/onboard-app-to-cluster.md).
---
## When to use
Triggers like:
- "Onboard `<app>` to `<cluster>`."
- "Add a `kube-state-metrics` override for `k8s-foo-prd-ase1`."
- "Bring up `external-dns` on the new cluster."
Do **not** use this skill for:
- Adding a brand-new cluster (use the `onboard-new-cluster` procedure).
- Bumping a chart's version (use `bump-chart-version`).
- Migrating a chart blue-green (use the `blue-green-chart-migration` procedure directly).
---
## Input
Required:
```yaml
app: <chart-name> # must exist in helm-templates/
target_cluster: <cluster-folder> # must exist in helm-overrides/
release_name: <name> # often == app
workload_namespace: <ns> # the K8s namespace pods run in
image_tag: <tag> # NEVER 'latest'
resources:
cpu_request: <e.g. 250m>
memory_request: <e.g. 512Mi>
cpu_limit: <e.g. 1>
memory_limit: <e.g. 2Gi>
node_pool_key: <e.g. dedicated OR cloud.google.com/compute-class>
node_pool_value: <e.g. monitoring OR monitoring-cc>
```
Optional:
```yaml
needs_external_dns: <bool> # if true, add a Service to external-dns-services/
needs_external_secret: <bool> # if true, add an ExternalSecret to external-secrets/
needs_compute_class: <bool> # if true (Autopilot), add a ComputeClass under computeclass/
replicas: <N or autoscaling-block>
persistence:
enabled: <bool>
storage_class: <name> # MUST exist in manifests/storageclass/
size: <e.g. 100Gi>
```
---
## Steps (deterministic)
1. **Verify pre-conditions.**
```bash
ls helm-templates/<app>/Chart.yaml # chart exists
ls helm-overrides/<target_cluster>/ # cluster exists
! ls helm-overrides/<target_cluster>/<app>/ # app not already onboarded here
ls manifests/storageclass/<storage_class>.yaml # if persistence.enabled
```
2. **Read the cluster's scheduling profile.** Sample a sibling app on the **same** cluster:
```bash
ls helm-overrides/<target_cluster>/ | grep -v '^contour' | head -3
yq e '.nodeSelector' helm-overrides/<target_cluster>/<sibling>/custom-values.yaml
```
Confirm the agent's `node_pool_key` matches the cluster's actual style (`dedicated:` vs `cloud.google.com/compute-class:`). Mismatch → **fail fast** and ask.
3. **Generate `helm-overrides/<target_cluster>/<app>/custom-values.yaml`.** Use this template:
```yaml
image:
registry: asia-southeast1-docker.pkg.dev
repository: meesho-devops-admin-0622/admin/sre/<app>
tag: <image_tag>
pullPolicy: IfNotPresent
replicaCount: <replicas-or-omit-if-autoscaling>
resources:
requests:
cpu: <cpu_request>
memory: <memory_request>
limits:
cpu: <cpu_limit>
memory: <memory_limit>
nodeSelector:
<node_pool_key>: <node_pool_value>
tolerations:
- key: <node_pool_key>
value: <node_pool_value>
effect: NoSchedule
# if persistence.enabled
persistence:
enabled: true
storageClass: <storage_class>
size: <size>
accessModes: [ReadWriteOnce]
```
4. **(If `needs_external_dns: true`)** Generate `helm-overrides/<target_cluster>/<app>/external-dns-services/<svc>.yaml` per [raw-manifest-sidecar-schema.md §Service for external-dns binding](../../docs/platform/schemas/raw-manifest-sidecar-schema.md). Sample a sibling cluster's pattern.
5. **(If `needs_external_secret: true`)** Generate an `ExternalSecret` under `helm-overrides/<target_cluster>/external-secrets/`. Verify the cluster has a `SecretStore` / `ClusterSecretStore` (sample sibling apps' `existingSecret:` references).
6. **(If `needs_compute_class: true`)** Generate `helm-overrides/<target_cluster>/<app>/computeclass/<node_pool_value>.yaml`. The `metadata.name` MUST equal `<node_pool_value>`.
7. **Validate.**
```bash
yamllint helm-overrides/<target_cluster>/<app>/custom-values.yaml
helm template <release_name> helm-templates/<app> \
-f helm-overrides/<target_cluster>/<app>/custom-values.yaml > /dev/null
```
Render must succeed. If it errors, fail and surface the error.
8. **Open the PR.**
```bash
git checkout -b onboard/<app>-on-<target_cluster>
git add helm-overrides/<target_cluster>/<app>/
git commit -m "Onboard <app> to <target_cluster>"
git push origin onboard/<app>-on-<target_cluster>
gh pr create --base main --title "Onboard <app> to <target_cluster>"
```
PR body (use a heredoc):
```markdown
## Summary
Onboards `<app>` to `<target_cluster>`.
- Procedure: `docs/platform/procedures/onboard-app-to-cluster.md`
- Skill: `skills/infra/onboard-app.md`
- Sister-repo PR: <link to devops-infra-argo-config PR or "TBD">
## Validation
- `yamllint` passed
- `helm template` rendered cleanly
- Scheduling profile verified against sibling apps on `<target_cluster>`
## Approvers
- App owner: <handle>
- Cluster owner: <handle>
## CMR
<ticket or "n/a">
```
---
## Output
A single PR diff containing 13+ new files in this repo:
- `helm-overrides/<target_cluster>/<app>/custom-values.yaml`
- (optional) `helm-overrides/<target_cluster>/<app>/external-dns-services/<svc>.yaml`
- (optional) `helm-overrides/<target_cluster>/<app>/computeclass/<name>.yaml`
- (optional) `helm-overrides/<target_cluster>/external-secrets/<name>.yaml`
The skill does **not**:
- Open the sister-repo PR (separate skill / manual). It must be drafted by the user or a follow-up step.
- Run `argocd app sync` (Layer 1 boundary).
- Modify `helm-templates/<chart>/`.
- Modify `repository.yaml`.
---
## Pattern reference
A clean recent onboarding to compare against: pick any merged PR titled "Onboard ... to k8s-...". `git log --oneline --grep='Onboard' -i | head -10`.
---
## Gotchas
1. **Don't copy a sibling cluster's values verbatim** — per-cluster scheduling differs ([SANCTITY_RULES R5](../../docs/global/SANCTITY_RULES.md)).
2. **Don't set `automated.{prune,selfHeal}` in the sister-repo Application** ([ADR-A5](../../wiki/analyses/ADR-A5-manual-sync-default-for-infra.md)).
3. **Verify `image.tag`** is real before opening the PR — Argo CD only catches a missing tag at sync time.
4. **The release name (`metadata.name` of the resulting `Application`) is set in the sister repo, not here.** Don't assume it; verify with the user.
5. **For Contour**, always cross-reference [contour-nodeselector-tolerations-summary.md](../../contour-nodeselector-tolerations-summary.md) — the matrix is load-bearing.
---
## Layer constraint
Layer 1. Open the PR; do not merge it; do not Sync. Reviewer + sister-repo PR + Argo CD UI Sync click are the human gates.
---
## Related
- Procedure: [onboard-app-to-cluster.md](../../docs/platform/procedures/onboard-app-to-cluster.md).
- Schema: [custom-values-schema.md](../../docs/platform/schemas/custom-values-schema.md).
- Boundaries: [AGENT_BOUNDARIES.md](../../docs/global/AGENT_BOUNDARIES.md).