---ci--- project: acdl phase: 14 milestone: v1.2 status: verify verdict: VERIFIED requirements: covered: [REQ-32] ---/ci--- Phase 14 plan-as-execute + verify. scripts/verify_phase14.sh green. l2-microservice composition (6 L1s, 2 wire kinds); contract schema extended (inputs allow objects + healthcheck); resolver extended (array-form wires, child->child refs, multi-resource L1 expansion); adapter extended (ref: interpolation translation). v1.2 IR: 11 resources. v1.1 S3 regression byte-identical. Ready to ship v1.2.4.
4.1 KiB
l2-microservice — thin-composition (ECS Fargate microservice)
The v1.2 L2. A thin-composition that references 6 L1s (depth 1):
l1-vpc, l1-ecs-cluster, l1-ecr, l1-iam-role, l1-alb,
l1-ecs-service. The contract's inputs (name, cidr, azs,
image, port, cpu, memory, env, protocol, region,
role_name, assume_role_policy, managed_policies) map to the
children's inputs through two wire kinds.
Composition (the IR-typed thin-composition tree)
See composition.json: kind=l2, depth=1, six children.
Children
| child id | L1 module | IR type(s) |
|---|---|---|
vpc |
l1-vpc@1.0.0 |
aws:ec2:vpc, aws:ec2:subnet, aws:ec2:routetable |
cluster |
l1-ecs-cluster@1.0.0 |
aws:ecs:cluster |
ecr |
l1-ecr@1.0.0 |
aws:ecr:repository |
roles |
l1-iam-role@1.0.0 |
aws:iam:role |
alb |
l1-alb@1.0.0 |
aws:elbv2:loadbalancer, aws:elbv2:listener, aws:elbv2:targetgroup |
service |
l1-ecs-service@1.0.0 |
aws:ecs:task_definition, aws:ecs:service |
Multi-resource L1s (vpc, alb, service) declare a resources
array in their interface.json; the resolver expands each child into
one IR resource per resources entry (id scheme <child_id>-<type_suffix>
where type_suffix is the last segment of the IR type with underscores
stripped — e.g. vpc-vpc, vpc-subnet, vpc-routetable,
alb-loadbalancer, alb-targetgroup, alb-listener,
service-taskdefinition, service-service. The hyphen separator keeps
the id valid against schemas/ir.schema.json's
^[a-z][a-z0-9-]*$ resource id pattern). Single-resource L1s keep the
child id verbatim (cluster, ecr, roles).
Wire kinds
-
Contract→child passthrough — wire name = contract input name; target = child id, input = child's input name. For contract inputs that fan out to multiple children (
name,port,region), the wire value is an array of{target, input}objects; otherwise a single object. Resolves to the concrete contract value. -
Child→child references — wire with
source: "child:<id>.<output>". The value is only known at apply time, so the resolver emits the IR input as the stringref:<ir_resource_id>.<output>(the IR resource id of the producing child's first resource — for single-resource L1s that is the child id, for multi-resource L1s it is<child_id>-<type_suffix>of the first resource in theresourcesarray that declares the output). The adapter translatesref:to a Terraform interpolation.
Wires used by this composition:
- Passthrough:
name(→vpc/cluster/ecr/alb),cidr(→vpc),azs(→vpc),image(→service),port(→service/alb),cpu(→service),memory(→service),env(→service),protocol(→alb),region(→all 6),role_name(→roles),assume_role_policy(→roles),managed_policies(→roles). - Child→child:
cluster_arn(cluster→service),subnet_ids(vpc→service/albsubnets),target_group_arn(alb→servicelb_target_group_arn),role_arn(roles→service/albsecurity_group).
IR → Terraform mapping (D-P10-1)
The Terraform adapter consumes the resolved IR instance (which has
kind=l2 + all 6 L1s expanded into one IR resource per entry in each
L1's resources array, with ref: strings on the consumer inputs).
For a depth-1 thin-composition, the L2 root module IS the union of
the L1 resources — no separate module "l1_x" { source = "..." }
blocks. The existing adapter TYPE_MAP + INPUT_MAP + OUTPUT_MAP
tables handle every IR type. ref:<id>.<output> inputs are translated
to ${<tf_type>.<id>.<attr>} (attribute mapped through OUTPUT_MAP
for the referenced resource's type). The relationships array records
the parent composition tree; ordering is implicit in the resource list.
v1.3+ may emit real module "l1_x" { source = "..." } blocks once L1s
are 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.