refactor(modules): remove thin-composition layer; rewrite all module READMEs
The L2 thin-composition layer (composition.json + contract_resolver.py + contract schema + sample contracts) has been removed completely. The implementation was unsatisfactory and is deferred for a later redesign. - Delete: composition.json x2, contract_resolver.py, contracts/ x2, contract.schema.json - Patch: run_platform.sh now loads a pre-existing IR instance instead of resolving a contract (the downstream adapter/checkov/confidence/outbox pipeline is unchanged) - Prune: L2 entries removed from registry.json (L1 entries unchanged) - Rewrite: all 7 L1 module READMEs in plain language (no jargon), each with Resources/Inputs/Outputs/Usage/Compliance-extension-points/Versioning sections derived from interface.json - Add: 2 L2 placeholder READMEs noting the composition is under redesign - Add: modules-ir/README.md catalog index + README-TEMPLATE.md ---ci--- project: acdl phase: 17 milestone: v1.3 status: execute ---/ci---
This commit is contained in:
@@ -1,85 +1,57 @@
|
||||
# l2-microservice — thin-composition (ECS Fargate microservice)
|
||||
# l2-microservice — ECS Fargate microservice (composition being redesigned)
|
||||
|
||||
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.
|
||||
> **Module kind:** L2 composition | **Version:** TBD | **Status:** Under redesign
|
||||
|
||||
## Composition (the IR-typed thin-composition tree)
|
||||
A composition that references multiple L1 primitives to deploy an ECS
|
||||
Fargate microservice end-to-end (VPC, cluster, ECR, IAM role, ALB,
|
||||
ECS service).
|
||||
|
||||
See `composition.json`: `kind=l2`, `depth=1`, six children.
|
||||
**The composition layer is being redesigned.** The previous
|
||||
thin-composition implementation (a `composition.json` with children +
|
||||
wires) has been removed. A new composition mechanism will be designed
|
||||
in a later phase.
|
||||
|
||||
### Children
|
||||
## Resources
|
||||
|
||||
| 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` |
|
||||
TBD — the composition will reference these L1 primitives:
|
||||
|
||||
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`).
|
||||
| L1 module | Purpose | README |
|
||||
|-----------|---------|--------|
|
||||
| `l1-vpc` | VPC, subnets, routing | [README](../l1/l1-vpc/README.md) |
|
||||
| `l1-ecs-cluster` | ECS Fargate cluster | [README](../l1/l1-ecs-cluster/README.md) |
|
||||
| `l1-ecr` | ECR image repository | [README](../l1/l1-ecr/README.md) |
|
||||
| `l1-iam-role` | IAM task execution role | [README](../l1/l1-iam-role/README.md) |
|
||||
| `l1-alb` | Application Load Balancer | [README](../l1/l1-alb/README.md) |
|
||||
| `l1-ecs-service` | ECS task definition + service | [README](../l1/l1-ecs-service/README.md) |
|
||||
|
||||
### Wire kinds
|
||||
## Inputs
|
||||
|
||||
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.
|
||||
TBD — will be defined when the composition mechanism is redesigned.
|
||||
|
||||
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.
|
||||
## Outputs
|
||||
|
||||
Wires used by this composition:
|
||||
TBD — will be defined when the composition mechanism is redesigned.
|
||||
|
||||
- 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`).
|
||||
## Usage
|
||||
|
||||
## IR → Terraform mapping (D-P10-1)
|
||||
TBD — the composition mechanism is being redesigned. Until then, use
|
||||
the L1 primitives directly. See each L1 module's README for usage
|
||||
examples.
|
||||
|
||||
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.
|
||||
## Compliance extension points
|
||||
|
||||
v1.3+ may emit real `module "l1_x" { source = "..." }` blocks once L1s
|
||||
are published Terraform modules rather than inline resources.
|
||||
The composition will need to wire compliance resources across L1s
|
||||
when the compliance milestone (GDPR, SOX, SOC2, HIPAA, DORA) lands:
|
||||
|
||||
## Versioning (W3.D)
|
||||
- **KMS key** — shared encryption key referenced by S3, ECR, CloudWatch Logs, and Secrets Manager.
|
||||
- **CloudTrail** — management-plane audit trail for the entire stack.
|
||||
- **VPC Flow Logs** — network audit trail.
|
||||
- **Security groups** — proper network segmentation between ALB, service, and data tiers.
|
||||
- **Private subnets** — ECS tasks in private subnets with NAT egress.
|
||||
|
||||
`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.
|
||||
See each L1 module's README for per-module compliance extension points.
|
||||
|
||||
## Versioning
|
||||
|
||||
Versioning will be defined when the composition mechanism is
|
||||
redesigned.
|
||||
@@ -1,55 +0,0 @@
|
||||
{
|
||||
"name": "l2-microservice",
|
||||
"version": "1.0.0",
|
||||
"kind": "l2",
|
||||
"depth": 1,
|
||||
"description": "Thin-composition: an ECS Fargate microservice. References 6 L1s (vpc, cluster, ecr, roles, alb, service).",
|
||||
"children": [
|
||||
{"id": "vpc", "module": "l1-vpc@1.0.0"},
|
||||
{"id": "cluster", "module": "l1-ecs-cluster@1.0.0"},
|
||||
{"id": "ecr", "module": "l1-ecr@1.0.0"},
|
||||
{"id": "roles", "module": "l1-iam-role@1.0.0"},
|
||||
{"id": "alb", "module": "l1-alb@1.0.0"},
|
||||
{"id": "service", "module": "l1-ecs-service@1.0.0"}
|
||||
],
|
||||
"wires": {
|
||||
"name": [
|
||||
{"target": "vpc", "input": "name"},
|
||||
{"target": "cluster", "input": "name"},
|
||||
{"target": "ecr", "input": "name"},
|
||||
{"target": "alb", "input": "name"}
|
||||
],
|
||||
"cidr": {"target": "vpc", "input": "cidr"},
|
||||
"azs": {"target": "vpc", "input": "azs"},
|
||||
"image": {"target": "service", "input": "image"},
|
||||
"port": [
|
||||
{"target": "service", "input": "port"},
|
||||
{"target": "alb", "input": "port"}
|
||||
],
|
||||
"cpu": {"target": "service", "input": "cpu"},
|
||||
"memory": {"target": "service", "input": "memory"},
|
||||
"env": {"target": "service", "input": "env"},
|
||||
"protocol": {"target": "alb", "input": "protocol"},
|
||||
"region": [
|
||||
{"target": "vpc", "input": "region"},
|
||||
{"target": "cluster", "input": "region"},
|
||||
{"target": "ecr", "input": "region"},
|
||||
{"target": "roles", "input": "region"},
|
||||
{"target": "alb", "input": "region"},
|
||||
{"target": "service", "input": "region"}
|
||||
],
|
||||
"role_name": {"target": "roles", "input": "role_name"},
|
||||
"assume_role_policy": {"target": "roles", "input": "assume_role_policy"},
|
||||
"managed_policies": {"target": "roles", "input": "managed_policies"},
|
||||
"cluster_arn": {"target": "service", "input": "cluster_arn", "source": "child:cluster.cluster_arn"},
|
||||
"subnet_ids": [
|
||||
{"target": "service", "input": "subnets", "source": "child:vpc.subnet_ids"},
|
||||
{"target": "alb", "input": "subnets", "source": "child:vpc.subnet_ids"}
|
||||
],
|
||||
"target_group_arn": {"target": "service", "input": "lb_target_group_arn", "source": "child:alb.target_group_arn"},
|
||||
"role_arn": [
|
||||
{"target": "service", "input": "security_group", "source": "child:roles.role_arn"},
|
||||
{"target": "alb", "input": "security_group", "source": "child:roles.role_arn"}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,51 @@
|
||||
# l2-static-asset — thin-composition (S3 static asset)
|
||||
# l2-static-asset — S3 static asset (composition being redesigned)
|
||||
|
||||
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.
|
||||
> **Module kind:** L2 composition | **Version:** TBD | **Status:** Under redesign
|
||||
|
||||
## Composition (the IR-typed thin-composition tree)
|
||||
A composition that references the `l1-s3` primitive to deploy a single
|
||||
S3 bucket for static asset hosting.
|
||||
|
||||
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).
|
||||
**The composition layer is being redesigned.** The previous
|
||||
thin-composition implementation (a `composition.json` with children +
|
||||
wires) has been removed. A new composition mechanism will be designed
|
||||
in a later phase.
|
||||
|
||||
## IR → Terraform mapping (D-P10-1)
|
||||
## Resources
|
||||
|
||||
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).
|
||||
TBD — the composition will reference this L1 primitive:
|
||||
|
||||
v1.2 may emit a real `module "l1_s3" { source = "..." }` block when L1s
|
||||
become published Terraform modules rather than inline resources.
|
||||
| L1 module | Purpose | README |
|
||||
|-----------|---------|--------|
|
||||
| `l1-s3` | S3 bucket | [README](../l1/l1-s3/README.md) |
|
||||
|
||||
## Versioning (W3.D)
|
||||
## Inputs
|
||||
|
||||
`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.
|
||||
TBD — will be defined when the composition mechanism is redesigned.
|
||||
|
||||
## Outputs
|
||||
|
||||
TBD — will be defined when the composition mechanism is redesigned.
|
||||
|
||||
## Usage
|
||||
|
||||
TBD — the composition mechanism is being redesigned. Until then, use
|
||||
`l1-s3` directly. See the [l1-s3 README](../l1/l1-s3/README.md) for a
|
||||
usage example.
|
||||
|
||||
## Compliance extension points
|
||||
|
||||
The composition will need to wire compliance resources when the
|
||||
compliance milestone (GDPR, SOX, SOC2, HIPAA, DORA) lands:
|
||||
|
||||
- **KMS key** — shared encryption key for S3 SSE.
|
||||
- **S3 access logs** — access logging to a separate audit bucket.
|
||||
- **Object Lock** — 7-year immutable retention for evidence.
|
||||
- **Public access block** — prevent data exfiltration.
|
||||
|
||||
See the [l1-s3 README](../l1/l1-s3/README.md) for per-module compliance
|
||||
extension points.
|
||||
|
||||
## Versioning
|
||||
|
||||
Versioning will be defined when the composition mechanism is
|
||||
redesigned.
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"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"}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user