Help us improve
Share bugs, ideas, or general feedback.
From arn-infra
Checks TTL sources (issue tracker, registry, manifest) for expired ephemeral infrastructure resources and destroys them after user confirmation with cost summary. Supports /loop for periodic monitoring.
npx claudepluginhub appsvortex/arness --plugin arn-infraHow this skill is triggered — by the user, by Claude, or both
Slash command
/arn-infra:arn-infra-cleanupThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Check for expired ephemeral infrastructure resources across three TTL sources (issue tracker, TTL registry, resource manifest) and destroy them with user confirmation. Supports periodic monitoring via `/loop` for session-duration TTL enforcement.
Enforces cloud operational hygiene: resource cleanup after migrations, cost attribution/tagging, monitoring/alerting defaults, Terraform drift detection, lifecycle policies for storage/artifacts.
Deploys infrastructure to staging or production using Terraform, Pulumi, CDK, Fly, or Railway. Enforces environment promotion, CI/CD checks, cost gates, safety layers, and resource tracking.
Automates dry-run cleanup of unused AWS resources like unattached EBS volumes, old snapshots, stopped EC2 instances, Elastic IPs, and S3 objects to reduce costs.
Share bugs, ideas, or general feedback.
Check for expired ephemeral infrastructure resources across three TTL sources (issue tracker, TTL registry, resource manifest) and destroy them with user confirmation. Supports periodic monitoring via /loop for session-duration TTL enforcement.
This skill never auto-destroys resources. Every destruction requires explicit user confirmation with a summary of what will be destroyed and its associated cost.
Read ## Arness from the project's CLAUDE.md. If no ## Arness section exists or Arness Infra fields are missing, inform the user: "Arness Infra is not configured for this project yet. Run /arn-infra-wizard to get started — it will set everything up automatically." Do not proceed without it.
Check the Deferred field. If Deferred: yes, inform the user: "Infrastructure is in deferred mode. Cleanup is not available until infrastructure is fully configured. Run /arn-infra-assess to un-defer." Stop.
Extract:
~/.arness/user-profile.yaml (or .claude/arness-profile.local.md if it exists — project override takes precedence). Apply the experience derivation mapping from ${CLAUDE_PLUGIN_ROOT}/skills/arn-infra-ensure-config/references/experience-derivation.md. If no profile exists, check for legacy Experience level in ## Arness as fallback.providers.mdenvironments.md for per-environment deployment stateactive-resources.json for resource inventorytooling-manifest.json for available CLIsCheck all three TTL sources in priority order. Collect a unified list of resources with expired or near-expiry TTLs.
Source 1: Issue Tracker (highest priority)
If issue tracking is configured (Platform is github or Issue tracker is jira):
For GitHub:
gh issue list --label "arn-infra-cleanup" --state open --json number,title,body,createdAt
For Jira:
Query issues with label arn-infra-cleanup in the configured Jira project.
Parse each cleanup issue:
arn-infra-deploy during ephemeral deployments)Source 2: TTL Registry (secondary)
Check for the TTL registry file:
Read .arness/infra/ttl-registry.md
If the file exists, parse resource entries with their TTL timestamps. The TTL registry is a fallback for environments without issue tracking or for resources created outside the normal deployment flow.
Expected format:
# TTL Registry
| Resource | Environment | Provider | Created | TTL Expiry | Destroy Command |
|----------|-------------|----------|---------|------------|-----------------|
| [name] | [env] | [provider] | [timestamp] | [expiry] | [command] |
Source 3: Resource Manifest (tertiary)
Read the resource manifest:
Read <resource-manifest-path>
Filter resources where:
ttl is not nullttl timestamp is in the past (expired)status is active (not already destroyed)Merge results from all three sources, deduplicating by resource ID. For each expired resource, compile:
monthly_cost × (hours_since_creation / 730))If no expired resources are found:
Present: "No expired resources found. All TTLs are current."
If there are resources with TTLs approaching expiry (within 1 hour), list them as early warnings: "The following resources will expire soon:
Stop here (or if running via /loop, wait for the next interval).
If expired resources are found:
Continue to Step 3.
Present each expired resource group (grouped by environment):
"The following resources have expired TTLs and are candidates for cleanup:
Environment: [env]
| Resource | Type | Provider | Expired | Cost Since Creation | Destroy Command |
|---|---|---|---|---|---|
| [name] | [type] | [provider] | [time since expiry] | $[amount] | [command] |
Total cost of expired resources: $[total] (estimated charges since TTL expired)
Ask (using AskUserQuestion):
"How would you like to handle the expired resources?"
Options:
NEVER auto-destroy without confirmation. Even when running via /loop, each cleanup cycle must ask for confirmation before destroying anything.
For each confirmed resource, execute the appropriate destroy command.
Read the local override or plugin default for
rollback-patterns.md.
Destroy commands by IaC tool:
| IaC Tool | Destroy Command |
|---|---|
| OpenTofu | tofu destroy -target=<resource> -var-file=environments/<env>.tfvars |
| Terraform | terraform destroy -target=<resource> -var-file=environments/<env>.tfvars |
| Pulumi | pulumi destroy --target <urn> --stack <env> --yes |
| CDK | cdk destroy --context env=<env> |
| Bicep | az resource delete --ids <resource-id> |
| kubectl | kubectl delete <resource-type> <name> -n <namespace> |
| Helm | helm uninstall <release> -n <namespace> |
| Fly.io | fly apps destroy <app-name> --yes |
| Railway | railway down or delete via dashboard |
| Vercel | vercel remove <project> --yes |
| Netlify | netlify sites:delete --id <site-id> |
| Render | Delete via Render dashboard |
For targeted IaC destruction (OpenTofu/Terraform):
When destroying specific resources from a larger state file, use -target to avoid destroying the entire environment:
tofu destroy -target=module.<module>.<resource_type>.<name> -var-file=environments/<env>.tfvars
For full environment teardown: If all resources in an environment are expired, offer full environment destruction:
tofu destroy -var-file=environments/<env>.tfvars
Important: Always ask for confirmation before executing destroy commands. Show the exact command that will be run.
After successful destruction:
5a. Update resource manifest:
status to destroyed for each destroyed resourcelastUpdated timestamp5b. Close/update cleanup issues: If the resource was tracked via an issue:
gh issue close <number> --comment "Resources destroyed by arn-infra-cleanup at [timestamp]."
5c. Update TTL registry:
If the resource was tracked in .arness/infra/ttl-registry.md, remove the entry or mark it as destroyed.
5d. Update Environments config: If all resources in an environment were destroyed (read from the Environments config path extracted in Prerequisites):
Last deployed: --, Pending changes: noneIf the user chose to extend TTL for some resources:
Ask: "How long would you like to extend the TTL? (e.g., 2h, 24h, 7d)"
For each selected resource:
ttl field in active-resources.jsonPresent: "TTL extended for [N] resources. New expiry: [timestamp]. The next cleanup check will re-evaluate these resources."
Present the cleanup summary:
"Cleanup Summary:
Files updated:
Remaining TTLs:
Periodic monitoring:
To automatically check for expired resources, use:
/loop 6h /arn-infra-cleanup
This will check TTLs every 6 hours during the current session and prompt for cleanup when resources expire."
This skill supports periodic execution via the /loop command:
/loop 6h /arn-infra-cleanup
When running in loop mode:
Recommended loop intervals:
## Arness config missing: Suggest running /arn-infra-wizard to get started. Stop./arn-infra-deploy (which creates cleanup issues) or manually add resources to .arness/infra/ttl-registry.md." Stop.destroyed in the manifest and close any associated cleanup issue. Inform the user: "[resource] was already destroyed (possibly manually or by another process)."destroyed in manifest). Closed issues are filtered out by the open-issues query.