Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 79e7a4a304 | |||
| 8ae307affc | |||
| 6e1a1bd7db | |||
| 040abc0fb7 |
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"phase": 0,
|
"phase": 0,
|
||||||
"stage": "grill",
|
"stage": "complete",
|
||||||
"milestone": "v1.14",
|
"milestone": "v1.14",
|
||||||
"phase_role": "pre_execution",
|
"phase_role": "pre_execution",
|
||||||
"attempts": 0,
|
"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": "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": "waf.outputs.web_acl_arn", "to": "cloudfront.inputs.waf_web_acl_arn"},
|
||||||
{"from": "contract.inputs.region", "to": "kms.inputs.region"},
|
{"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": [
|
"outputs": [
|
||||||
{"from": "cloudfront.outputs.distribution_domain_name", "to": "stack.outputs.distribution_domain_name"},
|
{"from": "cloudfront.outputs.distribution_domain_name", "to": "stack.outputs.distribution_domain_name"},
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
# Complex static-assets deployment (S3 + CloudFront + WAF)
|
# 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
|
environment: dev
|
||||||
id: assets
|
id: assets
|
||||||
infrastructure:
|
infrastructure:
|
||||||
static-assets:
|
static-assets:
|
||||||
inputs:
|
inputs:
|
||||||
bucket_name: my-static-site
|
bucket_name: my-static-site
|
||||||
default_ttl: 3600
|
default_ttl: 7200
|
||||||
max_ttl: 86400
|
max_ttl: 172800
|
||||||
price_class: PriceClass_100
|
price_class: PriceClass_200
|
||||||
region: us-east-1
|
region: us-east-1
|
||||||
viewer_protocol_policy: redirect-to-https
|
viewer_protocol_policy: https-only
|
||||||
waf_enabled: true
|
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
name: static assets
|
name: static assets
|
||||||
@@ -1,11 +1,18 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# scripts/run_l2_lifecycle_destroy.sh — run a single L2 module lifecycle destroy.
|
# 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
|
# 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.
|
# 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
|
# Lifecycle mode (REQ-134): ACDL_LIFECYCLE_MODE default "plan" = no-op
|
||||||
# (plan mode never applies resources, so there is nothing to destroy).
|
# (plan mode never applies resources, so there is nothing to destroy).
|
||||||
# Set to "full" for the real `--destroy` against live AWS.
|
# Set to "full" for the real `--destroy` against live AWS.
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# scripts/run_l2_lifecycle_test.sh — run a single L2 module lifecycle apply/modify.
|
# 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
|
# 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
|
# 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
|
# microservice composition's terraform_remote_state data source reads from
|
||||||
# the short-lived CI VPC (not the long-lived platform VPC).
|
# 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
|
# Lifecycle mode (REQ-134): ACDL_LIFECYCLE_MODE default "plan" runs
|
||||||
# `run_platform.sh --plan-only` (fast, no AWS mutation). Set to "full" for
|
# `run_platform.sh --plan-only` (fast, no AWS mutation). Set to "full" for
|
||||||
# the real `--apply` against live AWS.
|
# the real `--apply` against live AWS.
|
||||||
|
|||||||
@@ -331,3 +331,34 @@ class TestChildIdHelper:
|
|||||||
assert _child_id(["service-task-definition", "service-service"]) == "service"
|
assert _child_id(["service-task-definition", "service-service"]) == "service"
|
||||||
# alb expands to alb-loadbalancer + alb-targetgroup + alb-listener
|
# 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