docs(P59): create phase plan — L1 module lifecycle pipeline (author)
PLAN stage. P59 authors the modules-lifecycle pipeline that matrix-tests
every L1 module's examples/{simple,complex}.yml contracts through
apply→modify→destroy against live AWS. No per-module Python.
5 tasks: declarative contract, byte-identical Gitea+GitHub workflows,
schema, tests, README update.
---ci---
project: acdl
phase: P59
milestone: v1.11
status: plan
---/ci---
This commit is contained in:
+67
-60
@@ -1,84 +1,91 @@
|
|||||||
---
|
---
|
||||||
phase: P58
|
phase: P59
|
||||||
name: single-platform-vpc-deterministic-state
|
name: l1-lifecycle-pipeline-author
|
||||||
milestone: v1.11
|
milestone: v1.11
|
||||||
requirements: [REQ-126]
|
requirements: [REQ-127]
|
||||||
wave: 1
|
wave: 2
|
||||||
depends_on: [P57]
|
depends_on: [P58]
|
||||||
---
|
---
|
||||||
|
|
||||||
# P58 — Single Platform VPC + Deterministic State Keys
|
# P59 — L1 Module Lifecycle Pipeline (Author)
|
||||||
|
|
||||||
**Phase:** P58
|
**Phase:** P59
|
||||||
**Milestone:** v1.11 (RESTART)
|
**Milestone:** v1.11 (RESTART)
|
||||||
**Requirement:** REQ-126
|
**Requirement:** REQ-127
|
||||||
**Wave:** 1 (foundation — the 4-VPC bug fix)
|
**Wave:** 2 (the testing milestone — author the pipeline, P60 runs it live)
|
||||||
**Branch:** `milestone/v1.11-restart` → `phase/p58-platform-vpc-state`
|
**Branch:** `milestone/v1.11-restart` → `phase/p59-l1-lifecycle-pipeline`
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
1. Add a single shared VPC to `terraform/platform/main.tf` (VPC + 2 subnets +
|
Author the `modules-lifecycle` pipeline that matrix-tests every L1 module's
|
||||||
IGW + route table + ECS security group). Output vpc_id, subnet_ids,
|
lifecycle via its own `examples/{simple,complex}.yml` contracts through
|
||||||
ecs_security_group_id.
|
apply→modify→destroy against live AWS. No per-module Python. The "test" =
|
||||||
2. Drop the `vpc` child from the microservice composition; reference the
|
the pipeline cell going green.
|
||||||
platform VPC via a `data_sources` block. The alb + service children wire
|
|
||||||
to the platform VPC, not an inline VPC.
|
|
||||||
3. Fix the state key to be env-aware: `spike/{stack_name}/{environment}/terraform.tfstate`.
|
|
||||||
Same contract+env always hits the same state key → terraform modifies,
|
|
||||||
never duplicates.
|
|
||||||
4. The adapter emits `data "terraform_remote_state" "platform"` + `data "aws_vpc"`
|
|
||||||
blocks when a stack references platform-owned resources.
|
|
||||||
|
|
||||||
## Tasks (single wave)
|
## Tasks (single wave)
|
||||||
|
|
||||||
### Task 1 — Platform VPC in terraform/platform/main.tf (data-engineer)
|
### Task 1 — pipelines/modules-lifecycle.yml (declarative contract)
|
||||||
|
|
||||||
Add to `terraform/platform/main.tf`:
|
Author the declarative pipeline contract:
|
||||||
- `aws_vpc.acdl_shared` (10.0.0.0/16)
|
```yaml
|
||||||
- 2 `aws_subnet` across 2 AZs (10.0.1.0/24, 10.0.2.0/24)
|
name: acdl-modules-lifecycle
|
||||||
- `aws_internet_gateway` + `aws_route_table` + associations
|
triggers:
|
||||||
- `aws_security_group.ecs` (ingress on port 80, egress all)
|
pull_request: [main]
|
||||||
- Outputs: `vpc_id`, `subnet_ids` (comma-separated), `ecs_security_group_id`
|
workflow_dispatch: []
|
||||||
|
runner: ubuntu-latest
|
||||||
|
python_version: "3.12"
|
||||||
|
stages:
|
||||||
|
- name: validate-contract
|
||||||
|
command: python3 -c "import yaml,json; c=yaml.safe_load(open('$CONTRACT')); assert c['id']"
|
||||||
|
required: true
|
||||||
|
- name: resolve-stack
|
||||||
|
command: python3 core/contract_resolver.py "$CONTRACT" /tmp/lifecycle-stack.json
|
||||||
|
required: true
|
||||||
|
- name: terraform-apply
|
||||||
|
command: bash scripts/run_platform.sh --apply "$CONTRACT"
|
||||||
|
required: true
|
||||||
|
- name: terraform-modify
|
||||||
|
command: bash scripts/run_platform.sh --apply "$CONTRACT_COMPLEX"
|
||||||
|
required: true
|
||||||
|
- name: terraform-destroy
|
||||||
|
command: bash scripts/run_platform.sh --destroy "$CONTRACT_COMPLEX"
|
||||||
|
required: true
|
||||||
|
```
|
||||||
|
|
||||||
### Task 2 — Microservice composition: drop vpc, add data_sources (backend-engineer)
|
### Task 2 — .gitea/workflows/modules-lifecycle.yml + .github/workflows/modules-lifecycle.yml
|
||||||
|
|
||||||
Update `modules/l2/microservice/composition.json`:
|
Byte-identical workflows. Matrix over 12 L1 modules × {simple, complex}.
|
||||||
- Remove `{"id": "vpc", "module": "vpc@1.0.0"}` from children.
|
Each cell:
|
||||||
- Add a `data_sources` block: `{"name": "platform_vpc", "type": "terraform_remote_state", "source": "platform"}`.
|
- Checkout + Python 3.12 + Terraform 1.9.* + AWS creds (from secrets).
|
||||||
- Update wires: `vpc.outputs.subnet_ids` → `platform_vpc.outputs.subnet_ids`.
|
- `run_platform.sh --apply modules/l1/<module>/examples/simple.yml`
|
||||||
- Add a wire for `platform_vpc.outputs.vpc_id` → `alb.inputs.vpc_id`.
|
- `run_platform.sh --apply modules/l1/<module>/examples/complex.yml` (same state key → terraform modifies)
|
||||||
- Add a wire for `platform_vpc.outputs.ecs_security_group_id` → `service.inputs.security_group`.
|
- `run_platform.sh --destroy modules/l1/<module>/examples/complex.yml`
|
||||||
|
|
||||||
### Task 3 — Contract resolver: pass environment + handle data_sources (backend-engineer)
|
VPC-dependent L1s (alb, ecs-service, rds, uptime) reference the platform VPC
|
||||||
|
applied by a prerequisite job; standalone vpc L1 applies its own. Non-VPC
|
||||||
|
L1s (s3, kms-key, ecr, iam-role, ecs-cluster, cloudfront, waf) run independent.
|
||||||
|
|
||||||
Update `core/contract_resolver.py`:
|
### Task 3 — schemas/modules-lifecycle-pipeline.schema.json
|
||||||
- Add `"environment": env_name` to the stack instance's `stack` block (line 568-572).
|
|
||||||
- Handle `data_sources` in the composition: resolve data source references to
|
|
||||||
stack-level pseudo-resources that the adapter can emit as `data` blocks.
|
|
||||||
|
|
||||||
### Task 4 — Adapter: env-aware state key + data block emission (backend-engineer)
|
Schema for the new pipeline shape (extends pipeline.schema.json with
|
||||||
|
workflow_dispatch trigger + matrix stages).
|
||||||
|
|
||||||
Update `adapters/terraform/adapter.py`:
|
### Task 4 — Extend tests/test_pipeline_contract.py
|
||||||
- State key: `spike/{stack_name}/{environment}/terraform.tfstate` (read
|
|
||||||
environment from `stack_instance["stack"]["environment"]`).
|
|
||||||
- When a resource input references a platform data source (e.g.
|
|
||||||
`ref:platform_vpc.subnet_ids`), emit a `data "terraform_remote_state" "platform"`
|
|
||||||
block + pass the data source output as the module argument.
|
|
||||||
|
|
||||||
### Task 5 — Tests + offline regression
|
Add a TestModulesLifecyclePipeline class:
|
||||||
|
- Schema validates.
|
||||||
|
- Gitea + GitHub workflows are byte-identical.
|
||||||
|
- Matrix lists all 12 L1 modules.
|
||||||
|
- Pipeline contract validates against the new schema.
|
||||||
|
|
||||||
- Update `tests/test_adapter.py`: assert the state key is env-aware.
|
### Task 5 — Extend pipelines/README.md
|
||||||
- Update `tests/test_pipeline.py`: the microservice contract now resolves
|
|
||||||
without a vpc resource.
|
Add the modules-lifecycle pipeline to the table.
|
||||||
- `pytest tests/ -m "not slow"` — all pass.
|
|
||||||
- `run_platform.sh --check-only contracts/microservice.yml` — exits 0.
|
|
||||||
|
|
||||||
## Success Criteria (phase gate)
|
## Success Criteria (phase gate)
|
||||||
|
|
||||||
1. `terraform/platform/main.tf` has a VPC + subnets + IGW + route table + SG.
|
1. `pipelines/modules-lifecycle.yml` validates against its schema.
|
||||||
2. `contracts/microservice.yml` resolution produces NO `aws:ec2:vpc` resource.
|
2. `.gitea/workflows/modules-lifecycle.yml` and `.github/workflows/modules-lifecycle.yml` are byte-identical.
|
||||||
3. Two contract applies (dev + prod) → ONE VPC, two state keys
|
3. Matrix lists all 12 L1 modules.
|
||||||
(`spike/msvc/dev/`, `spike/msvc/prod/`), two ECS services.
|
4. `test_pipeline_contract.py` passes (offline).
|
||||||
4. Same contract+env re-applied → same state key → terraform modifies, never duplicates.
|
5. Full offline pytest suite green.
|
||||||
5. `pytest tests/ -m "not slow"` — all pass.
|
|
||||||
6. `run_platform.sh --check-only contracts/microservice.yml` — exits 0.
|
|
||||||
Reference in New Issue
Block a user