228 lines
8.7 KiB
Markdown
228 lines
8.7 KiB
Markdown
# Consumer Guide — Declare intent, deploy to AWS
|
|
|
|
**TL;DR** — This guide takes a consumer from an empty repository to
|
|
applied AWS infrastructure: create a repo, write one YAML contract,
|
|
validate offline, then run the platform script against AWS.
|
|
|
|
**What** —
|
|
- Step-by-step contract authoring with a worked static-site example,
|
|
generic across all modules.
|
|
- A field-by-field reference for contract and module inputs.
|
|
- Offline validation first (no AWS); the live AWS run second.
|
|
|
|
**Why** — The contract is the whole consumer interface; infrastructure
|
|
code stays platform-side.
|
|
|
|
**Action** — No action — FYI. Follow Steps 1-6 below when ready to
|
|
deploy.
|
|
|
|
**Details** — The platform README (commands and credentials);
|
|
[`docs/contracts/`](contracts/index.md) (contract shapes).
|
|
|
|
|
|
This guide walks a consumer through creating a repo, writing a contract,
|
|
validating it offline, and running it against AWS. It is **generic** across
|
|
all modules in the registry; `static-assets` is the worked example, but
|
|
every step applies to `microservice` and any future module.
|
|
|
|
## The model
|
|
|
|
You write a contract YAML file and the platform does the rest. Your
|
|
repository contains only your application code and your contracts. You do
|
|
not write infrastructure modules or adapter code.
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
A["your repo<br/>(app code + contract)"] -->|run_platform.sh| B
|
|
B["platform<br/>(resolver + adapter + modules)"] -->|contract -> stack -> terraform -> apply| C
|
|
C["your resources in AWS"]
|
|
```
|
|
|
|
## Prerequisites
|
|
|
|
- **A consumer repository** for your application code + contract.
|
|
- **A platform-managed environment** bound to your repo. The platform team
|
|
provisions the AWS account, network, and state backend. See
|
|
[Environments](environments/index.md).
|
|
- **AWS credentials** for the target environment, in `.ciagent/.env.secrets`
|
|
(gitignored) using the `NOVA_AWS_*` prefix. See the
|
|
[platform README](../README.md#credentials) and
|
|
[`terraform/bootstrap/README.md`](../terraform/bootstrap/README.md).
|
|
|
|
## Step 1 — Create a consumer repo
|
|
|
|
Create a repository for your application. The top level holds your app
|
|
code; your contract lives at the repo root (or wherever you point
|
|
`run_platform.sh`). Example for a static site:
|
|
|
|
```
|
|
my-static-site/
|
|
index.html
|
|
assets/
|
|
style.css
|
|
logo.png
|
|
contract.yml
|
|
```
|
|
|
|
Example for a microservice:
|
|
|
|
```
|
|
my-microservice/
|
|
app.py
|
|
Dockerfile
|
|
contract.yml
|
|
```
|
|
|
|
## Step 2 — Define the contract
|
|
|
|
Write `contract.yml`. The `static-assets` example:
|
|
|
|
```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
|
|
```
|
|
|
|
### Contract 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). Each entry carries a `module` name (matching a registry key), an optional `version` (defaults to latest non-deprecated), and required `inputs`. One entry = single-module deploy; N entries = multi-module manifest. |
|
|
|
|
### 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 `X.Y.Z`. Omitted = latest non-deprecated version. |
|
|
| `inputs` | object | yes | Module-specific inputs (see the module's README). No `aws_*` keys — the contract is engine-agnostic. |
|
|
|
|
Each module declares its inputs in its `interface.json`. Consult the
|
|
[module catalog](modules/index.md) for the full list, or read the module's
|
|
own README under `modules/l1/<name>/` or `modules/l2/<name>/`.
|
|
|
|
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 reference (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` |
|
|
| `${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` |
|
|
|
|
## Step 3 — Validate offline (no AWS required)
|
|
|
|
Before touching AWS, validate the contract end-to-end offline. Clone the
|
|
Nova Platform repo and run `--check-only` against your contract:
|
|
|
|
```bash
|
|
bash scripts/run_platform.sh --check-only path/to/your/contract.yml
|
|
# Expected: "=== PLATFORM CHECK OK ==="
|
|
```
|
|
|
|
This runs: environment check → contract schema validation → resolve to
|
|
stack → adapter compiles to HCL → output structure validation. No AWS
|
|
credentials are needed.
|
|
|
|
## Step 4 — Run against live AWS
|
|
|
|
Once the contract validates offline, run the full pipeline against AWS.
|
|
Ensure your credentials are in `.ciagent/.env.secrets` (see
|
|
[Credentials](../README.md#credentials)):
|
|
|
|
```bash
|
|
bash scripts/run_platform.sh contracts/static-assets.yml
|
|
# Expected: "=== PLATFORM APPLY OK ==="
|
|
```
|
|
|
|
The full path: environment check → validate contract → resolve to stack →
|
|
adapter compiles to HCL → load AWS credentials → `terraform init` →
|
|
`terraform validate` → `terraform plan` → `terraform apply -auto-approve`.
|
|
|
|
To stop before apply (review the plan only):
|
|
|
|
```bash
|
|
bash scripts/run_platform.sh --plan-only contracts/static-assets.yml
|
|
# Expected: "=== PLATFORM PLAN OK ==="
|
|
```
|
|
|
|
## Step 5 — What gets created
|
|
|
|
After a successful `dev` run, the resources declared by your module's
|
|
pattern exist in your AWS account.
|
|
|
|
For the `static-assets` example (s3 + cloudfront + kms-key, D-038):
|
|
|
|
- An **S3 bucket** (named via your `bucket_name` input, interpolation
|
|
expanded) with versioning enabled.
|
|
- A **CloudFront distribution** with the S3 bucket as the origin.
|
|
- A **KMS key** for SSE.
|
|
|
|
For other modules, consult the module's README
|
|
(`modules/l1/<name>/README.md` or `modules/l2/<name>/README.md`) for the
|
|
exact resources created.
|
|
|
|
## Step 6 — Upload your content (static-assets example)
|
|
|
|
The platform provisions the infrastructure; you upload your content. For the
|
|
`static-assets` module:
|
|
|
|
```bash
|
|
aws s3 sync ./assets s3://<your-bucket-name>/
|
|
```
|
|
|
|
For a `microservice`, the platform provisions the ECS service and ALB; you
|
|
push your container image to the ECR repo the platform created.
|
|
|
|
## Reference
|
|
|
|
| Resource | Path | Description |
|
|
|----------|------|-------------|
|
|
| Contract schema | `schemas/contract.schema.json` | JSON Schema for consumer contracts. |
|
|
| Stack schema | `schemas/stack.schema.json` | JSON Schema for the resolved stack instance. |
|
|
| Module catalog | [modules/](modules/index.md) | All primitives and modules. |
|
|
| Sample contract | `contracts/static-assets.yml` | The reference example contract. |
|
|
| Sample contract | `contracts/microservice.yml` | The microservice example contract. |
|
|
| Module examples | `modules/<name>/examples/` | Validated per-module example contracts. |
|
|
| Contract resolver | `core/contract_resolver.py` | Resolves contracts to stack instances. |
|
|
| Terraform adapter | `adapters/terraform/adapter.py` | Compiles stack instances to Terraform. |
|
|
| Pipeline runner | `scripts/run_platform.sh` | The pipeline runner. |
|
|
| Environments | [environments/](environments/index.md) | Platform-managed environments. |
|
|
| Platform README | `README.md` | How the platform works + how to run it. |
|
|
| Credentials | `README.md#credentials` | The static-key model + bootstrap runbook. | |