# `infra/terraform` — baseline infrastructure as code

Terraform here manages **only low-frequency baseline resources**:

- **probe machines** — overseas reference dial-test points (doc/04 §1, §4.2).
- **control-plane environment** — the API + MySQL + Redis host (doc/04 §5.2),
  off by default because it changes rarely.

## What is deliberately NOT here

**Data-plane nodes are not in Terraform.** They are disposable cattle, created
and destroyed minute-by-minute through vendor APIs by the provision service
(`server/internal/provision`, doc/04 §4). Putting them in Terraform state would
fight the "nodes are cattle, not pets" model and serialise every open/退机
behind a state lock. Division of labour:

| concern | owner | frequency | in TF state |
|---------|-------|-----------|-------------|
| probe machines | Terraform (this dir) | low | ✅ |
| control-plane env | Terraform (this dir) | one-off | ✅ |
| data-plane nodes (entry/relay/exit) | provision service + vendor API | minutes | ❌ |

## Identity isolation (RED LINE, doc/06 §2)

Every vendor/account/domain used here MUST be an **independent identity** — its
own account, email, and crypto payment, with **zero cross-linkage** to other
assets. This Terraform code and the data-plane vendor accounts use **separate**
credentials:

- `var.hcloud_token` here is the **management/probe** account token — *not* a
  data-plane vendor token.
- Data-plane vendor credentials live only in `PROVISION_<VENDOR>_*` env secrets
  consumed by the provision service, never in Terraform, never in the DB.

The full isolation register (which account/email/payment maps to which asset) is
maintained in [`../identity-isolation.md`](../identity-isolation.md).

## Usage

```bash
cd infra/terraform
cp terraform.tfvars.example terraform.tfvars   # gitignored; fill in
export TF_VAR_hcloud_token=...                 # inject secret, never commit

terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply
```

CI/management operations run on a **dedicated channel** (doc/06 §2), not from an
operator's everyday machine.

## Layout

```
terraform/
  versions.tf            provider + backend pins
  variables.tf           root inputs
  main.tf                wires probe[] + control-plane modules
  outputs.tf             probe IPs, control-plane IP
  terraform.tfvars.example
  modules/
    probe/               one overseas reference probe point
    control-plane/       API+MySQL+Redis host (prevent_destroy)
```
