Files
acdl/pipelines/modules-lifecycle.yml
T
Jon Chery 41c3377b96 feat(P67b): lifecycle tests default to plan-only; ACDL_LIFECYCLE_MODE flag overrides to full (REQ-134)
---
ci---
project: acdl
phase: 67b
milestone: v1.12
status: execute
---
/ci---

The modules-lifecycle pipeline now defaults to plan-only (fast, no AWS
mutation, no credentials, no cost) so it runs on every PR. A CI variable
ACDL_LIFECYCLE_MODE (workflow_dispatch input 'lifecycle_mode', default
'plan') overrides to 'full' for the real apply->modify->destroy against
live AWS.

Scripts: run_lifecycle_test.sh / run_lifecycle_destroy.sh /
run_l2_lifecycle_test.sh / run_l2_lifecycle_destroy.sh read the flag and
dispatch to --plan-only (plan mode) or --apply/--destroy (full mode).
Destroy is a no-op exit 0 in plan mode (nothing was applied). VPC-output
injection is gated on full mode.

Workflows: both .github + .gitea (byte-identical) expose lifecycle_mode
as a workflow_dispatch input (choice: plan/full), pass it via env:
ACDL_LIFECYCLE_MODE to every lifecycle step, skip ci-vpc-apply +
ci-vpc-destroy + Read-CI-VPC-outputs in plan mode, and run the lifecycle
+ l2-lifecycle jobs with if: always() so they execute (plan-only) even
when ci-vpc-apply is skipped.

Contract + schema: pipelines/modules-lifecycle.yml gains default_mode:
plan; the schema accepts default_mode (enum plan|full) and a richer
workflow_dispatch inputs shape.

Tests: 14 new tests in test_lifecycle_mode_flag.py (script dispatch) +
10 new tests in TestModulesLifecyclePipeline (workflow flag wiring,
byte-identity, plan-mode skips). Updated test_platform_vpc_destroy to
reflect the plan-mode skip. 516 tests pass; smoke-tested plan mode on
the s3 module (--plan-only green, no AWS apply).
2026-07-29 13:16:03 +00:00

88 lines
3.8 KiB
YAML

name: acdl-modules-lifecycle
# ACDL Modules Lifecycle Pipeline — apply→modify→destroy against live AWS.
#
# Matrix-runs each L1 module's examples/{simple,complex}.yml contracts:
# 1. --apply simple.yml (terraform apply — creates resources)
# 2. --apply complex.yml (same state key — terraform modifies)
# 3. --destroy complex.yml (terraform destroy — cleans up)
#
# No per-module Python. The "test" = the pipeline cell going green.
# VPC-dependent L1s (alb, ecs-service, rds, uptime) reference the platform
# VPC applied by a prerequisite job. Non-VPC L1s run independent.
#
# Lifecycle mode (REQ-134, v1.12): `default_mode: plan` — the lifecycle
# scripts run `run_platform.sh --plan-only` (fast, no AWS mutation, no
# AWS credentials, no cost) on every PR. Set the ACDL_LIFECYCLE_MODE CI
# variable (workflow_dispatch input `lifecycle_mode`) to `full` for the
# real apply→modify→destroy against live AWS. The CI VPC apply/destroy
# jobs are skipped in plan mode (nothing is applied).
#
# Both Gitea (.gitea/workflows/modules-lifecycle.yml) and GitHub
# (.github/workflows/modules-lifecycle.yml) implement this contract
# byte-identically.
triggers:
pull_request: [main]
workflow_dispatch:
inputs:
- name: lifecycle_mode
description: "Lifecycle mode: 'plan' (default, fast) or 'full' (real apply→destroy)"
default: plan
runner: ubuntu-latest
python_version: "3.12"
terraform_version: "1.9.*"
# Default lifecycle mode: "plan" (plan-only, fast, no AWS mutation) or "full"
# (real apply→modify→destroy against live AWS). Overridable via the
# ACDL_LIFECYCLE_MODE CI variable / workflow_dispatch input.
default_mode: plan
stages:
- name: platform-vpc-apply
command: cd terraform/platform && terraform init -input=false && terraform apply -auto-approve -lock=false
required: true
description: "Apply the shared platform VPC (prerequisite for VPC-dependent L1s)"
- name: lifecycle-apply
command: bash scripts/run_platform.sh --apply "modules/l1/${MODULE}/examples/simple.yml"
required: true
description: "Apply the module's simple example contract (terraform apply)"
- name: lifecycle-modify
command: bash scripts/run_platform.sh --apply "modules/l1/${MODULE}/examples/complex.yml"
required: true
description: "Apply the module's complex example (same state key — terraform modifies)"
- name: lifecycle-destroy
command: bash scripts/run_platform.sh --destroy "modules/l1/${MODULE}/examples/complex.yml"
required: true
description: "Destroy the module's resources (terraform destroy)"
- name: platform-vpc-destroy
command: cd terraform/platform && terraform destroy -auto-approve -lock=false
required: false
description: "Destroy the shared platform VPC (cleanup — runs even if lifecycle steps fail)"
# L2 lifecycle stages (composition modules)
- name: l2-lifecycle-apply
command: bash scripts/run_platform.sh --apply "modules/l2/${L2_MODULE}/examples/simple.yml"
required: true
description: "Apply the L2 module's simple example contract (terraform apply)"
- name: l2-lifecycle-modify
command: bash scripts/run_platform.sh --apply "modules/l2/${L2_MODULE}/examples/complex.yml"
required: true
description: "Apply the L2 module's complex example (same state key — terraform modifies)"
- name: l2-lifecycle-destroy
command: bash scripts/run_platform.sh --destroy "modules/l2/${L2_MODULE}/examples/complex.yml"
required: true
description: "Destroy the L2 module's resources (terraform destroy)"
matrix:
modules: [s3, kms-key, ecr, ecs-cluster, iam-role, cloudfront, waf, vpc, alb, ecs-service, rds, uptime]
vpc_dependent: [alb, ecs-service, rds, uptime]
independent: [s3, kms-key, ecr, ecs-cluster, iam-role, cloudfront, waf, vpc]
l2_modules: [static-assets, microservice]