Co-Authored-By: Claude Fable 5.1 <[email protected]>
4.5 KiB
minio_app — déclarer ses buckets depuis SON dépôt
Chacun son périmètre : les buckets d'une application appartiennent au dépôt de
cette application. Ce module standardise la déclaration, il ne la détient
pas — sans lui, chaque bucket de chaque app deviendrait une PR sur tools.
Usage
Dans l'iac/ de l'app :
# Le provisionneur MinIO : des droits d'administration MINIMAUX (créer un
# bucket, un compte de service, une politique), jamais le root — qui, lui, ne
# sort pas du pipeline `minio`.
data "vault_kv_secret_v2" "minio_provisioner" {
mount = "kvv2"
name = "minio/provisioner"
}
provider "minio" {
minio_server = "s3.arcodange.fr"
minio_user = data.vault_kv_secret_v2.minio_provisioner.data["MINIO_ACCESS_KEY"]
minio_password = data.vault_kv_secret_v2.minio_provisioner.data["MINIO_SECRET_KEY"]
minio_ssl = true
}
module "stockage" {
source = "git::ssh://[email protected]:2222/arcodange-org/tools.git//minio/iac/modules/minio_app?depth=1&ref=main"
app = "mon-app" # = le nom de son rôle Vault
buckets = ["mon-app-fichiers"]
providers = { minio = minio }
}
Puis, côté chart : une VaultStaticSecret sur kvv2/minio/<app> et l'injection
des variables dans le Deployment.
Ce que le module garantit
- les buckets sont privés — l'accès passe par des URL présignées ;
- les téléversements abandonnés sont ramassés au bout d'un jour (voir plus bas : c'est de l'hygiène de protocole, pas un choix de l'app) ;
- le compte de service ne peut rien toucher d'autre que ces buckets-là ;
- le compte de service peut refermer et abandonner un téléversement en
parts —
ListMultipartUploadPartsetAbortMultipartUpload, les deux actions quePutObjectne couvre pas (sans elles, l'assemblage rend 403 et aucun objet de plus d'une part n'arrive jamais — mesuré le 2026-09-07) ; - ses clés vont dans
kvv2/minio/<app>, que le module Vault central autorise déjà l'app à lire (règle inconditionnelle : le chemin porte le nom de l'app, donc il ne peut exposer que ses propres clés).
Plusieurs buckets
C'est le cas courant : deux contenus aux cycles de vie différents méritent deux buckets. Il suffit de les lister — le compte de service existant gagne l'accès, sans nouvelle clé.
Ce que le module ne fait PAS
Il ne pose ni quota, ni expiration de contenu, ni versioning : ces choix appartiennent à l'app et varient d'un bucket à l'autre. « Ces vidéos se purgent à 90 jours » est une décision de produit, elle se prend dans le dépôt du produit.
⚠ L'exception, et la ligne qu'elle trace
Ce module pose une seule règle de cycle de vie :
AbortIncompleteMultipartUpload à 1 jour, sur chaque bucket qu'il crée.
Elle a l'air de contredire le paragraphe ci-dessus. Elle ne le contredit pas — elle en précise la frontière, et c'est la question « à QUOI cette connaissance appartient-elle ? » qui tranche :
- une expiration de contenu porte sur des objets que l'app a voulus, qu'elle montre, et dont elle seule sait combien de temps ils valent. Elle varie d'une app à l'autre : elle est chez l'app ;
- un téléversement en plusieurs parts jamais refermé n'est le contenu de
personne. Ce sont des morceaux qu'aucune API ne montre — ni
mc ls, ni la console — laissés par un navigateur qui a fermé l'onglet. Aucune app ne veut les garder, et aucune ne peut les voir depuis son propre code. C'est un déchet de PROTOCOLE, produit par le mécanisme même du bucket : il est chez celui qui crée les buckets.
Le test pratique : si la réponse à « combien de temps ? » demande de connaître le produit, c'est chez l'app. Ici, la réponse ne demande que de connaître S3 — passé l'expiration des URL signées, un téléversement en cours ne peut plus rien recevoir, il occupe seulement.
⚠ Le délai n'est pas paramétrable, et c'est voulu (YAGNI) : un seul cas existe. Le jour où une app signe des parts pour plus de 24 h, ce sera le déclencheur pour en faire une variable — pas avant.
Plancher de version
⚠ Ce module exige aminueza/minio >= 3.10.0 : abort_incomplete_multipart_upload
y est apparu (mesuré en interrogeant le schéma du provider version par version —
3.9.0 ne l'a pas). Un appelant resté plus bas se verra dire, dès tofu init :
no available releases match the given constraints 3.3.0, >= 3.10.0
… ce qui NOMME la version à atteindre, au lieu d'un « unsupported block type » au plan, qui ne l'aurait pas dite.