---ci--- project: nova-platform milestone: v1.0 status: complete requirements: covered: [REQ-01,REQ-02,REQ-03,REQ-04,REQ-05,REQ-06,REQ-07,REQ-08,REQ-09,REQ-10,REQ-11,REQ-12,REQ-13,REQ-14,REQ-15,REQ-16,REQ-17,REQ-18,REQ-19,REQ-20,REQ-21,REQ-22,REQ-23,REQ-24,REQ-25,REQ-26,REQ-27,REQ-28,REQ-29,REQ-30,REQ-31,REQ-32,REQ-33,REQ-34,REQ-35,REQ-36,REQ-37,REQ-38] partial: [] ---/ci--- v1.0 milestone complete: simplified infrastructure-delivery platform derived from Nova (acdl). 6 phases (P0-P5 + P6 final). 38 REQ-IDs. 38 decisions (D-001..D-038). 76 tests pass. Engine boundary holds. Happy paths green (check-only + CI). 13 L1 + 2 L2 modules. 5 terraform roots. Shell reproducibility. Zero OOS files. Tags: v0.1.0 (P0) → v0.1.1..v0.1.5 (P1..P5) → v0.1.6 (P6 = milestone release on v0.1 patch line).
5.1 KiB
Contracts
A consumer declares intent in a contract — a small YAML file that names infrastructure (one or more modules), selects an environment, and supplies module-specific inputs. The platform validates, resolves, and deploys it.
The contract file
A minimal example (the static-assets module):
id: stsi
name: Static Assets Site
environment: dev
infrastructure:
- module: static-assets
version: "1.0.0"
inputs:
bucket_name: "${env.environment}-${contract.id}-assets"
index_document: index.html
A microservice example:
id: msvc
name: Microservice
environment: dev
infrastructure:
- module: microservice
version: "1.0.0"
inputs:
service_name: "${env.environment}-${contract.id}-svc"
desired_count: 2
Array-based infrastructure (D-015)
The infrastructure field is an array of module entries, not a map
keyed by module name. This is a locked deviation from the Nova reference
(D-015). Each entry is an object with module, version (optional), and
inputs.
One entry = single-module deploy. N entries = multi-module manifest deployed in one pipeline run:
id: app
name: Pricing Service API
environment: dev
infrastructure:
- module: microservice
version: "1.0.0"
inputs: { ... }
- module: static-assets
version: "1.0.0"
inputs: { ... }
All modules deploy to the same environment in one pipeline run.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | yes | Short operational acronym (^[a-z][a-z0-9-]{2,5}$, 3-6 chars). Becomes the stack name used for the Terraform state key and resource naming prefix. Stable across deploys and environment promotions. |
name |
string | yes | Full human-readable stack name (min 3 chars). |
environment |
string | yes | The platform-managed environment to deploy to (dev/qa/prod/dr). See Environments. |
infrastructure |
array | yes | Array of modules to deploy (D-015). minItems: 1. |
Infrastructure item fields
| Field | Type | Required | Description |
|---|---|---|---|
module |
string | yes | Module name from modules/registry.json (^[a-z][a-z0-9-]*$). |
version |
string | no | Semver pin (^\d+\.\d+\.\d+$). Omitted = latest non-deprecated version from the registry. |
inputs |
object | yes | Module-specific inputs (see the module's README / interface.json). No aws_* keys — the contract is engine-agnostic. |
Validation
The contract is validated against
schemas/contract.schema.json. An
invalid contract (missing field, unknown module, wrong type) fails at the
validate-contract stage with a clear error.
Interpolation tokens (D-016)
The resolver expands ${env.*} and ${contract.*} tokens after the
environment is loaded. Unknown tokens raise ValueError (fail loud).
Expansion is recursive (nested map/list values expand too).
| Token | Resolves to | Example |
|---|---|---|
${env.name} |
the environment name | dev |
${env.region} |
the environment's AWS region | us-east-1 |
${env.account_id} |
the environment's AWS account id | 000000000000 |
${env.state_backend.bucket} |
the environment's state bucket | nova-tfstate-dev-us-east-1 |
${env.state_backend.lock_table} |
the environment's lock table | nova-tfstate-locks |
${env.network.vpc_cidr} |
the environment's VPC CIDR | 10.0.0.0/16 |
${env.network.azs} |
the environment's availability zones | ["us-east-1a","us-east-1b"] |
${contract.id} |
the contract's operational acronym | stsi |
${contract.name} |
the contract's name field | Static Assets Site |
${contract.environment} |
the contract's environment field | dev |
Sample contracts
Two reference examples exist in contracts/:
contracts/static-assets.yml— thestatic-assetsmodule (s3 + cloudfront + kms-key, D-038).contracts/microservice.yml— themicroservicemodule (vpc + ecs-cluster + ecs-service + iam-role + ecr + alb, D-038).
Additionally, every module has a modules/<name>/examples/ directory with
validated example contracts. See the module catalog
for the full list.
Per-environment variants (D-033)
Each sample contract has per-environment variants that differ only in
the environment field — all other fields are identical. Interpolation
resolves environment-specific values at resolver time.
| File | Environment |
|---|---|
contracts/static-assets.yml |
dev (default) |
contracts/static-assets.dev.yml |
dev |
contracts/static-assets.qa.yml |
qa |
contracts/static-assets.prod.yml |
prod |
contracts/static-assets.dr.yml |
dr |
contracts/microservice.yml |
dev (default) |
contracts/microservice.dev.yml |
dev |
contracts/microservice.qa.yml |
qa |
contracts/microservice.prod.yml |
prod |
contracts/microservice.dr.yml |
dr |
Promotion = running the pipeline against the matching variant. See the Consumer Guide for the end-to-end flow.