Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 79e7a4a304 | |||
| 8ae307affc | |||
| 6e1a1bd7db | |||
| 040abc0fb7 |
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"phase": 0,
|
||||
"stage": "grill",
|
||||
"stage": "complete",
|
||||
"milestone": "v1.14",
|
||||
"phase_role": "pre_execution",
|
||||
"attempts": 0,
|
||||
"updated_at": "2026-07-29T20:25:00Z"
|
||||
"updated_at": "2026-07-29T20:30:00Z"
|
||||
}
|
||||
@@ -18,7 +18,11 @@
|
||||
{"from": "s3.outputs.bucket_regional_domain_name", "to": "cloudfront.inputs.bucket_regional_domain_name"},
|
||||
{"from": "waf.outputs.web_acl_arn", "to": "cloudfront.inputs.waf_web_acl_arn"},
|
||||
{"from": "contract.inputs.region", "to": "kms.inputs.region"},
|
||||
{"from": "kms.outputs.kms_key_arn", "to": "s3.inputs.kms_key_arn"}
|
||||
{"from": "kms.outputs.kms_key_arn", "to": "s3.inputs.kms_key_arn"},
|
||||
{"from": "contract.inputs.default_ttl", "to": "cloudfront.inputs.default_ttl"},
|
||||
{"from": "contract.inputs.max_ttl", "to": "cloudfront.inputs.max_ttl"},
|
||||
{"from": "contract.inputs.price_class", "to": "cloudfront.inputs.price_class"},
|
||||
{"from": "contract.inputs.viewer_protocol_policy", "to": "cloudfront.inputs.viewer_protocol_policy"}
|
||||
],
|
||||
"outputs": [
|
||||
{"from": "cloudfront.outputs.distribution_domain_name", "to": "stack.outputs.distribution_domain_name"},
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
# Complex static-assets deployment (S3 + CloudFront + WAF)
|
||||
# Modify variant: same bucket_name as simple (in-place modify, adds CDN + WAF)
|
||||
# Modify variant: same bucket_name as simple (in-place modify, tunes CDN
|
||||
# TTLs + price class + viewer protocol policy). The simple example uses
|
||||
# the cloudfront interface defaults (default_ttl=3600, max_ttl=86400,
|
||||
# PriceClass_100, redirect-to-https); this complex example sets explicit
|
||||
# non-default values so the lifecycle "modify" step exercises a real
|
||||
# terraform diff on the cloudfront distribution, not an idempotent
|
||||
# re-apply.
|
||||
environment: dev
|
||||
id: assets
|
||||
infrastructure:
|
||||
static-assets:
|
||||
inputs:
|
||||
bucket_name: my-static-site
|
||||
default_ttl: 3600
|
||||
max_ttl: 86400
|
||||
price_class: PriceClass_100
|
||||
default_ttl: 7200
|
||||
max_ttl: 172800
|
||||
price_class: PriceClass_200
|
||||
region: us-east-1
|
||||
viewer_protocol_policy: redirect-to-https
|
||||
waf_enabled: true
|
||||
viewer_protocol_policy: https-only
|
||||
version: 1.0.0
|
||||
name: static assets
|
||||
name: static assets
|
||||
@@ -1,11 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
# scripts/run_l2_lifecycle_destroy.sh — run a single L2 module lifecycle destroy.
|
||||
#
|
||||
# Usage: run_l2_lifecycle_destroy.sh <module> [ci-vpc-outputs.json]
|
||||
# Usage: run_l2_lifecycle_destroy.sh <module>
|
||||
#
|
||||
# Wraps run_platform.sh for L2 composition modules in the modules-lifecycle
|
||||
# pipeline. Sets ACDL_REMOTE_STATE_KEY to point to the CI VPC state.
|
||||
#
|
||||
# NOTE: unlike the L1 scripts (run_lifecycle_destroy.sh), the L2 path does
|
||||
# NOT take a ci-vpc-outputs.json argument. L2 compositions reference the
|
||||
# platform VPC via terraform_remote_state (a data source), not by injecting
|
||||
# VPC outputs into the contract. The workflow passes 2 positional args for
|
||||
# parity with the L1 matrix, but $2 is accepted-but-ignored here (documented,
|
||||
# not a bug).
|
||||
#
|
||||
# Lifecycle mode (REQ-134): ACDL_LIFECYCLE_MODE default "plan" = no-op
|
||||
# (plan mode never applies resources, so there is nothing to destroy).
|
||||
# Set to "full" for the real `--destroy` against live AWS.
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# scripts/run_l2_lifecycle_test.sh — run a single L2 module lifecycle apply/modify.
|
||||
#
|
||||
# Usage: run_l2_lifecycle_test.sh <module> <example> [ci-vpc-outputs.json]
|
||||
# Usage: run_l2_lifecycle_test.sh <module> <example>
|
||||
#
|
||||
# Wraps run_platform.sh for L2 composition modules in the modules-lifecycle
|
||||
# pipeline. Sets ACDL_REMOTE_STATE_KEY to point to the CI VPC state so the
|
||||
# microservice composition's terraform_remote_state data source reads from
|
||||
# the short-lived CI VPC (not the long-lived platform VPC).
|
||||
#
|
||||
# NOTE: unlike the L1 scripts (run_lifecycle_test.sh), the L2 path does NOT
|
||||
# take a ci-vpc-outputs.json argument. L2 compositions reference the platform
|
||||
# VPC via terraform_remote_state (a data source), not by injecting VPC
|
||||
# outputs into the contract. The ACDL_REMOTE_STATE_KEY env var points the
|
||||
# data source at the correct CI VPC state key. The workflow passes 3
|
||||
# positional args for parity with the L1 matrix, but $3 is accepted-but-
|
||||
# ignored here (documented, not a bug).
|
||||
#
|
||||
# Lifecycle mode (REQ-134): ACDL_LIFECYCLE_MODE default "plan" runs
|
||||
# `run_platform.sh --plan-only` (fast, no AWS mutation). Set to "full" for
|
||||
# the real `--apply` against live AWS.
|
||||
|
||||
+32
-1
@@ -330,4 +330,35 @@ class TestChildIdHelper:
|
||||
# ecs-service expands to service-task-definition + service-service
|
||||
assert _child_id(["service-task-definition", "service-service"]) == "service"
|
||||
# alb expands to alb-loadbalancer + alb-targetgroup + alb-listener
|
||||
assert _child_id(["alb-loadbalancer", "alb-targetgroup", "alb-listener"]) == "alb"
|
||||
assert _child_id(["alb-loadbalancer", "alb-targetgroup", "alb-listener"]) == "alb"
|
||||
|
||||
|
||||
class TestAdapterDedupRejectsUnregisteredModule:
|
||||
"""P1-1 (v1.14, REQ-135): a resource whose module is not in the
|
||||
registry must raise ValueError, not be silently dropped from the
|
||||
dedup merge. A typo'd module field (e.g. 'iam-role' vs 'iam_roles')
|
||||
must surface as a diagnostic, not vanish."""
|
||||
|
||||
def test_unregistered_module_raises_valueerror(self, tmp_path):
|
||||
stack = {
|
||||
"resources": [
|
||||
{"id": "bad", "type": "aws:bogus:thing", "module": "nonexistent@1.0.0", "inputs": {}}
|
||||
],
|
||||
"outputs": {},
|
||||
"data_sources": [],
|
||||
}
|
||||
with pytest.raises(ValueError, match="no terraform_dir for module 'nonexistent'"):
|
||||
adapt(stack, str(tmp_path))
|
||||
|
||||
def test_registered_module_still_works(self, tmp_path):
|
||||
"""A registered module (s3) must still emit valid terraform — the
|
||||
ValueError guard must not break the happy path."""
|
||||
stack = {
|
||||
"resources": [
|
||||
{"id": "s3", "type": "aws:s3:bucket", "module": "s3@1.0.0", "inputs": {"bucket_name": "test"}}
|
||||
],
|
||||
"outputs": {},
|
||||
"data_sources": [],
|
||||
}
|
||||
adapt(stack, str(tmp_path))
|
||||
assert (tmp_path / "main.tf").exists()
|
||||
Reference in New Issue
Block a user