# `infra/` — elastic-node infrastructure

This directory is the **IaC half** of the elastic-node base (task #14). The
**control-plane half** — vendor adapters and the make-before-break orchestration
— lives in [`../server/internal/provision`](../server/internal/provision).

```
infra/
  terraform/             baseline resources: probe machines + control-plane env
  cloud-init/
    node.yaml.tmpl       data-plane node bootstrap (rendered by provision svc)
  identity-isolation.md  per-asset identity isolation register (doc/06 §2)
```

## Division of labour (doc/04 §4)

- **Terraform** (`terraform/`) — low-frequency baseline only (probes, control
  plane). These are in Terraform state.
- **Provision service** (`server/internal/provision`) — high-frequency,
  minute-scale, idempotent node open/退机 via vendor APIs. Nodes are cattle and
  are **never** in Terraform state.

## `cloud-init/node.yaml.tmpl`

The entire persistent footprint of a data-plane node: sing-box + agent + a
one-time bootstrap token (doc/04 §2). It is a Go `text/template` rendered by the
provision service's `CloudInitRenderer`, injecting:

`NodeUUID`, `BootstrapToken` (task #5), `Region`, `Role`, `Tier`,
`ControlPlaneURL`.

The rendered output carries the one-time enrollment token and **must not be
logged**. The agent self-registers over mTLS (task #6); the control plane then
drives the node `provisioning → probing → up`.

## Red lines (doc/06 §2)

- Everything here targets the **new vendor pools**. It must **never** manage the
  production EC2 host (the `deploy/` marzban machine).
- Credentials are never committed: Terraform tokens via `TF_VAR_*` / CI secrets,
  vendor API keys via `PROVISION_<VENDOR>_*` env consumed by the provision
  service. The `providers` table stores only `name/api_kind/regions/pool/enabled`.
- Each vendor/domain/account is an independent identity with zero cross-linkage;
  see `identity-isolation.md`.
