| 1 | # region-remote-host |
| 2 | |
| 3 | Provisions what an off-cloud CARLOS host needs when there is no EC2 instance |
| 4 | profile to lean on: a region data bucket plus an IAM user carrying a scoped |
| 5 | inline policy and access key, limited to this region's data bucket and |
| 6 | nothing else (wrong-region-fails-at-IAM, the same residency property |
| 7 | `region-host` gives cloud hosts). |
| 8 | |
| 9 | Consumed by customer fleets (paulca/pi-fleet is the live example) and |
| 10 | the platform's tito hq box. The module is reusable as-is for both — they |
| 11 | differ only in account and variable values, not shape. |
| 12 | |
| 13 | **`deployment_bucket_arn` is optional (default `""`).** The fleet API |
| 14 | surface (issue #73) means a fleet box no longer needs any IAM grant on the |
| 15 | platform's deployment bucket at all: it reads releases and status, and |
| 16 | writes heartbeats, through the console's edge (`/store/o/...`) using the |
| 17 | same tunnel token it already dials with — the door authenticates and |
| 18 | scopes the request, not a bucket-level AWS credential. That is the shape |
| 19 | every new fleet-API consumer's tofu root should apply with: leave |
| 20 | `deployment_bucket_arn` unset, and the module emits no deployment-bucket |
| 21 | IAM statement at all. |
| 22 | |
| 23 | The variable still exists for **grandfathered direct-S3 boxes** — ones |
| 24 | still running the pre-#73 agent, or deliberately kept off the fleet API — |
| 25 | which need RW straight on the deployment bucket exactly as before; set |
| 26 | `deployment_bucket_arn` explicitly for those and the module emits the |
| 27 | extra scoped statement (`aws_iam_user_policy.host_deployment_bucket`) on |
| 28 | top of the always-present own-data-bucket grant. |
| 29 | |
| 30 | The S3 action list in the inline policy is not independently chosen: it is |
| 31 | copied verbatim from `infra/modules/region-host/main.tf`'s |
| 32 | `aws_iam_role_policy.host_buckets` (the authority for what this principal |
| 33 | shape may do to S3), split the same way region-host splits it — object |
| 34 | actions (`GetObject`/`PutObject`/`DeleteObject`) scoped to the object ARNs, |
| 35 | and bucket-level actions (`ListBucket`/`GetBucketLocation`) scoped to the |
| 36 | bucket ARNs. If region-host's action list changes, this module's should |
| 37 | change with it. |
| 38 | |
| 39 | The data bucket follows the same convention `deployment-buckets` uses for |
| 40 | this class of bucket (see `infra/modules/README.md`): versioning, AES256 |
| 41 | SSE, a full public-access block, and `prevent_destroy`, hard-coded the same |
| 42 | way `deployment-buckets` hard-codes it (tofu can't take a variable in a |
| 43 | `lifecycle` block). Boxes are disposable; this bucket is not — parked |
| 44 | instance state has no other recovery story. A demo region like `pi` that |
| 45 | needs to go away entirely is not a `tofu destroy`: empty the bucket first |
| 46 | (S3 refuses to delete a non-empty bucket regardless of `prevent_destroy`), |
| 47 | then either comment out the `prevent_destroy` line for that one apply or |
| 48 | `tofu state rm` the bucket before removing the module instance — the same |
| 49 | manual override `deployment-buckets` requires, not a mechanism specific to |
| 50 | this module. |
| 51 | |