# Module `minio_app` — une app déclare SES buckets depuis SON dépôt. # Décisions : factory/doc/adr/20260726-stockage-objet-minio.md resource "minio_s3_bucket" "app" { for_each = toset(var.buckets) bucket = each.key acl = "private" # l'accès passe par des URL présignées force_destroy = false # détruire un bucket doit être un geste explicite } resource "minio_iam_policy" "app" { name = "${var.app}-app" policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"] Resource = [for b in var.buckets : "arn:aws:s3:::${b}/*"] }, { Effect = "Allow" Action = ["s3:ListBucket", "s3:GetBucketLocation"] Resource = [for b in var.buckets : "arn:aws:s3:::${b}"] }, ] }) } resource "random_password" "app" { length = 40 special = false # les outils S3 transportent mal certains caractères en URL } resource "minio_iam_user" "app" { name = "${var.app}-app" secret = random_password.app.result force_destroy = false # une rotation ne recrée pas l'utilisateur : les objets gardent leur propriétaire } resource "minio_iam_user_policy_attachment" "app" { user_name = minio_iam_user.app.id policy_name = minio_iam_policy.app.id } # Lu par le pod de l'app — `app_policy` lui accorde déjà ce chemin. resource "vault_kv_secret_v2" "app" { mount = "kvv2" name = "minio/${var.app}" data_json = jsonencode({ MINIO_ENDPOINT = var.endpoint MINIO_BUCKET = var.buckets[0] MINIO_BUCKETS = join(",", var.buckets) MINIO_ACCESS_KEY = minio_iam_user.app.id MINIO_SECRET_KEY = random_password.app.result }) }