feat(destroy-addons): graceful teardown for both providers + Crossplane deletion-ordering (consolidates #641, fixes #593/#34/#35/#36) - #830
Conversation
…troy kind-kro-ack's destroy deleted the hub cluster claim directly, which killed the on-hub ACK/KRO/Crossplane controllers and orphaned the AWS resources they managed (team IAM roles/policies, ALBs, DynamoDB, spoke clusters) -> redeploy conflicts on a reused account (EntityAlreadyExists, DuplicateLoadBalancerName, delivery-source ConflictException). - Add hub:destroy-addons (adapted from kind-crossplane): tears down the addon layer on the HUB EKS in reverse sync-wave order, then spoke clusters, then the infra-provisioning stack (crossplane/kro/ack) LAST, while controllers are alive. All-best-effort; no-op if the hub is already gone. Also satisfies the missing provider-contract task (#593). - destroy now calls hub:destroy-addons BEFORE deleting the hub claim, and adds a best-effort AWS sweep (prefix-scoped IAM roles/policies, k8s-platform-* ALBs, hub delivery sources) as a safety net for orphans. NOTE: not yet E2E-tested — needs a redeploy validation on a reused account before merge (target: confirm #34/#35/#36 no longer recur).
…b addons -> infra Per review: destroy must follow the reverse of provisioning. - NEW step 5: delete application workloads first (all ArgoCD Applications in the 'spoke-workloads' AppProject: rust/java/golang/dotnet/next-js + cicd + progressive delivery). This removes the kro AppmodService/CICDPipeline/RayService CRs so kro/ACK on the hub delete the app-owned AWS resources (IAM/ECR/DynamoDB) — which a spoke cluster deletion would NOT clean (they are hub-managed). - step 6: delete spoke clusters (now BEFORE hub addons). - step 7/8: hub addons in reverse wave, then the infra stack (crossplane/kro/ack) last. Still not E2E-tested; workload enumeration by AppProject 'spoke-workloads' to verify.
… kro-c1)
Read-only inspection of a live kro-c1 deployment surfaced 3 bugs in the initial
version:
- Workloads span multiple AppProjects (rust-project, java-project, cpu-ray-project,
spoke-workloads) not just spoke-workloads -> now delete all Applications whose
project is not 'default'/'platform'.
- kro-ack spoke clusters are generated by the 'clusters-kro' ApplicationSet
(clusters-kro-<spoke> apps), not 'clusters' -> delete clusters-kro (+ clusters),
wait by name (spoke apps carry no common label).
- ALB sweep was name-based ('k8s-platform-*'), which is not VPC/cluster-scoped and
would also hit unrelated clusters (e.g. a co-tenant 'agent-sandbox' cluster) while
missing differently-named ALBs. Now scoped by the elbv2.k8s.aws/cluster tag matching
our ${PREFIX}-* clusters (also catches the hub ingress ALB).
Still needs an E2E redeploy test on a reused account to confirm #34/#35/#36.
…wnerRef child detection (both providers) + Crossplane Usage deletion-ordering - kind-crossplane hub:destroy-addons: port #641 rewrite (dynamic AppSet discovery via kubectl + sync-wave sort, ownerReference-based child-app detection, skip finalizer/deletion waits when no children, agent-platform chain phase, drop ignore_error / use 2>&1 for visibility) - kind-kro-ack hub:destroy-addons: adopt the same dynamic-discovery + ownerReference technique (steps 7 & 8), keeping the ordered workloads->spokes->addons->infra->AWS-sweep teardown; drop the static registry-file ADDONS computation - platform-cluster composition: add 6 Usage resources (natgw-uses-eip, route-uses-igw, route-uses-natgw, rta-uses-rt, cluster-uses-subnets, cluster-uses-vpc) to enforce reverse deletion ordering and avoid orphaned EIP/NAT/VPC on teardown - add DELETION-ORDERING.md documenting the Usage fix Supersedes #641 (which targeted feature/agent-platform); adapted to the rc3 structure (abstractions/crossplane/platform-cluster path).
…list
Addresses the blocking review point: the destroy-time IAM sweep matched every
${PREFIX}-* role/policy by name, which on a reused/self-paced account could
delete the IDE execution role (*-team-stack-*/*SharedRole*, CFN-managed),
cluster/provider roles, and the #831 argo-rollouts roles.
Now a role/policy is swept only if it BOTH starts with the prefix AND carries an
ACK ownership tag (services.k8s.aws/*), and never if its name matches the
infra/bootstrap/CFN denylist. Also: renumber the duplicate step 8 (fleet-secrets
-> 9, leftover -> 10) and add a keep-in-sync note to INFRA_STACK.
|
Thanks for the thorough review — addressed the blocker in a9527e6. 🔴 #1 IAM sweep blast radius (fixed): the destroy-time sweep no longer matches roles/policies by name alone. A role/policy is now swept only if it BOTH starts with the prefix AND carries an ACK ownership tag ( 🟢 cosmetics (fixed): renumbered the duplicate step 8 (fleet-secrets → 9, leftover → 10); added a keep-in-sync note to Deferred (follow-ups, not blocking) — agree they're worth doing:
Still not E2E-tested (destructive teardown) — a full provision→destroy on a reused account is the real validation for #34/#35/#36. |
Code review — graceful teardown (kind-kro-ack / kind-crossplane) + Crossplane Usage deletion-orderingRead all 4 files and validated 3 points against Team 10's live hub (Crossplane v2.2.1). VerdictSolid, well-documented, structured and defensive (best-effort / idempotent). The teardown logic and the Usage approach are correct. One point to fix before merge (IAM sweep blast radius — now fixed, see below), a few medium robustness items, and minor nits. ✅ Strengths (verified)
🔴 Blocker — FIXED (a9527e6)The prefix-based IAM sweep was too broad. Deleting every 🟠 Medium (recommended follow-ups, not blocking)
🟢 Nits
TL;DRMergeable now that the IAM sweep is scoped (the only real risk). Points 2–5 are recommended robustness improvements; the rest is cosmetic. The Usage approach and teardown order are correct and compatible with the deployed Crossplane v2.2.1. |
Consistency with the kind-kro-ack sweep: the kind-crossplane destroy sweeps roles/policies by cluster-name prefix; add the DENY_RE denylist so it also skips the infra/bootstrap/CFN/provider/cluster roles and the #831 argo-rollouts roles (shared prefix but must survive teardown / a reused-account redeploy).
|
Applied the reviewer's consistency recommendation (a) in the latest commit: the kind-crossplane destroy sweep now carries the same |
…weep (#2/#3) #3: mirror the kind-crossplane agent-platform phase into kind-kro-ack so the AppSet is stopped (preserveResources) before its child apps are orphaned — otherwise agent-platform sat only in the step-7 SKIP and its AppSet would regenerate the workloads deleted in step 5. No-op when agent-platform is absent (the case on rc3); keeps the two providers symmetric. #2: add a prefix-scoped, ACK-tag-guarded ECR repository sweep to the destroy AWS net (repos named ${PREFIX}/<app>[/cache]). DynamoDB tables (arbitrary user-provided names, no deployment-scoping tag) are intentionally NOT swept to avoid the same blast-radius as #1; documented inline.
|
Follow-ups from the review addressed:
Remaining known trade-off: the strip-finalizers fallback can still orphan a stuck DynamoDB table on a hard timeout (by design, to not hang teardown) — surfaced, not swept. |
What
Graceful, ordered teardown for the redeploy issues (#593, #34/#35/#36), now consolidating #641 so #641 can be closed. Covers both cluster providers plus the Crossplane composition.
kind-kro-ackhub:destroy-addons(original #830, now upgraded)Ordered reverse-of-provision teardown so on-hub ACK/KRO/Crossplane controllers delete their managed AWS resources while still alive:
default/platformprojects) → 2. spoke clusters → 3. hub addons (reverse sync-wave, skip infra) → 4. infra stack LAST (crossplane/kro/ack-*) → AWS sweep net (prefix-scoped IAM roles/policies, ALBs scoped byelbv2.k8s.aws/clustertag, delivery sources).Now adopts fix(destroy-addons): dynamic addon discovery and composition deletion ordering #641's technique: dynamic AppSet discovery (kubectl, not static registry files) + ownerReference-based child-app detection + skip finalizer/deletion waits when no children (no more per-addon 30s/120s timeouts).
kind-crossplanehub:destroy-addons(ported from #641)Same rewrite: dynamic discovery + sync-wave sort, ownerReference child detection, agent-platform chain phase,
2>&1for error visibility, noignore_error.Crossplane composition — deletion ordering (from #641)
Adds 6
Usageresources (natgw-uses-eip,route-uses-igw,route-uses-natgw,rta-uses-rt,cluster-uses-subnets,cluster-uses-vpc) toabstractions/crossplane/platform-clusterso composed AWS resources delete in dependency order (avoids orphaned EIP/NAT/VPC). +DELETION-ORDERING.md.Relationship to #641
Supersedes #641 (which targeted
feature/agent-platformwith a divergentresource-groups/layout). Its changes are re-applied here adapted to the rc3 structure (abstractions/crossplane/platform-cluster). #641's core.yaml external-dns probes are already present on rc3; itsabstractions.yamlexclude is N/A to the rc3 layout — both intentionally omitted.Validation
public-rt(network) andaddon-vpc-cni(cluster).Targets
release/v0.3.0-rc3. Fixes #593, #34, #35, #36.