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

7.5 KiB
Raw Blame History

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.


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:

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:

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.

    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:

    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:

    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. 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.

    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.

    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):

    ## 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).
  2. Don't set automated.{prune,selfHeal} in the sister-repo Application (ADR-A5).
  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 — 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.