# l1-vpc — VPC primitive (multi-resource L1) An L1 module for a VPC with subnets and a route table. Substrate-agnostic (the IR types are `aws:ec2:vpc`, `aws:ec2:subnet`, `aws:ec2:routetable`, not Terraform resource types). This is a multi-resource L1: the interface declares the group's inputs/outputs plus a `resources` array listing the IR types it emits. The IR instance (Phase 14/15) will have multiple `resources` entries all with `module: "l1-vpc@1.0.0"`. ## Interface (the IR-typed contract) See `interface.json`: inputs `cidr` (string, e.g. "10.0.0.0/16"), `azs` (string, comma-separated, e.g. "us-east-1a,us-east-1b"), `name` (string, used for tagging), `region` (string); outputs `vpc_id` (string), `subnet_ids` (string, comma-separated), `igw_id` (string); no NFRs. The `resources` array lists the emitted IR types: - `aws:ec2:vpc` — the VPC itself (cidr → cidr_block, name → tag). - `aws:ec2:subnet` — one subnet per availability zone (`azs` split on comma); inputs include the parent VPC id. - `aws:ec2:routetable` — route table bound to the VPC with an internet gateway + default route (0.0.0.0/0 → igw). ## IR → Terraform mapping (performed by the adapter) The Terraform adapter (`adapters/terraform/adapter.py`) translates each emitted IR resource to Terraform: | IR | Terraform | |----|-----------| | `resource.type = aws:ec2:vpc` | `resource "aws_vpc" "" { ... }` | | `resource.inputs.cidr` | `cidr_block = ` arg | | `resource.inputs.name` | `tags = { Name = }` (emit as-is) | | `resource.outputs.vpc_id` | `output "vpc_id" { value = aws_vpc..id }` | | `resource.type = aws:ec2:subnet` | `resource "aws_subnet" "" { ... }` | | `resource.inputs.cidr` | `cidr_block = ` arg | | `resource.inputs.az` | `availability_zone = ` arg | | `resource.outputs.subnet_id` | `output "subnet_id" { value = aws_subnet..id }` | | `resource.type = aws:ec2:routetable` | `resource "aws_route_table" "" { ... }` | | `resource.inputs.vpc_id` | `vpc_id = ` arg | The internet gateway + default route are emitted as part of the route table resource's IR (the `igw_id` output is wired via the route table's inputs). The adapter is a thin layer (ARCHITECTURE.md §12.2); it does not own L1 content — it only translates. ## 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.