Lab C — Kiro onboarding (`add-app`)
Before this: promote-app map closed the Lab B deep dives a thin prompt inherits.
This lab proves the spine claim it owes: a thin prompt produces a compliant dual-overlay app.
Run the thin prompt
Section titled “Run the thin prompt”Do not hand-write the app. Start from empty apps/ in
jajera/kiro-eks-argocd-migration. Use the
eks-migration agent. Frames below are full IDE shots from the Lab C recording — not a montage.
Paste this thin prompt in Kiro
Amazon's agentic IDE — runs vibe or spec sessions against the factory's `.kiro/` steering, skills, and hooks.:
Add a web-service app named demo-nginx.Image: public.ecr.aws/nginx/nginx:1.27 (retag into our ECR as demo-nginx).No Secrets Manager. Egress: DNS + HTTPS as required for probes.Ingress: yes, hostname demo-nginx.dev.example.com on alb.Replicas: 2 in both overlays (so PDB minAvailable: 1 is valid).The Git-only hook allows kustomize
Kubernetes config tool that builds base + overlay trees into deployable manifests without templates. build (read-only) and blocks chat-side kubectl apply. A live ACCESS DENIED was not in this recording.
Git-only is prevention; Argo CD is the backstop
Section titled “Git-only is prevention; Argo CD is the backstop”The shell gate is the first line: see
block-infra-commands.kiro.hook.
It keeps the agent on Git-only paths (kustomize build, gator verify, local lint) and denies
mutating cluster or cloud commands from chat.
That is not the only safety net. This factory is GitOps
Operate the cluster from Git as the source of truth — changes land as PRs, then sync, not as ad-hoc kubectl.: Argo CD
GitOps continuous delivery controller that syncs Kubernetes manifests from Git into the cluster. reconciles the cluster to what is in Git after a human merges. An out-of-band kubectl apply that somehow reached the API would not become the lasting source of truth — the next sync brings the live object back in line with the repo (or surfaces drift for a human to fix). The hook stops the agent from creating that mess; Argo CD is why Git still wins if something else does.
What add-app actually creates
Section titled “What add-app actually creates”apps/ in
jajera/kiro-eks-argocd-migration holds
nothing but a .gitkeep until a reader runs this prompt — the demo-nginx tree in the frames
above is not checked into the repository, so this page cannot quote it as a system of record.
Run the thin prompt yourself against the eks-migration agent to get these files; copying YAML
off this page into a repo instead is not a substitute.
The add-app skill scaffolds this tree for a web-service archetype:
| File | Contents |
|---|---|
apps/demo-nginx/base/namespace.yaml |
Namespace with name/owner labels |
apps/demo-nginx/base/application.yaml |
Argo CD Application using profile defaults |
apps/demo-nginx/base/kustomization.yaml |
Lists the base resources |
apps/demo-nginx/base/manifests/deployment.yaml |
Deployment with probes, resource limits, rolling update strategy |
apps/demo-nginx/base/manifests/serviceaccount.yaml |
ServiceAccount for the workload |
apps/demo-nginx/base/manifests/networkpolicy.yaml |
default-deny-all plus DNS/HTTPS allow rules |
apps/demo-nginx/base/manifests/ingress.yaml |
ALB Ingress for the web-service archetype |
apps/demo-nginx/base/manifests/poddisruptionbudget.yaml |
PDB, only added because replicas >= 2 |
apps/demo-nginx/overlays/dev-eks-1/kustomization.yaml |
Overlay resources + patches for dev |
apps/demo-nginx/overlays/prod-eks-1/kustomization.yaml |
Overlay resources + patches for prod |
apps/demo-nginx/iam.tf |
IAM policy + Pod Identity association, skipped here since the prompt calls no AWS APIs |
apps/demo-nginx/README.md |
Required app README with a Mermaid inputs/outputs diagram |
See the full scaffold contract in
add-app.
The skill’s own validate step is what add-app runs before calling the scaffold done — this is
the exact command block the tables above and below are checked against:
Source: .kiro/skills/add-app/SKILL.md lines 107-113
kustomize build apps/<app>/basefor c in dev-eks-1 prod-eks-1; do kustomize build apps/<app>/overlays/$c kustomize build apps/<app>/overlays/$c/manifestsdoneterraform fmt -check apps/<app>npx --yes markdownlint-cli2 "apps/<app>/README.md"That block runs in order:
- Build the base tree alone, so a base-level error surfaces before either overlay is touched.
- Build both overlays and their
manifests/patches, dev then prod, so neither is skipped. - Check Terraform formatting on
iam.tfif the app has one. - Lint the required app README.
Checking the output against the archetype contract
Section titled “Checking the output against the archetype contract”The web-service archetype in the Workload archetypes map names
seven things a compliant app must
have. Each one traces to exactly one factory layer, not to the prompt:
| Contract item | Satisfied by | Supplying layer |
|---|---|---|
| Readiness probe | deployment.yaml container probes |
add-app skill, step 3 |
| Liveness probe | deployment.yaml container probes |
add-app skill, step 3 |
| Ingress present | ingress.yaml with the ALB class and hostname |
steering: workload-archetypes.md |
| NetworkPolicy present | networkpolicy.yaml with default-deny-all plus allows |
add-app skill, step 3 |
PDB valid at replicas: 2 |
poddisruptionbudget.yaml only added because replicas >= 2 |
hook: validate-app-scaffold |
| Placeholder image digest | Overlay patches pin <app>:<tag>@sha256:<digest> in the project ECR, never the upstream registry |
add-app skill, step 2 |
| Both overlays present | overlays/dev-eks-1/ and overlays/prod-eks-1/, never just one |
add-app skill, step 4 |
None of these seven came from the prompt. The prompt named the app, the image, and the hostname — the archetype contract, the file shape, and the PDB validity check all came from steering, the skill, and a hook.
Takeaway
Section titled “Takeaway”This was vibe coding
Thin natural-language session — short prompt, guardrails do the shaping; Lab C is the vibe case.: short prompt, no hand-authored manifests. Output still matched the platform contract because steering, add-app
Factory skill that scaffolds a dual-overlay app tree from a thin prompt (Lab C)., hooks, and the agent bundle did the heavy lifting. Humans still review before merge — this lab is the closing proof of skills generate → hooks enforce → humans approve. The shell gate keeps apply out of chat; Argo CD sync keeps Git authoritative on the cluster afterward.
Tradeoff
Section titled “Tradeoff”Choice: thin prompt plus hard guardrails. Alternative: a long prescriptive prompt that restates every factory rule. Reason: the .kiro/ map already encodes overlays, PDB
PodDisruptionBudget — limits voluntary disruptions; the factory scar requires replicas >= 2 when minAvailable is 1., and Git-only shell policy, so repeating them in chat adds noise without safety.
If add-app stops at the PDB step, see
Known scars: the PDB scar at replicas 1 — the same
rule enforced in the contract-check table above.
Next: Lab D (out of scope) — what the live path looks like after a human merges this app’s PR.