Use this skill for a Helm-upgrade deploy of an app service (the web portal or the edge service) to an EXISTING Kubernetes cluster, plus post-deploy verification. NOT for cluster-level ops -- Minikube/k3s lifecycle, GCP firewall, tunnels, bootstrap secrets (use kubernetes-deployment); NOT for cross-environment promotion (use release-promotion).
Scanned 9/5/2026
Install to Claude Code
npx -y skills add atretyak1985/swarmery --skill deployment --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Deployment?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/atretyak1985-deployment)More formats (shields.io, HTML) on the badges page.
---
name: deployment
description: "Use this skill for a Helm-upgrade deploy of an app service (the web portal or the edge service) to an EXISTING Kubernetes cluster, plus post-deploy verification. NOT for cluster-level ops -- Minikube/k3s lifecycle, GCP firewall, tunnels, bootstrap secrets (use kubernetes-deployment); NOT for cross-environment promotion (use release-promotion)."
version: "1.0.0"
owner: "swarmery-infra"
docs:
status: reviewed
source_sha: 4112200c69a3
updated: 2026-08-06
---
# Purpose
Orchestrate the project's service deployments across local-dev (Minikube), the staging environment (project.json → cloud.envAlias; typically a cloud VM + Minikube), and production (e.g. edge device + k3s) using Helm, producing a deploy status report with pod health and endpoint verification. This skill covers the single-environment deploy-and-verify cycle; it defers image building to `docker-build`, chart template authoring to `helm-chart-expert`, and cross-environment promotion to `release-promotion`.
# When to use this skill
- Trigger A -- Deploying a Helm release to any single project environment
- Trigger B -- Running post-deployment verification (pod health, endpoint checks, ingress validation)
- Trigger C -- Rolling back a failed Helm release within the same environment
- Trigger D -- Inspecting current deploy state (helm list, helm history, pod status)
# When NOT to use this skill
- Anti-trigger A -- Building or pushing Docker images -> use `docker-build` instead
- Anti-trigger B -- Writing or modifying Helm chart templates -> use `helm-chart-expert` instead
- Anti-trigger C -- CI/CD pipeline configuration -> use `gitlab-ci-cd` instead
- Anti-trigger D -- Production deploy without an approved merge request -> stop and escalate
- Anti-trigger E -- Staging-environment operational recovery (SSH debugging, secret rotation, VM recovery) -> follow the project's environment runbooks; cluster-level pieces belong to `kubernetes-deployment`
- Anti-trigger F -- Promoting an image across environments (dev -> staging -> production) -> use `release-promotion` instead
- Anti-trigger G -- Cluster-level infrastructure ops (Minikube management, GCP firewall, tunnel debugging) -> use `kubernetes-deployment` instead
# Required environment
- Runtime mount: `.claude/skills/deployment/SKILL.md`
- Tools / libraries: `helm` (v3+), `kubectl`, `gcloud` CLI, SSH access (for staging/production)
- Bundled resources:
- `.claude/skills/deployment/scripts/deploy-checklist.sh` -- pre-deploy validation
- `.claude/skills/deployment/resources/environments.md` -- environment coordinates
- Reversibility profile: hard-to-reverse -- confirm before applying to shared clusters; `helm rollback` can revert but causes pod disruption
# Inputs
- `environment: "localdev" | "<envAlias>" | "production"` -- target environment (staging alias from project.json → cloud.envAlias)
- `chart_path: string` -- path to the Helm chart (e.g., `charts/<app>/`)
- `values_file: string` -- environment-specific values file (e.g., `values.localdev.yaml`)
- `image_tag: string` -- the image tag to deploy (git short hash or semver)
# Outputs
- Format: Deploy status report inlined in agent response
- Length budget: max 30 lines for the status report; verbose pod logs or dry-run diffs go in a collapsible block
- Output template:
```
Deploy: {chart} -> {environment}
Image: {registry}/{image}:{tag}
Helm revision: {N}
Pod status: {count} Running, {count} other
Health endpoint: {status code}
Audit trail: {updated | skipped (localdev)}
```
# Procedure
1. **Validate prerequisites** -- Confirm GCP auth (`gcloud auth print-access-token`), kubectl cluster access (`kubectl get nodes`), and image existence in registry (`gcloud artifacts docker images describe $IMAGE_REGISTRY/$IMAGE:$TAG`). Use `$IMAGE_REGISTRY` environment variable for the registry URL (do not hardcode GCP project IDs). Checkpoint: All three checks pass. If any fails, stop and report which prerequisite is missing.
2. **Run pre-deploy checklist** -- Execute `.claude/skills/deployment/scripts/deploy-checklist.sh <image-name> <image-tag> <chart-path>` to validate chart lint, template render, and image availability. Checkpoint: Script exits 0.
3. **Dry-run first** -- Always run `helm upgrade --install --dry-run` (or the chart repo's environment wrapper with its dry-run flag, if one exists) before the live deploy. Review the rendered manifests for stop conditions.
```bash
# Local dev
helm upgrade --install <release> charts/<app>/ -f charts/<app>/values.localdev.yaml --dry-run
# Staging (<envAlias>)
ssh <staging-host> "cd <chart-repo> && helm upgrade --install <release> charts/<app>/ -f charts/<app>/values.<envAlias>.yaml --dry-run"
```
Checkpoint: Dry-run output reviewed. STOP if any of these appear: `kind: PersistentVolumeClaim` being deleted, replica count decrease >50%, resource limits removed entirely, namespace change, or `kind: ServiceAccount` deleted. Otherwise proceed.
4. **Run helm diff** -- If `helm-diff` plugin is available, run `helm diff upgrade` to see a colored diff of what will change. Checkpoint: Diff reviewed and accepted by the operator.
5. **Deploy** -- Execute the live deploy command. Side effect: This modifies the target Kubernetes cluster. The Helm release revision increments.
```bash
# Local dev
helm upgrade --install <release> charts/<app>/ -f charts/<app>/values.localdev.yaml
# Staging (<envAlias>)
ssh <staging-host> "cd <chart-repo> && helm upgrade --install <release> charts/<app>/ -f charts/<app>/values.<envAlias>.yaml"
```
Checkpoint: `helm history` shows the new revision with status `deployed`.
6. **Post-deploy verification** -- Run all checks:
- `kubectl get pods -n <namespace>` -- all pods in Running state within 120 seconds
- `curl http://<endpoint>/api/health` -- returns HTTP 200
- `kubectl get ingress -A` -- ingress routes match expected hostnames
Checkpoint: All pods Running, health endpoint returns 200, ingress routes correct.
7. **Update audit trail** -- After a successful staging or production deploy, update the version-pinning repo, if the project uses one (project.json → repos), via a commit or MR. Fields to update: `image_tag`, `chart_version`, `deployed_at` (ISO 8601 timestamp), `helm_revision`. This is not optional for shared environments. Checkpoint: Version file committed or MR opened.
### Environments Reference
| Environment | Infra | Namespace | Access |
|-------------|-------|-----------|--------|
| localdev | Minikube | `<app-namespace>` | `*.<localdev-host>` via /etc/hosts |
| `<envAlias>` (staging) | Cloud VM + Minikube | `<app-namespace>` | SSH tunnel |
| production | Edge device + k3s (or managed cluster) | `<app-namespace>` | Direct |
### Service Ports (localdev)
| Service | Domain | Port |
|---------|--------|------|
| Web portal | `<localdev-host>` | 80 |
| Device N | `dN.<localdev-host>` | 80 |
| Keycloak | `keycloak.<localdev-host>` | 80 |
| PgAdmin | `pgadmin.<localdev-host>` | 80 |
# Self-check before returning
- [ ] Every file cited has been read; no claim references an unopened file.
- [ ] Output matches the format above.
- [ ] Uncertain claims tagged `[LOW-CONFIDENCE]`.
- [ ] No hardcoded paths or environment-specific values leaked.
- [ ] Pre-deploy checklist script was run and exited 0.
- [ ] `helm upgrade --dry-run` was executed before the live deploy.
- [ ] No `NEXT_PUBLIC_*` variables were passed as `--build-arg` (build-time bake violates 12-factor; use `window.__ENV__` runtime bridge).
- [ ] Registry URL used `$IMAGE_REGISTRY` variable, not a hardcoded GCP project ID.
- [ ] All pods in target namespace are Running.
- [ ] Health endpoint returned HTTP 200.
- [ ] Version-pinning audit trail was updated (staging/production only, if the project uses one).
- [ ] No `--push` command was run without the operator understanding it writes to the shared registry.
# Common mistakes to avoid
- DO NOT use `NEXT_PUBLIC_*` as Docker `--build-arg` -- this bakes environment-specific values into the image, violating 12-factor build-once/deploy-anywhere. Use the `window.__ENV__` runtime bridge pattern instead (server renders `<script>window.__ENV__={...}</script>`, client reads from `window.__ENV__`).
- DO NOT hardcode GCP project IDs in commands -- use the `$IMAGE_REGISTRY` variable.
- DO NOT run the live deploy before the dry-run -- always `--dry-run` first.
- DO NOT skip `helm dependency update` after modifying subchart Chart.yaml versions.
- DO NOT run `--push` to the shared registry without confirming the intended tag -- pushes are not easily reversible.
- DO NOT deploy to production without an approved merge request.
- DO NOT use `latest` tag in any environment.
- DO NOT confuse this skill with `release-promotion` -- this skill deploys to one environment; `release-promotion` manages the digest handoff across environments.
# Escalation
- Stop and ask when: Target is production and there is no approved MR.
- Stop and ask when: Dry-run shows any stop condition (PVC deletion, replica decrease >50%, resource limits removed, namespace change).
- Stop and ask when: Post-deploy verification fails after 2 retry cycles (pods not Running, health endpoint not responding).
- Stop and ask when: The image tag does not exist in the registry.
- Refuse and explain when: Asked to deploy to production without confirmed approved MR URL. Required: operator must provide the MR URL before the skill proceeds with production deploy commands.
<examples>
<example>
<user_task>Deploy the web portal to localdev after a new feature merge</user_task>
<procedure_trace>
Step 1: Validate prerequisites
gcloud auth print-access-token > /dev/null 2>&1 # Auth valid
kubectl get nodes # Cluster accessible
Step 2: Pre-deploy checklist
.claude/skills/deployment/scripts/deploy-checklist.sh <main-app> abc1234 charts/<app>/
Step 3: Dry-run
helm upgrade --install <release> charts/<app>/ -f charts/<app>/values.localdev.yaml --dry-run
# Reviewed: no PVC deletions, no replica decreases, no namespace changes.
Step 4: Deploy
helm upgrade --install <release> charts/<app>/ -f charts/<app>/values.localdev.yaml
Step 5: Verify
kubectl get pods -n <app-namespace>
# NAME READY STATUS RESTARTS
# <release>-<app>-7b9f8c6d4-x2k9m 1/1 Running 0
curl http://<localdev-host>/api/health
# {"status":"ok"}
</procedure_trace>
<output>
Deploy: <app> -> localdev
Image: $IMAGE_REGISTRY/<main-app>:abc1234
Helm revision: 12
Pod status: 1 Running
Health endpoint: 200 OK
Audit trail: skipped (localdev)
</output>
</example>
</examples>
# Failure modes
- Mode: ImagePullBackOff -- symptom: pod stuck in ImagePullBackOff -- detection: `kubectl describe pod` shows auth error -- action: re-authenticate with `gcloud auth login && gcloud auth configure-docker <region>-docker.pkg.dev`, then regenerate the registry pull secret via the chart repo's docker-secret helper script
- Mode: Stale subchart -- symptom: Helm chart changes not applied after deploy -- detection: `helm template` output does not include expected changes -- action: bump version in subchart `Chart.yaml`, bump dependency version in parent `Chart.yaml`, run `helm dependency update charts/<app>/`
- Mode: CrashLoopBackOff -- symptom: pod restarts repeatedly -- detection: `kubectl logs -n <ns> <pod> --previous` shows error -- action: check for missing env vars in values.yaml, wrong image tag, or failing health probe
- Mode: Rollback needed -- symptom: deploy succeeded but application is broken -- detection: health endpoint returns non-200 or telemetry not flowing -- action: `helm rollback <release> <revision> -n <namespace>`, then update the version-pinning repo (if the project uses one)
# Related skills
- `docker-build` -- defer to docker-build for image creation; deployment consumes the built image
- `helm-chart-expert` -- defer to helm-chart-expert for chart template modifications; compose when a deploy failure traces to a template bug
- `gitlab-ci-cd` -- defer to gitlab-ci-cd for pipeline configuration; deployment is the runtime execution
- `release-promotion` -- defer to release-promotion for cross-environment digest promotion; deployment handles the single-environment Helm upgrade that release-promotion orchestrates
- `kubernetes-deployment` -- defer to kubernetes-deployment for cluster-level infrastructure (Minikube management, firewall rules, tunnel debugging)
# How to use
## What it does
This skill runs one Helm deploy against one Kubernetes cluster that already exists, then proves the deploy worked. It walks you through prerequisite checks, a mandatory dry-run, the live `helm upgrade --install`, pod and health-endpoint verification, and the audit-trail update for shared environments. You end up with a short status report instead of a pile of raw `kubectl` output.
## When to use it
- You want to ship a built image to local dev, staging, or production and confirm it came up healthy.
- A deploy already happened and you need post-deploy verification: pod health, health endpoint, ingress routes.
- A release went bad in one environment and you need `helm rollback` plus the follow-up audit update.
- You want to read the current state of a release — `helm list`, `helm history`, pod status.
## When not to use it
- Building or pushing the image itself — use the `docker-build` skill.
- Editing chart templates or values structure — use the `helm-chart-expert` skill.
- Moving an image digest across environments — use the `release-promotion` skill.
- Cluster-level work such as Minikube lifecycle, firewall rules, or tunnels — use the `kubernetes-deployment` skill.
## How to invoke
```
Skill(skill: "infra-pack:deployment")
```
Invoke it, then say which environment, chart, values file, and image tag you are deploying.
## Inputs
- `environment` — `localdev`, your staging alias, or `production` — required.
- `chart_path` — path to the Helm chart, e.g. `charts/<app>/` — required.
- `values_file` — the environment values file, e.g. `values.localdev.yaml` — required.
- `image_tag` — a git short hash or semver; never `latest` — required.
## What you get back
A status report of at most 30 lines in the reply: chart and target environment, the deployed image reference, the new Helm revision, pod counts by state, the health-endpoint status code, and whether the audit trail was updated or skipped. Verbose logs and dry-run diffs stay in a collapsible block. Side effects are real: the cluster changes and the Helm revision increments.
## Worked example
```
Skill(skill: "infra-pack:deployment")
Deploy the web portal to localdev at image tag abc1234, chart charts/<app>/.
→ auth + cluster + registry checks pass
→ pre-deploy checklist script exits 0
→ helm upgrade --dry-run reviewed: no PVC deletion, no replica drop
→ helm upgrade --install runs; history shows revision 12 deployed
→ 1/1 pod Running, /api/health returns 200
Deploy: <app> -> localdev
Image: $IMAGE_REGISTRY/<main-app>:abc1234
Helm revision: 12
Pod status: 1 Running
Health endpoint: 200 OK
Audit trail: skipped (localdev)
```
## Related
- `docker-build` — build and push the image before you deploy it.
- `helm-chart-expert` — change chart templates when a deploy failure traces to one.
- `release-promotion` — promote a digest from one environment to the next.
- `kubernetes-deployment` — cluster-level infrastructure rather than a single release.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!