Files
acdl/modules-ir/l2/l2-microservice
Jon Chery d103a37419 docs(P14): plan-as-execute + verify (v1.2.4)
---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.
2026-07-21 21:12:17 +00:00
..

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

  1. 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.

  2. 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 string ref:<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 the resources array that declares the output). The adapter translates ref: 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/alb subnets), target_group_arn (alb→service lb_target_group_arn), role_arn (roles→service/alb security_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.