# 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): ```yaml 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: ```yaml 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: ```yaml 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](../environments/index.md). | | `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`](../../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`](../../contracts/static-assets.yml) — the `static-assets` module (s3 + cloudfront + kms-key, D-038). - [`contracts/microservice.yml`](../../contracts/microservice.yml) — the `microservice` module (vpc + ecs-cluster + ecs-service + iam-role + ecr + alb, D-038). Additionally, every module has a `modules//examples/` directory with validated example contracts. See the [module catalog](../modules/index.md) 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](../consumer-guide.md) for the end-to-end flow.