phase: 10, status: plan-as-execute, persona: platform-engineer, task: T-10.1..T-10.3+T-10.6
---ci--- project: acdl phase: 10 milestone: v1.1 status: plan-as-execute persona: platform-engineer task: [T-10.1, T-10.2, T-10.3, T-10.6] requirements.covered: [REQ-25] ---/ci--- Wave 1: L2 thin-composition + registry extension + adapter L2 handling. - T-10.1: modules-ir/l2/l2-static-asset/composition.json (kind=l2, depth=1, one child l1-s3@1.0.0, wires passthrough). - T-10.2: modules-ir/registry.json extended with l2-static-asset@1.0.0. - T-10.3: modules-ir/l2/l2-static-asset/README.md (D-P10-1 doc). - T-10.6: adapters/terraform/adapter.py - backend key now derived from the stack name (spike/<stack_name>/terraform.tfstate). The resources array handling is unchanged; a resolved L2 IR instance has the L1 resource as resources[0], so the existing TYPE_MAP + resource emission handle it (the adapter is shape-driven, not kind-driven).
This commit is contained in:
@@ -82,6 +82,8 @@ def adapt(ir_instance, out_dir):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# --- terraform.tf: required_version + required_providers + S3 backend (no DynamoDB lock per D-P09-1) ---
|
# --- terraform.tf: required_version + required_providers + S3 backend (no DynamoDB lock per D-P09-1) ---
|
||||||
|
# The backend key is derived from the stack name so l1 vs l2 spikes use separate state keys (D-P10-1).
|
||||||
|
stack_name = stack.get("name", "spike")
|
||||||
terraform_tf = (
|
terraform_tf = (
|
||||||
'terraform {\n'
|
'terraform {\n'
|
||||||
' required_version = ">= 1.9, < 1.10"\n'
|
' required_version = ">= 1.9, < 1.10"\n'
|
||||||
@@ -93,7 +95,7 @@ def adapt(ir_instance, out_dir):
|
|||||||
' }\n'
|
' }\n'
|
||||||
' backend "s3" {\n'
|
' backend "s3" {\n'
|
||||||
' bucket = "acdl-tfstate-581513795199-us-east-1"\n'
|
' bucket = "acdl-tfstate-581513795199-us-east-1"\n'
|
||||||
' key = "spike/l1-s3/terraform.tfstate"\n'
|
f' key = "spike/{stack_name}/terraform.tfstate"\n'
|
||||||
' region = "us-east-1"\n'
|
' region = "us-east-1"\n'
|
||||||
' }\n'
|
' }\n'
|
||||||
'}\n'
|
'}\n'
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# l2-static-asset — thin-composition (S3 static asset)
|
||||||
|
|
||||||
|
The v1.1 spike's L2. A thin-composition that references `l1-s3` only
|
||||||
|
(depth 1). The contract's inputs (`bucket_name`, `region`) map 1:1
|
||||||
|
through the wires to the L1's inputs.
|
||||||
|
|
||||||
|
## Composition (the IR-typed thin-composition tree)
|
||||||
|
|
||||||
|
See `composition.json`: `kind=l2`, `depth=1`, one child `l1-s3@1.0.0`,
|
||||||
|
wires `{bucket_name → s3.inputs.bucket_name, region → s3.inputs.region}`
|
||||||
|
(passthrough).
|
||||||
|
|
||||||
|
## IR → Terraform mapping (D-P10-1)
|
||||||
|
|
||||||
|
The Terraform adapter consumes the *resolved IR instance* (which has
|
||||||
|
`kind=l2` + the L1 resource `s3` in its `resources` array). For a
|
||||||
|
depth-1 thin-composition, the L2 root module **IS** the L1's resource —
|
||||||
|
no separate `module "l1_s3" { source = "..." }` block. The existing
|
||||||
|
adapter `TYPE_MAP` + resource emission handle both l1 and l2 instances
|
||||||
|
(the resources array is the same shape). The `relationships` array is
|
||||||
|
ignored at the Terraform level for the spike (composition ordering is
|
||||||
|
implicit in the single resource).
|
||||||
|
|
||||||
|
v1.2 may emit a real `module "l1_s3" { source = "..." }` block when L1s
|
||||||
|
become published Terraform modules rather than inline resources.
|
||||||
|
|
||||||
|
## Versioning (W3.D)
|
||||||
|
|
||||||
|
`1.0.0` — interface MAJOR, behavior MINOR, lifecycle PATCH. MAJOR bumps
|
||||||
|
require a new registry entry (immutable publication); old entries enter
|
||||||
|
a 12-month deprecation window.
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "l2-static-asset",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"kind": "l2",
|
||||||
|
"depth": 1,
|
||||||
|
"description": "Thin-composition: a single S3 bucket for static asset hosting. References l1-s3 only (depth 1).",
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"id": "s3",
|
||||||
|
"module": "l1-s3@1.0.0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"wires": {
|
||||||
|
"bucket_name": {"target": "s3", "input": "bucket_name"},
|
||||||
|
"region": {"target": "s3", "input": "region"}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,5 +5,12 @@
|
|||||||
"published_at": "2026-07-21T19:00:00Z",
|
"published_at": "2026-07-21T19:00:00Z",
|
||||||
"deprecated": false
|
"deprecated": false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"l2-static-asset": {
|
||||||
|
"1.0.0": {
|
||||||
|
"composition": "modules-ir/l2/l2-static-asset/composition.json",
|
||||||
|
"published_at": "2026-07-21T19:30:00Z",
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user