Meilleures pratiques lors de L'utilisation de Terraform

je suis en train de changer notre infrastructure en terraform. Quelle est la meilleure pratique pour gérer les fichiers terraform et l'état? Je réalise que c'est l'infrastructure En tant que code, et je vais m'engager .TF file dans git, mais est-ce que je m'engage aussi dans tfstate? Ça devrait être quelque part comme S3 ? J'aimerais que CI gère tout ça, mais c'est loin d'être facile et ça m'oblige à trouver les pièces mobiles pour les fichiers.

je suis vraiment juste à la recherche pour voir combien de gens il y a réellement utiliser ce type de substance dans la production de

55
demandé sur the0ther 2015-10-15 23:03:53

5 réponses

je suis aussi dans un état de migration de l'infrastructure AWS pour transformer le terrain doit donc viser à la mise à jour de la réponse que je développe.

j'ai beaucoup compté sur le Terraform officiel exemples et de multiples essais et erreurs pour étoffer les domaines dans lesquels j'ai été incertain.

.tfstate fichiers

Terraform config peut être utilisé pour fournir de nombreuses boîtes sur des infrastructures différentes, dont chacune pourrait avoir un état différent. Comme il peut également être dirigé par plusieurs personnes, cet état devrait être centralisé (comme S3) mais pas git.

cela peut être confirmé en regardant la Terraform .gitignore .

Développeur de contrôle

