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