# Terraform — simulation environment (T4) Declares the simulated fleet and its observability stack on the k3d cluster created by [`../../ansible/sim-cluster.yml`](../../ansible/sim-cluster.yml). This module is the executable miniature of the dev/sim environment from [06 — Environments](../../../docs/06-environments.md). | Resource | Purpose | | --- | --- | | StatefulSet `drone` × `drone_count` | Virtual drones; stable pod names become `DRONE_ID`s; all write Hive-partitioned Parquet into the shared `/data` lake | | Deployment `exporter` | Prometheus exporter reading the lake with DuckDB | | Deployment `explorer` + NodePort 30088 | Partition tree + read-only SQL console (also feeds the prototype's live mode) | | Deployment `prometheus` + NodePort 30990 | Scrapes the exporter | | Deployment `grafana` + NodePort 30300 | Same dashboard JSON as the Compose profile, provisioned from a ConfigMap | ## Usage ```bash ansible-playbook ../../ansible/sim-cluster.yml # once: cluster + image terraform init terraform apply terraform output # URLs ``` Scale the fleet without touching YAML: ```bash terraform apply -var drone_count=9 -var speedup=4 ``` ## Notes - `image_pull_policy = "Never"` — the simulator image is imported by the Ansible playbook (`k3d image import`); the cluster never pulls from a registry, mirroring the air-gap doctrine. - Pods discover their identity from the pod name (StatefulSet ordinal), so a flight survives `kubectl delete pod` the same way a drone survives a power cycle: new process, same identity, new flight ID. - State is local (`terraform.tfstate` in this directory) — the simulation cluster is disposable; nothing here is shared infrastructure.