$ cat terraform-state-organization.md

Ένα Terraform state ή πολλά; Μια πρακτική απάντηση.

· 5 λεπτά · terraform

Κάθε Terraform codebase φτάνει στο ίδιο σταυροδρόμι: ένα μεγάλο state ή πολλά; Ο πιο διαδεδομένος τρόπος split — ανά ομάδα — μοιάζει οργανωμένος και είναι σχεδόν πάντα λάθος.

Ο κλασικός μονόλιθος ξεκινάει το ίδιο παντού. Πρώτη μέρα: ένα main.tf, ένα VPC, ένα RDS. Δεύτερος χρόνος: 4.000 resources σε ένα state, το terraform plan τρέχει εννιά λεπτά, και κάθε αλλαγή σε security group κλειδώνει το αρχείο για όλους.

Το ένστικτο λέει split. Σωστό ένστικτο. Ο τρόπος που οι περισσότερες ομάδες κάνουν split είναι λάθος.

Γιατί το «split ανά ομάδα» αποτυγχάνει

Η ενστικτώδης κατανομή ακολουθεί το οργανόγραμμα:

terraform/
  backend-team/
  frontend-team/
  data-team/
  platform-team/

Σπάνε τρία πράγματα, με αυτή τη σειρά:

  1. Τα κοινόχρηστα resources χρειάζονται ιδιοκτήτη. Ποιανού state έχει το VPC; Το shared S3 bucket; Το IAM role που χρησιμοποιεί το CI όλων; Οι διαμάχες ιδιοκτησίας μετατρέπονται σε PRs που μένουν μια εβδομάδα ανοιχτά.
  2. Τα cross-state references πολλαπλασιάζονται. Το RDS subnet group του backend χρειάζεται το VPC ID του platform, οπότε διαβάζει το platform state μέσω data "terraform_remote_state". Τώρα το plan του backend σπάει κάθε φορά που αλλάζουν τα outputs του platform.
  3. Τα reorgs σαπίζουν τη δομή. Το data team συγχωνεύεται με το platform. Η δομή φακέλων είναι πια απολίθωμα. Ή θα μετονομάσεις (και θα ξαναγράψεις κάθε remote-state αναφορά) ή θα ζεις με ένα ψέμα.

Το οργανόγραμμα αλλάζει κάθε χρόνο. Η υποδομή αλλάζει με άλλο ρυθμό. Μην τα δένεις.

Σπάσε ανά lifecycle

Ομαδοποίησε resources ανάλογα με πόσο συχνά αλλάζουν, όχι ποιος τα έχει. Μια ρεαλιστική default δομή για τα περισσότερα cloud accounts:

terraform/
  # Αλλάζει σχεδόν ποτέ. Manual approval για plan.
  bootstrap/         # το ίδιο το state bucket, IAM roots, org-level SCPs

  # Αλλάζει ~ κάθε τρίμηνο. Με προσοχή.
  network/           # VPCs, subnets, transit gateways, DNS zones
  data/              # RDS, ElastiCache, S3 buckets με business δεδομένα

  # Αλλάζει ~ εβδομαδιαία. Auto-apply on merge.
  platform/          # EKS clusters, ECR repos, shared IAM roles

  # Αλλάζει ~ καθημερινά. Auto-apply ανά app.
  apps/
    api/
    worker/
    web/

Γιατί δουλεύει:

Πώς μιλούν τα layers μεταξύ τους

Τα κάτω layers εκθέτουν outputs. Τα πάνω layers τα διαβάζουν ως data sources.

# network/outputs.tf
output "vpc_id" {
  value = aws_vpc.main.id
}
output "private_subnet_ids" {
  value = aws_subnet.private[*].id
}

# platform/main.tf
data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "acme-tf-state"
    key    = "network/terraform.tfstate"
    region = "eu-south-2"
  }
}

module "eks" {
  source     = "./modules/eks"
  vpc_id     = data.terraform_remote_state.network.outputs.vpc_id
  subnet_ids = data.terraform_remote_state.network.outputs.private_subnet_ids
}

Το βέλος της εξάρτησης δείχνει μόνο προς τα κάτω — apps εξαρτώνται από platform, platform από network, network από bootstrap. Ποτέ ανάποδα. Αν σου περάσει η σκέψη να διαβάσεις apps state από το platform, έχεις βάλει κάτι σε λάθος layer.

Ευρετικός κανόνας. Αν δύο resources αλλάζουν σχεδόν πάντα μαζί στο ίδιο PR, ανήκουν στο ίδιο state. Αν αλλάζουν με διαφορετικό ρυθμό, σπάσε τα — ακόμη κι αν τα έχει ο ίδιος άνθρωπος.

Τι παίζει με τα workspaces;

Χρησιμοποίησε terraform workspace για environments (dev / staging / prod) μέσα σε ένα layer. Μη το χρησιμοποιείς ως υποκατάστατο για split layer — τα workspaces μοιράζονται κώδικα, providers και lock file. Το split του state και τα workspaces είναι ορθογώνια εργαλεία που λύνουν διαφορετικά προβλήματα.

Σημειώσεις στο tooling


Είσαι στη μέση ενός split, ή ξεκινάς από έναν 4.000-resource μονόλιθο; Έχουμε ξεμπλέξει αρκετά τέτοια — πες μας τι σε δυσκολεύει.