docs(P57): create phase plan — shell orchestrator lifecycle modes

PLAN stage. P57 adds --apply and --destroy modes to run_platform.sh.
The shell owns all terraform lifecycle; Python never runs terraform.

4 tasks: add flags + lifecycle branches, update usage header, add tests,
offline regression.

---ci---
project: acdl
phase: P57
milestone: v1.11
status: plan
---/ci---
This commit is contained in:
Jon Chery
2026-07-28 15:33:45 +00:00
parent 42354989bb
commit 5c1d5aaab5
+52 -75
View File
@@ -1,100 +1,77 @@
---
phase: P56b
name: l1-module-terraform-authoring
phase: P57
name: shell-orchestrator-lifecycle-modes
milestone: v1.11
requirements: [REQ-124]
requirements: [REQ-125]
wave: 1
depends_on: [P56a]
depends_on: [P56b]
---
# P56bAuthor 11 L1 Module Terraform Subdirs
# P57Shell Orchestrator Lifecycle Modes
**Phase:** P56b
**Phase:** P57
**Milestone:** v1.11 (RESTART)
**Requirement:** REQ-124
**Wave:** 1 (foundation — sequential prerequisite for P57P58)
**Branch:** `milestone/v1.11-restart``phase/p56b-l1-terraform`
**Requirement:** REQ-125
**Wave:** 1 (foundation)
**Branch:** `milestone/v1.11-restart``phase/p57-shell-lifecycle`
## Goal
Author the remaining 11 L1 module terraform subdirs (vpc, ecs-cluster,
ecs-service, iam-role, alb, ecr, cloudfront, waf, rds, kms-key, uptime)
with the full versions/variables/locals/main/outputs split. Defaults
currently hardcoded in the adapter move into locals.tf. Each module's
interface.json stays engine-agnostic. Add terraform_dir to each registry
entry.
Add `--apply` and `--destroy` modes to `scripts/run_platform.sh`. The shell
owns all terraform lifecycle; Python never runs terraform. The existing
`--plan-only` and `--check-only` modes are preserved unchanged.
## Module Classification
## Tasks (single wave)
**Single-resource modules** (simpler; may inline locals in main.tf):
- `kms-key` — aws_kms_key + alias
- `ecr` — aws_ecr_repository
- `ecs-cluster` — aws_ecs_cluster
- `iam-role` — aws_iam_role (+ inline policy defaults)
- `rds` — aws_db_instance
- `waf` — aws_wafv2_web_acl
- `uptime` — aws_ecs_service (uptime-kuma)
### Task 1 — Add --apply / --destroy flags + lifecycle modes
**Multi-resource modules** (full 5-file split with locals.tf):
- `vpc` — aws_vpc + aws_subnet + aws_route_table + igw (intra-refs)
- `ecs-service` — aws_ecs_task_definition + aws_ecs_service (intra-refs)
- `alb` — aws_lb + aws_lb_target_group + aws_lb_listener (intra-refs)
- `cloudfront` — aws_cloudfront_distribution + aws_cloudfront_origin_access_control (intra-refs)
Add `APPLY_ONLY=0` and `DESTROY_ONLY=0` to the arg parsing (lines 39-47).
Add `--apply` and `--destroy` cases to the arg loop (lines 58-76).
## Tasks (single wave — all modules are independent once the adapter is proven)
After the terraform init+validate+plan section (line 274-291), add two
new branches:
### Task 1 — Simple single-resource modules (data-engineer)
**--apply mode:**
- After terraform plan succeeds, run `terraform apply -auto-approve -lock=false`
against the emitted TF.
- For qa/prod/dr, the existing HITL gate (line 350-379) runs BEFORE apply.
- After apply, read terraform outputs and print them.
- Exit 0 with "PLATFORM APPLY OK".
Author terraform/ for: kms-key, ecr, ecs-cluster, rds, waf, uptime.
Each gets versions.tf + variables.tf + main.tf (with inlined locals or a
locals.tf) + outputs.tf. Defaults from the adapter move here.
**--destroy mode:**
- After terraform init+validate, run `terraform destroy -auto-approve -lock=false`.
- The `--decommission` flag + CR validation (D-070 two-step) gates destroy
when used with `--destroy --decommission <CR>`. Without `--decommission`,
`--destroy` is a direct destroy (for lifecycle testing, not production
teardown).
- Exit 0 with "PLATFORM DESTROY OK".
Key defaults to move:
- `kms-key`: enable_key_rotation=true, deletion_window_in_days=30 default
- `ecr`: encryption_configuration from kms_key_arn, image_scanning=true
- `ecs-cluster`: name default
- `rds`: storage_encrypted=true default, multi_az default, kms_key_arn
- `waf`: scope=cloudfront, default_action=allow, visibility_config, rules rendering
- `uptime`: Fargate compat, container_definitions from inputs
### Task 2 — Update usage header + mode docs
### Task 2 — iam-role module (data-engineer)
Update the script header (lines 1-26) to document the new modes:
- `--apply <contract.yml>` — resolve → adapter → terraform init/validate/plan/apply
- `--destroy <contract.yml>` — resolve → adapter → terraform init/validate/destroy
Author terraform/ for iam-role. The adapter previously hardcoded:
- assume_role_policy fallback (ECS task trust) — move to locals.tf
- inline ECR/logs policy when no managed_policies — move to locals.tf
- role_name default
### Task 3 — Add lifecycle mode tests
### Task 3 — Multi-resource modules with intra-refs (data-engineer)
Add tests to `tests/test_pipeline.py`:
- `test_run_platform_apply_mode_exists``run_platform.sh --apply` parses
without "unknown flag" error (offline smoke; doesn't actually apply).
- `test_run_platform_destroy_mode_exists``run_platform.sh --destroy` parses
without "unknown flag" error.
- `test_no_python_runs_terraform_apply` — grep assertion: no `.py` file in
scripts/ contains `terraform apply` or `terraform destroy`.
Author terraform/ for: vpc, ecs-service, alb, cloudfront.
Each has multiple resources with intra-refs (one resource references
another's output within the same module). The locals.tf centralizes:
- vpc: cidr_block default, subnet cidr derivation, route table defaults, IGW
- ecs-service: container_definitions jsonencode, Fargate compat, execution_role, network_config
- alb: listener default_action, target group vpc_id, port defaults
- cloudfront: origin block, default_cache_behavior, OAC defaults
### Task 4 — Offline regression
### Task 4 — Registry extension (backend-engineer)
Add terraform_dir to all 11 remaining registry entries.
### Task 5 — Validate all modules standalone (data-engineer)
Run `terraform init + validate` in each of the 12 terraform/ subdirs.
Fix any validation errors.
### Task 6 — Offline regression (backend-engineer)
- `pytest tests/ -m "not slow"` — all offline tests pass; the 6 P56b-skipped
tests should now unblock (static-assets contract resolves cloudfront/waf/s3).
- `bash scripts/run_primitive_plan.sh --check-only <module>` for each of the
12 modules — each exits 0.
- `pytest tests/ -m "not slow"` — all offline tests pass.
- `run_platform.sh --check-only` still works (no regression in existing modes).
## Success Criteria (phase gate)
1. All 12 L1 modules have a terraform/ subdir with the required files.
2. All 12 terraform/ subdirs pass `terraform init + validate` standalone.
3. All 12 registry entries have a terraform_dir field.
4. No defaults remain in the adapter (grep for hardcoded CIDR, assume_role_policy, etc.).
5. `pytest tests/ -m "not slow"` — 455+ passed, 0 skipped (the 6 P56b-skipped tests unblock).
6. `run_primitive_plan.sh --check-only <module>` exits 0 for all 12 modules.
1. `run_platform.sh --apply <contract>` and `--destroy <contract>` modes exist
and parse without "unknown flag" error.
2. `grep -rn "terraform apply\|terraform destroy" scripts/*.py` returns nothing
(Python never runs terraform lifecycle).
3. The existing `--check-only` and `--plan-only` modes still work (no regression).
4. `pytest tests/ -m "not slow"` — all pass.