eleven / messenger Public

Clone
git clone https://amadan.net/eleven/messenger

Plain git — no account needed to clone.

Download

Download this file

1# 🤖 The dev mesh's object store — deliberately SEPARATE from prod's buckets and
2# from infra/dev's proof buckets. Mesh membership is S3 heartbeats under a
3# prefix, so a distinct bucket is what physically stops a dev node from ever
4# joining the prod mesh (docs/dev-mesh.md § Cut-off). One bucket holds it all:
5# membership, the hibernation lease + replicas, and instance DBs.
6
7resource "aws_s3_bucket" "mesh" {
8 bucket = "eleven-dev-mesh-${local.account_id}"
9}
10
11# Versioning is the ransomware/oops posture: an overwrite or delete with the
12# box's own credentials leaves recoverable versions behind. Dev data is
13# disposable, but the machinery must match prod so we exercise the real thing.
14resource "aws_s3_bucket_versioning" "mesh" {
15 bucket = aws_s3_bucket.mesh.id
16 versioning_configuration {
17 status = "Enabled"
18 }
19}
20
21resource "aws_s3_bucket_lifecycle_configuration" "mesh" {
22 bucket = aws_s3_bucket.mesh.id
23 rule {
24 id = "prune-noncurrent"
25 status = "Enabled"
26 filter {}
27 noncurrent_version_expiration {
28 noncurrent_days = 5
29 }
30 }
31}
32
33resource "aws_s3_bucket_public_access_block" "mesh" {
34 bucket = aws_s3_bucket.mesh.id
35 block_public_acls = true
36 block_public_policy = true
37 ignore_public_acls = true
38 restrict_public_buckets = true
39}
40
41# ---- the Helsinki (fi) node's credential --------------------------------------
42# Hetzner can't assume an EC2 role, so the fi node gets a scoped IAM user whose
43# policy is confined to this one bucket — the shape a non-AWS provider's
44# credential takes in the co-op model. The access key is created here but its
45# secret is written to tofu STATE only (S3, private); it must be pulled from
46# there into the vault, never committed. See outputs.tf.
47
48resource "aws_iam_user" "fi_node" {
49 name = "eleven-dev-mesh-fi"
50}
51
52data "aws_iam_policy_document" "mesh_rw" {
53 statement {
54 sid = "ListMeshBucket"
55 # GetBucketLocation: the hibernation restore (embedded Litestream) resolves
56 # the bucket's region before reading replicas — without it a woken instance
57 # 503s with "cannot lookup bucket region" even though object read/write is
58 # allowed. Bucket-level, so it sits in this ARN-of-the-bucket statement.
59 actions = ["s3:ListBucket", "s3:ListBucketVersions", "s3:GetBucketLocation"]
60 resources = [aws_s3_bucket.mesh.arn]
61 }
62 statement {
63 sid = "ReadWriteMeshObjects"
64 actions = [
65 "s3:GetObject",
66 "s3:PutObject",
67 "s3:DeleteObject",
68 "s3:DeleteObjectVersion",
69 ]
70 resources = ["${aws_s3_bucket.mesh.arn}/*"]
71 }
72}
73
74resource "aws_iam_user_policy" "fi_node" {
75 name = "eleven-dev-mesh-bucket"
76 user = aws_iam_user.fi_node.name
77 policy = data.aws_iam_policy_document.mesh_rw.json
78}
79
80resource "aws_iam_access_key" "fi_node" {
81 user = aws_iam_user.fi_node.name
82}
83