eleven / ocho Public

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

Plain git — no account needed to clone.

Download

Download this file

1# πŸ€– The blob MIRROR bucket (federated blobs Phase A, #992 β€”
2# docs/federated-blob-storage.md): the second copy of every store-backed
3# attachment, on the second provider. The PRIMARY blob store is Hetzner
4# Object Storage β€” enabled and credentialed in the Hetzner console, since
5# neither the hcloud provider nor this AWS one can manage it; this file is
6# the AWS half only.
7#
8# Versioning is deliberately OFF, unlike the hibernation bucket beside it:
9# blobs are write-once (an id is never rewritten, so versions can't help),
10# and a delete here is member-initiated GC β€” retaining a deleted member's
11# media as noncurrent versions would quietly betray the deletion. When a
12# blob goes, both copies actually go.
13
14resource "aws_s3_bucket" "production_blob_mirror" {
15 bucket = "eleven-production-blob-mirror-${local.account_id}"
16}
17
18resource "aws_s3_bucket_public_access_block" "production_blob_mirror" {
19 bucket = aws_s3_bucket.production_blob_mirror.id
20
21 block_public_acls = true
22 block_public_policy = true
23 ignore_public_acls = true
24 restrict_public_buckets = true
25}
26
27# TLS-only, same shape as the hibernation bucket: deny-only grants nothing
28# public, so it attaches fine under the full access block above.
29data "aws_iam_policy_document" "production_blob_mirror_tls_only" {
30 statement {
31 sid = "DenyInsecureTransport"
32 effect = "Deny"
33 actions = ["s3:*"]
34 resources = [
35 aws_s3_bucket.production_blob_mirror.arn,
36 "${aws_s3_bucket.production_blob_mirror.arn}/*",
37 ]
38
39 principals {
40 type = "*"
41 identifiers = ["*"]
42 }
43
44 condition {
45 test = "Bool"
46 variable = "aws:SecureTransport"
47 values = ["false"]
48 }
49 }
50}
51
52resource "aws_s3_bucket_policy" "production_blob_mirror" {
53 bucket = aws_s3_bucket.production_blob_mirror.id
54 policy = data.aws_iam_policy_document.production_blob_mirror_tls_only.json
55}
56
57# The instances' mirror credentials (LCHAT_BLOB_S3_MIRROR_ACCESS_KEY /
58# _SECRET_KEY): object rw on this bucket only β€” no List, because the mirror
59# and audit sweeps address every object by id straight from the blobs table
60# (HeadObject rides the s3:GetObject grant). Key minted by hand
61# (`aws iam create-access-key`), sealed into the vault β€” never in tofu state.
62resource "aws_iam_user" "blob_mirror_production" {
63 name = "blob-mirror-production"
64}
65
66data "aws_iam_policy_document" "blob_mirror_production" {
67 statement {
68 sid = "ReadWriteBlobMirrorObjects"
69 actions = [
70 "s3:GetObject",
71 "s3:PutObject",
72 "s3:DeleteObject",
73 ]
74 resources = ["${aws_s3_bucket.production_blob_mirror.arn}/*"]
75 }
76}
77
78resource "aws_iam_user_policy" "blob_mirror_production" {
79 name = "blob-mirror-production-bucket"
80 user = aws_iam_user.blob_mirror_production.name
81 policy = data.aws_iam_policy_document.blob_mirror_production.json
82}
83
84output "production_blob_mirror_bucket" {
85 value = aws_s3_bucket.production_blob_mirror.bucket
86}
87