Notre objectif est de fournir plus de contrôle de l'infrastructure de les développeurs tout en maintenant un audit complet (git log) et la possibilité de changements de contrôle de santé mentale (pull requests). Avec cela à l'esprit le nouveau workflow d'infrastructure que je vise est:

  1. fondation de Base des ARM courants qui comprennent des modules réutilisables, p.ex. marionnettes.
  2. Core infrastructure provided by DevOps using Terraform.
  3. les développeurs modifient la configuration Terraform dans Git au besoin (nombre d'instances; nouveau VPC; ajout de la région / zone de disponibilité, etc.).
  4. git configuration poussée et une demande de pull soumise à contrôle de bon sens par un membre de la brigade DevOps.
  5. si approuvé, appelle webhook à CI pour construire et déployer (ne sait pas comment partager plusieurs environnements à ce moment)

Edition 1 - mise à Jour sur l'état actuel

Depuis le début de cette réponse, j'ai écrit beaucoup de code TF et se sentir plus à l'aise dans notre état de choses. Nous avons relevé des bogues et des restrictions en cours de route, mais je reconnais que c'est une caractéristique de l'utilisation de nouveaux logiciels qui changent rapidement.

Mise en page

nous avons une infrastructure AWS compliquée avec plusieurs VPC chacun avec plusieurs sous-réseaux. La définition d'une taxinomie souple qui englobe la région, l'environnement, les services et les propriétaire que nous pouvons utiliser pour organiser notre code d'infrastructure (à la fois terraform et puppet).

Modules

la prochaine étape était de créer un dépôt git unique pour stocker nos modules terraform. Notre structure dir de haut niveau pour les modules ressemble à ceci:

tree -L 1 . . ├── README.md ├── aws-asg ├── aws-ec2 ├── aws-elb ├── aws-rds ├── aws-sg ├── aws-vpc └── templates

chacun définit quelques valeurs par défaut saines mais les expose comme des variables qui peuvent être écrasées par notre "colle".

colle

nous avons un second dépôt avec notre glue qui utilise les modules mentionnés ci-dessus. Il est conforme à notre taxinomie:

. ├── README.md ├── clientA │   ├── eu-west-1 │   │   └── dev │   └── us-east-1 │   └── dev ├── clientB │   ├── eu-west-1 │   │   ├── dev │   │   ├── ec2-keys.tf │   │   ├── prod │   │   └── terraform.tfstate │   ├── iam.tf │   ├── terraform.tfstate │   └── terraform.tfstate.backup └── clientC ├── eu-west-1 │   ├── aws.tf │   ├── dev │   ├── iam-roles.tf │   ├── ec2-keys.tf │   ├── prod │   ├── stg │   └── terraform.tfstate └── iam.tf

à l'intérieur du niveau client nous avons des fichiers .tf spécifiques au compte AWS qui fournissent des ressources globales (comme les rôles IAM); suivant est le niveau régional avec les clés publiques EC2 SSH; enfin dans notre environnement ( dev , stg , prod etc) sont nos configurations VPC, la création d'instance et les connexions de peering etc. sont stockées.

Side Note: comme vous pouvez le voir, je vais à l'encontre de mon propre conseil ci-dessus de garder terraform.tfstate en git. Il s'agit d'une mesure temporaire jusqu'à ce que je passe à S3 mais me convient car je suis actuellement le seul développeur.

Prochaines Étapes

C'est c'est toujours un processus manuel et pas encore à Jenkins mais nous portons une infrastructure assez grande et compliquée et jusqu'à présent si bonne. Comme je l'ai dit, peu d'insectes mais ça va bien!

Edition 2 - Les Modifications

Cela fait presque un an que j'ai écrit cette réponse initiale et L'état de Terraform et de moi-même a changé de manière significative. Je suis maintenant à une nouvelle position en utilisant Terraform pour gérer un cluster D'Azur et Terraform est maintenant v0.10.7 .

État

les gens m'ont dit à plusieurs reprises l'État devrait pas aller en Git - et ils sont corrects. Nous nous en sommes servis comme mesure provisoire avec une équipe de deux personnes qui s'appuyait sur la communication avec les développeurs et la discipline. Avec une équipe plus importante et distribuée, nous exploitons pleinement l'état distant en S3 avec locking fourni par DynamoDB. Idéalement, ce sera migré au consul maintenant il est v1.0 pour couper les fournisseurs de cloud cross.

Modules

auparavant, nous avons créé et utilisé des modules internes. C'est toujours le cas, mais avec l'avènement et la croissance du Terraform registry nous essayons de les utiliser comme au moins une base.

structure du Fichier

la nouvelle position a un beaucoup plus simple taxonomie avec seulement deux environnements infx - dev et prod . Chacun a ses propres variables et sorties, en réutilisant nos modules créés ci-dessus. Le fournisseur remote_state aide également à partager les sorties des ressources créées entre les environnements. Notre scénario est des sous-domaines dans différents groupes de ressources azures à un TLD géré à l'échelle mondiale.

├── main.tf ├── dev │   ├── main.tf │   ├── output.tf │   └── variables.tf └── prod ├── main.tf ├── output.tf └── variables.tf

Planification

encore une fois avec les défis supplémentaires d'une équipe distribuée, nous enregistrons maintenant toujours notre sortie de la commande terraform plan . Nous pouvons inspecter et savoir ce qui sera exécuté sans risque de changements entre l'étape plan et apply (bien que le verrouillage aide avec cela). N'oubliez pas de supprimer ce fichier de plan car il pourrait contenir des variables "secrètes" en texte clair.

dans l'ensemble, nous sommes très heureux avec Terraform et continuer à apprendre et à améliorer avec le nouvelles fonctionnalités ajoutées.

49
répondu Ewan 2017-10-17 15:19:13

nous utilisons Terraform lourdement et notre configuration recommandée est la suivante:

Fichier de mise en page

nous vous recommandons fortement de stocker le code Terraform pour chacun de vos environnements (par exemple stage, prod, qa) dans des ensembles séparés de gabarits (et donc des fichiers séparés .tfstate ). C'est important pour que vos environnements séparés soient réellement isolés les uns des autres tout en apportant des changements. Autrement, tout en jouant avec un peu de code dans la mise en scène, c'est trop facile de faire exploser quelque chose dans prod aussi. Voir Terraform, VPC, et pourquoi vous voulez un fichier tfstate par env pour une discussion colorée 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 pour la CPV de l'étape va dans le dossier stage , tout le code pour la CPV prod va dans le dossier prod , et tout le code qui vit en dehors d'une CPV (par ex. IAM users, SNS topics, S3 buckets) va dans 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.

Modules

typiquement, nous définissons notre infrastructure En deux dossiers:

  1. infrastructure-modules : ce dossier contient de petits modules réutilisables suivis en versions. Pensez à chaque module comme un plan directeur pour la création d'un seul élément d'infrastructure, comme une VPC ou une base de données.
  2. infrastructure-live : ce dossier contient l'infrastructure réelle en cours d'exécution, qu'il crée en combinant les modules dans infrastructure-modules . Pensez au code dans ce dossier comme les maisons que vous avez construites à partir de vos plans.

a module Terraform est juste n'importe quel ensemble de gabarits Terraform dans un dossier. Par exemple, nous pourrions avoir un dossier appelé vpc dans infrastructure-modules qui définit toutes les tables de routes, sous-réseaux, passerelles, ACLs, etc pour un seul VPC:

infrastructure-modules
  └ vpc
    └ main.tf
    └ vars.tf
    └ outputs.tf

nous pouvons alors utiliser ce module dans infrastructure-live/stage et infrastructure-live/prod pour créer la scène et prod VPCs. Pour exemple, voici ce que infrastructure-live/stage/main.tf pourrait ressembler à:

module "stage_vpc" {
  source = "git::git@github.com: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 vers un chemin local sur votre disque dur (par exemple source = "../infrastructure-modules/vpc" ) ou, comme dans l'exemple ci-dessus, une URL Git (voir module sources ). L'avantage de L'URL Git est que nous pouvons spécifier un git sha1 ou une balise ( ref=v0.0.4 ). Maintenant, non seulement nous définir notre infrastructure comme un tas de petits modules, mais nous pouvons modifiez ces modules et mettez-les à jour ou faites-les reculer au besoin.

nous avons créé un certain nombre de paquets D'Infrastructure réutilisables, testés et documentés" 1519710920 pour créer des VPC, des clusters de dockers, des bases de données, et ainsi de suite, et sous le capot, la plupart d'entre eux ne sont que des modules terraformés suivis en versions.

État

lorsque vous utilisez Terraform pour créer des ressources (par exemple EC2 instances, bases de données, VPCs), il enregistre information sur ce qu'il a créé dans un fichier .tfstate . Pour apporter des changements à ces ressources, tout le monde dans votre équipe a besoin d'accéder à ce même fichier .tfstate , mais vous ne devriez pas le vérifier dans Git (voir ici pour une explication pourquoi ).

au lieu de cela, nous vous recommandons de stocker les fichiers .tfstate dans S3 en activant État à distance Terraform , qui poussera/tirera automatiquement les derniers fichiers à chaque fois que vous exécutez Terraform. Faire sûr de activer la versioning dans votre seau S3 de sorte que vous pouvez retourner aux fichiers plus anciens .tfstate au cas où vous quelque peu corrompre la dernière version. Cependant, une note 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 peuvent finir par s'écraser mutuellement.

Pour résoudre ce problème, nous avons créé un outil open source appelé Terragrunt , qui est un emballage mince pour Terraform qui utilise Amazon DynamoDB pour fournir le verrouillage (qui devrait être complètement libre pour la plupart des équipes). Cliquez sur ajoutez le verrouillage Automatique À Distance et la Configuration à Terraform avec Terragrunt pour plus d'informations.

Lire la suite

nous venons de commencer une série de billets de blog appelé un guide complet pour Terraform que décrit en détail toutes les meilleures pratiques que nous avons apprises pour utiliser Terraform dans le monde réel.

mise à Jour: le Guide Complet pour transformer le terrain après le blog de la série a tellement de succès que nous avons développé dans un livre intitulé Terraform: Up & Running !

58
répondu Yevgeniy Brikman 2017-05-23 12:34:33

avec remote config , ceci est devenu beaucoup plus simple:

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.

9
répondu Shantanu 2016-07-09 18:25:30

couvert plus en détail par @Yevgeny Brikman mais répondant spécifiquement aux questions de L'OP:

What's the best practice for actually managing the terraform files and state?

utilisez git pour les fichiers TF. Mais ne Vérifiez pas les fichiers de l'État dans (c.-à-d. tfstate). Utilisez plutôt Terragrunt pour la synchronisation / verrouillage des fichiers d'état vers S3.

but do I commit tfstate as well? 

Pas de.

Should that reside somewhere like S3?

Oui

4
répondu Snowcrash 2017-06-19 10:47:06

je sais qu'il y a beaucoup de réponses ici, mais mon approche est assez différente.

⁃   Modules
⁃   Environment management 
⁃   Separation of duties

Modules

  1. créer des modules pour les collections logiques de ressources. Exemple: si votre objectif est de déployer une API, qui nécessite un DB, un VMS HA, un autoscaling, un DNS, un PubSub et un stockage objet, alors toutes ces ressources doivent être rassemblées dans un seul module.
  2. éviter de créer des modules qui utiliser une seule ressource. Cela peut être fait et cela a déjà été fait, et bon nombre des modules du registre le font, mais c'est une pratique qui aide à l'accessibilité des ressources plutôt qu'à l'orchestration de l'infrastructure. Exemple: un module pour AWS EC2 aide l'utilisateur à accéder à EC2 en rendant les configurations complexes plus simples à invoquer mais un module comme l'exemple en 1. aide l'utilisateur lors de l'orchestration d'une application, d'un composant ou d'une infrastructure axée sur le service.
    1. éviter la ressource déclarations dans votre espace de travail. Il s'agit plutôt de garder votre code bien rangé et organisé. Comme les modules sont facilement versionés, vous avez plus de contrôle sur vos versions.

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 à avoir une infrastructure de développement ainsi que des environnements d'applications de développement.

  1. N'utilisez pas de dossiers pour gérer vos environnements IaC. Cela conduit à dériver car il n'y a pas de modèle commun pour votre infrastructure.
  2. utilise un seul espace de travail et des variables pour contrôler les spécifications de l'environnement. Exemple: écrivez vos modules de façon à ce que lorsque vous changez la variable d'environnement (var.la scène est populaire) le plan change pour s'adapter à vos besoins. Généralement, les environnements devraient varier le moins possible avec la quantité, l'exposition et la capacité étant généralement les configurations variables. Dev peut déployer 1 VM avec 1 core et 1 Go de RAM en topologie privée, mais la production peut être de 3 VM avec 2 core et 4 Go de RAM avec une topologie publique supplémentaire. Vous pouvez bien sûr avoir plus de variation: dev peut exécuter le processus de base de données sur le même serveur que l'application pour économiser des coûts, mais la production peut avoir une instance DB dédiée. Tout cela peut être géré en changeant une seule variable, les déclarations ternaires et l'interpolation.

" séparation des fonctions

si vous êtes dans une petite organisation ou si vous exploitez une infrastructure personnelle, cela ne s'applique pas vraiment, mais cela vous aidera à gérer vos opérations.

  1. répartissez votre infrastructure par tâches, responsabilités ou équipes. Exemple: contrôle central des TI sous-jacents aux services partagés (réseaux virtuels, sous-réseaux, adresses IP publiques, groupes de logs, ressources de gouvernance, locataires DBs, clés, etc.) tandis que L'équipe API ne contrôle que les ressources nécessaires à leur service (VMs, LBs, PubSub, etc.) et consomme ses Services centraux par le biais de sources de données et de recherches À Distance.
    1. Gouverner l'équipe d'accès. Exemple: L'IT Central peut avoir des droits admin mais L'équipe API n'a accès qu'à un ensemble restreint d'API de cloud public.

cela aide aussi avec les préoccupations de libération que vous trouverez quelques ressources changent rarement, tandis que d'autres changent tout le temps. La séparation élimine le risque et la complexité.

cette stratégie établit des parallèles avec la stratégie multi-comptes D'AWS. À lire pour plus d'info.

CI / CD

C'est un sujet à part, mais Terraform fonctionne très bien dans un bon pipeline. L'erreur la plus courante ici est de traiter L'IC comme une balle en argent. Sur le plan technique, Terraform ne devrait être Infrastructure d'approvisionnement pendant les étapes d'un pipeline d'assemblage. Cela serait distinct de ce qui se produit aux étapes de L'assurance-récolte, où l'on valide et teste habituellement les modèles.

N.B. écrit sur mobile veuillez excuser toute erreur.

0
répondu Henry Dobson 2018-09-22 15:45:52