Je suis en train de permuter notre infrastructure en terraform .. Quelle est la meilleure pratique pour gérer réellement les fichiers terraform et leur état? Je réalise que c'est une infrastructure en tant que code et je vais valider mes fichiers .tf git, mais est-ce que je commets aussi tfstate? Cela devrait-il résider quelque part comme S3? Je souhaiterais éventuellement que CI gère tout cela, mais c’est très difficile et cela me demande de trouver les pièces en mouvement pour les fichiers.
Je cherche vraiment à voir comment les gens utilisent réellement ce genre de choses dans la production
Nous utilisons beaucoup Terraform et notre configuration recommandée est la suivante:
Nous vous recommandons vivement de stocker le code Terraform pour chacun de vos environnements (par exemple, stage, prod, qa) dans des ensembles distincts de modèles (et par conséquent, des fichiers .tfstate
séparés). Cela est important pour que vos environnements distincts soient réellement isolés les uns des autres lors de modifications. Sinon, tout en jouant avec du code dans la mise en scène, il est trop facile de faire sauter quelque chose en prod. Voir Terraform, VPC et pourquoi vous voulez un fichier tfstate par env pour une discussion en couleur de pourquoi.
Par conséquent, notre disposition de fichier typique ressemble à ceci:
stage
└ main.tf
└ vars.tf
└ outputs.tf
prod
└ main.tf
└ vars.tf
└ outputs.tf
global
└ main.tf
└ vars.tf
└ outputs.tf
Tout le code Terraform du VPC de scène est placé dans le dossier stage
, tout le code du VPC prod est placé dans le dossier prod
et tout le code qui réside en dehors d’un VPC (utilisateurs IAM, sujets SNS, compartiments S3, par exemple) le dossier global
.
Notez que, par convention, nous divisons généralement notre code Terraform en 3 fichiers:
vars.tf
: variables d'entrée.outputs.tf
: variables de sortie.main.tf
: les ressources réelles.En règle générale, nous définissons notre infrastructure dans deux dossiers:
infrastructure-modules
: Ce dossier contient de petits modules versionnés réutilisables. Considérez chaque module comme un modèle de création d’un élément d’infrastructure unique, tel qu’un VPC ou une base de données.infrastructure-live
: ce dossier contient l’infrastructure réelle et en cours d’exécution qu’il crée en combinant les modules dans infrastructure-modules
. Pensez au code de ce dossier comme aux maisons que vous avez construites à partir de vos plans.Un module Terraform correspond à n’importe quel jeu de modèles Terraform dans un dossier. Par exemple, nous pourrions avoir un dossier appelé vpc
dans infrastructure-modules
qui définit toutes les tables de routage, sous-réseaux, passerelles, ACL, etc. pour un seul VPC:
infrastructure-modules
└ vpc
└ main.tf
└ vars.tf
└ outputs.tf
Nous pouvons ensuite utiliser ce module dans infrastructure-live/stage
et infrastructure-live/prod
pour créer la scène et produire des VPC. Par exemple, voici à quoi pourrait ressembler infrastructure-live/stage/main.tf
:
module "stage_vpc" {
source = "git::[email protected]:gruntwork-io/module-vpc.git//modules/vpc-app?ref=v0.0.4"
vpc_name = "stage"
aws_region = "us-east-1"
num_nat_gateways = 3
cidr_block = "10.2.0.0/18"
}
Pour utiliser un module, vous utilisez la ressource module
et pointez son champ source
sur un chemin local de votre disque dur (par exemple source = "../infrastructure-modules/vpc"
) ou, comme dans l'exemple ci-dessus, sur une URL Git (voir sources du module ). L’avantage de l’URL Git est que nous pouvons spécifier un git sha1 ou une balise spécifique (ref=v0.0.4
). Désormais, non seulement nous définissons notre infrastructure comme un ensemble de petits modules, mais nous pouvons également les mettre à la version et les mettre à jour ou les restaurer avec précaution selon les besoins.
Nous avons créé un certain nombre de Packages d'infrastructure réutilisables, testés et documentés, permettant de créer des VPC, des clusters Docker, des bases de données, etc.
Lorsque vous utilisez Terraform pour créer des ressources (par exemple, instances EC2, bases de données, VPC), il enregistre des informations sur ce qu'il a créé dans un fichier .tfstate
. Pour modifier ces ressources, tous les membres de votre équipe doivent avoir accès à ce même fichier .tfstate
, mais vous ne devez PAS l'archiver dans Git (voir ici pour une explication de la raison ).
Au lieu de cela, nous vous recommandons de stocker les fichiers .tfstate
dans S3 en activant Terraform Remote State , qui enverra/extraira automatiquement les fichiers les plus récents à chaque exécution de Terraform. Assurez-vous de activer le contrôle de version dans votre compartiment S3 afin de pouvoir restaurer les fichiers .tfstate
plus anciens au cas où vous corrompriez la dernière version. Cependant, une remarque importante: Terraform ne fournit pas de verrouillage. Ainsi, si deux membres de l'équipe exécutent terraform apply
en même temps sur le même fichier .tfstate
, ils risquent de remplacer les modifications apportées.
Pour résoudre ce problème, nous avons créé un outil open source appelé Terragrunt , qui est un wrapper fin pour Terraform qui utilise Amazon DynamoDB pour fournir un verrouillage (qui devrait être totalement gratuit pour la plupart des équipes). Check out Ajoutez le verrouillage et la configuration automatiques de l'état à distance à Terraform avec Terragrunt pour plus d'informations.
Nous venons de commencer une série de billets de blog intitulée Un guide complet de Terraform qui décrit en détail toutes les meilleures pratiques que nous avons apprises lors de l’utilisation de Terraform dans le monde réel.
Mise à jour: la série d'articles sur le guide complet de Terraform est devenue si populaire que nous l'avons développée dans un livre intitulé Terraform: Up & Running!
Auparavant, remote config
autorisait cela, mais a maintenant été remplacé par " backends ", donc terraform remote n'est plus disponible.
terraform remote config -backend-config="bucket=<s3_bucket_to_store_tfstate>" -backend-config="key=terraform.tfstate" -backend=s3
terraform remote pull
terraform apply
terraform remote Push
Voir le docs pour plus de détails.
Couvert de manière plus approfondie par @Yevgeny Brikman mais répondant spécifiquement aux questions du PO:
Quelle est la meilleure pratique pour gérer réellement les fichiers et l'état terraform?
Utilisez git pour les fichiers TF. Mais ne pas archiver les fichiers d’État (c’est-à-dire tfstate). Utilisez plutôt Terragrunt
pour synchroniser/verrouiller les fichiers d’état vers S3.
mais est-ce que je commets aussi tfstate?
Non.
Cela devrait-il résider quelque part comme S3?
Oui
Je sais qu’il ya beaucoup de réponses ici, mais mon approche est très différente.
⁃ Modules
⁃ Environment management
⁃ Separation of duties
Modules
Gestion de l'environnement
IaC a rendu le processus SDLC pertinent pour la gestion de l’infrastructure et il n’est pas normal de s’attendre à disposer d’une infrastructure de développement ainsi que d’environnements d’applications de développement.
Séparation des tâches
Si vous êtes dans une petite organisation ou si vous utilisez une infrastructure personnelle, cela ne s'applique pas vraiment, mais cela vous aidera à gérer vos opérations.
Cela aide également à résoudre les problèmes de libération car vous constaterez que certaines ressources changent rarement tandis que d'autres changent tout le temps. La séparation élimine les risques et la complexité.
Cette stratégie établit un parallèle avec la stratégie multi-comptes d’AWS. Ayez une lecture pour plus d'informations.
CI/CD
C'est un sujet en soi, mais Terraform fonctionne très bien dans un bon pipeline. L'erreur la plus courante est de traiter l'IC comme une solution miracle. Techniquement, Terraform ne devrait constituer une infrastructure d'approvisionnement que lors des étapes d'un pipeline d'assemblage. Cela serait distinct de ce qui se passe dans les étapes CI où l'on valide et teste généralement les modèles.
N.B. Écrit sur mobile, veuillez donc excuser les erreurs.
Si vous recherchez toujours la meilleure solution, examinez les espaces de travail qui peuvent remplacer le maintien de la structure de dossiers d'environnement différente. Ces variables peuvent avoir des variables spécifiques à un espace de travail.
En tant que { Yevgeniy Brikman } _ _ { mentionné il est préférable d'avoir une structure de modules.
Avant que les réponses ne soient très solides et instructives, je vais essayer d’ajouter mes 2 centimes ici
Il est plus facile et plus rapide de travailler avec un plus petit nombre de ressources:
terraform plan
et terraform
appliquent tous les deux des appels d'API cloud pour vérifier l'état des ressources.Le rayon de souffle est plus petit avec moins de ressources:
Démarrez votre projet en utilisant l'état distant:
tfstate
dans git est un cauchemar.Essayez de pratiquer une structure et une convention de nommage cohérentes:
Gardez les modules de ressources aussi clairs que possible.
Ne pas coder en dur les valeurs pouvant être transmises en tant que variables ou découvertes à l'aide de sources de données.
Utilisez data
sources et terraform_remote_state
spécifiquement comme liant entre les modules d’infrastructure de la composition.
( article de référence: https://www.terraform-best-practices.com/code-structure )
Exemple:
Il est plus facile et plus rapide de travailler avec un plus petit nombre de ressources, nous présentons donc ci-dessous un code recommandé.
NOTE: juste comme référence à ne pas suivre à la lettre car chaque projet a ses propres caractéristiques
.
├── 1_tf-backend #remote AWS S3 + Dynamo Lock tfstate
│ ├── main.tf
│ ├── ...
├── 2_secrets
│ ├── main.tf
│ ├── ...
├── 3_identities
│ ├── account.tf
│ ├── roles.tf
│ ├── group.tf
│ ├── users.tf
│ ├── ...
├── 4_security
│ ├── awscloudtrail.tf
│ ├── awsconfig.tf
│ ├── awsinspector.tf
│ ├── awsguarduty.tf
│ ├── awswaf.tf
│ └── ...
├── 5_network
│ ├── account.tf
│ ├── dns_remote_zone_auth.tf
│ ├── dns.tf
│ ├── network.tf
│ ├── network_vpc_peering_dev.tf
│ ├── ...
├── 6_notifications
│ ├── ...
├── 7_containers
│ ├── account.tf
│ ├── container_registry.tf
│ ├── ...
├── config
│ ├── backend.config
│ └── main.config
└── readme.md