Bonnes pratiques lors de l'utilisation de Terraform [fermé]

111

Je suis en train de changer notre infrastructure en terraform. Quelle est la meilleure pratique pour gérer réellement les fichiers et l'état de terraform? Je me rends compte que c'est une infrastructure en tant que code, et je vais commettre mes fichiers .tf dans git, mais est-ce que je commets également tfstate? Cela devrait-il résider quelque part comme S3? Je voudrais finalement que CI gère tout cela, mais c'est très difficile et je dois trouver les pièces mobiles pour les fichiers.

Je cherche simplement à voir comment les gens utilisent réellement ce type de choses dans la production

Marc Young
la source

Réponses:

85

Je suis également en train de migrer l'infrastructure AWS existante vers Terraform, je vais donc essayer de mettre à jour la réponse au fur et à mesure de mon développement.

Je me suis fortement appuyé sur les exemples officiels de Terraform et sur de multiples essais et erreurs pour étoffer les domaines dans lesquels j'étais incertain.

.tfstate des dossiers

Terraform config peut être utilisé pour provisionner de nombreuses boîtes sur différentes infrastructures, chacune pouvant avoir un état différent. Comme il peut également être exécuté par plusieurs personnes, cet état doit être dans un emplacement centralisé (comme S3) mais pas git.

Cela peut être confirmé en regardant le Terraform .gitignore.

Contrôle développeur

Notre objectif est de fournir plus de contrôle de l'infrastructure aux développeurs tout en maintenant un audit complet (git log) et la possibilité de vérifier les modifications (pull requests). Dans cet esprit, le nouveau flux de travail d'infrastructure que je vise est:

  1. Base de base des AMI communes qui incluent des modules réutilisables, par exemple des marionnettes.
  2. Infrastructure de base fournie par DevOps à l'aide de Terraform.
  3. Les développeurs modifient la configuration de Terraform dans Git selon les besoins (nombre d'instances; nouveau VPC; ajout de région / zone de disponibilité, etc.).
  4. La configuration Git a été poussée et une demande d'extraction soumise à une vérification de validité par un membre de l'équipe DevOps.
  5. S'il est approuvé, appelle le webhook à CI pour créer et déployer (ne sait pas comment partitionner plusieurs environnements pour le moment)

Edit 1 - Mise à jour sur l'état actuel

Depuis que j'ai commencé cette réponse, j'ai écrit beaucoup de code TF et je me sens plus à l'aise dans notre situation. Nous avons rencontré des bogues et des restrictions en cours de route, mais j'accepte que ce soit une caractéristique de l'utilisation de nouveaux logiciels en évolution rapide.

Disposition

Nous avons une infrastructure AWS compliquée avec plusieurs VPC, chacun avec plusieurs sous-réseaux. La clé pour gérer facilement cela était de définir une taxonomie flexible qui englobe la région, l'environnement, le service et le propriétaire que nous pouvons utiliser pour organiser notre code d'infrastructure (à la fois terraform et marionnette).

Modules

L'étape suivante a été de créer un référentiel git unique pour stocker nos modules terraform. Notre structure de répertoire de niveau supérieur pour les modules ressemble à ceci:

tree -L 1 .

Résultat:

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

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

La colle

Nous avons un deuxième référentiel avec notre gluequi utilise les modules mentionnés ci-dessus. Il est présenté conformément à notre document de taxonomie:

.
├── 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

Au niveau du client, nous avons des .tffichiers spécifiques au compte AWS qui fournissent des ressources globales (comme les rôles IAM); Vient ensuite le niveau de la région avec les clés publiques EC2 SSH; Enfin , dans notre environnement ( dev, stg, prodetc.) sont nos configurations de VPC, la création d'instance et de connexions de peering etc. sont stockés.

Note latérale: comme vous pouvez le voir, je vais à l'encontre de mes propres conseils ci-dessus en gardant terraform.tfstatedans git. C'est une mesure temporaire jusqu'à ce que je passe à S3 mais me convient car je suis actuellement le seul développeur.

Prochaines étapes

Il s'agit toujours d'un processus manuel et pas encore dans Jenkins, mais nous portons une infrastructure assez grande et compliquée et jusqu'à présent tout va bien. Comme je l'ai dit, peu de bugs mais ça va bien!

Edit 2 - Modifications

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

Etat

Les gens m'ont dit à plusieurs reprises que l'État ne devrait pas entrer dans Git - et ils ont raison. Nous avons utilisé cela comme mesure provisoire avec une équipe de deux personnes qui reposait sur la communication et la discipline des développeurs. Avec une équipe plus importante et distribuée, nous exploitons désormais pleinement l'état distant dans S3 avec le verrouillage fourni par DynamoDB. Idéalement, cela sera migré vers consul maintenant, c'est la 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 registre Terraform, nous essayons de les utiliser au moins comme base.

Structure des fichiers

La nouvelle position a une taxonomie beaucoup plus simple avec seulement deux environnements infx - devet prod. Chacun a ses propres variables et sorties, réutilisant nos modules créés ci-dessus. Le remote_statefournisseur aide également à partager les sorties des ressources créées entre les environnements. Notre scénario consiste en des sous-domaines de différents groupes de ressources Azure vers un TLD géré globalement.

├── 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 sauvegardons désormais toujours notre sortie de la terraform plancommande. Nous pouvons inspecter et savoir ce qui sera exécuté sans risque de changements entre les étapes planet apply(bien que le verrouillage aide à cela). N'oubliez pas de supprimer ce fichier de plan car il pourrait contenir des variables "secrètes" en texte brut.

Dans l'ensemble, nous sommes très satisfaits de Terraform et continuons à apprendre et à nous améliorer grâce aux nouvelles fonctionnalités ajoutées.

Ewan
la source
Avez-vous eu de la chance / des problèmes depuis cette réponse? Le vôtre ressemble beaucoup à ce que je vise à faire, mais vous êtes peut-être plus avancé que moi.
Marc Young
3
Je suis curieux de savoir pourquoi vous pensez que les fichiers tfstate ne devraient pas être stockés dans git? Est-ce simplement parce que l'ancien État ne vaut pas la peine d'être sauvé, ou y a-t-il d'autres problèmes?
agbodike
3
@agbodike - Lorsque vous travaillez en tant que développeur unique ou que vous faites partie d'une très petite équipe, tfstate peut être conservé dans git tant qu'il est régulièrement engagé et poussé pour éviter les conflits. Ma prochaine étape consiste à configurer cela conformément à leur documentation sur l' état distant dans S3 (qui dit également: "cela rend le travail avec Terraform dans une équipe compliqué car c'est une source fréquente de conflits de fusion. L'état distant aide à atténuer ces problèmes.") . Comme pour la plupart des choses, une bonne communication d'équipe peut aider à atténuer la plupart / tous les problèmes, quelle que soit la tactique de maintien de l'état :-)
Ewan
1
@ the0ther - J'ai peur que mon référentiel principal soit propriétaire, mais je travaille actuellement sur un référentiel personnel que je rendrai public dans un très proche avenir.
Ewan
2
Une chance sur un repo Git @Ewan? J'adorerais voir ce que tu fais.
David
85

Nous utilisons beaucoup Terraform et notre configuration recommandée est la suivante:

Disposition des fichiers

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 modèles (et par conséquent, des .tfstatefichiers séparés ). Ceci est important pour que vos environnements séparés soient réellement isolés les uns des autres lors des modifications. Sinon, tout en jouant avec du code lors de la mise en scène, il est trop facile de faire exploser quelque chose en prod. Voir Terraform, VPC et pourquoi vous voulez un fichier tfstate par env pour une discussion colorée sur 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 le VPC de scène va dans le stagedossier, tout le code pour le VPC prod va dans le proddossier, et tout le code qui vit en dehors d'un VPC (par exemple les utilisateurs IAM, les sujets SNS, les compartiments S3) va dans le globaldossier .

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

En règle générale, nous définissons notre infrastructure dans deux dossiers:

  1. infrastructure-modules: Ce dossier contient de petits modules réutilisables et versionnés. Considérez chaque module comme un modèle pour créer une seule infrastructure, telle qu'un 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. Considérez le code de ce dossier comme les maisons que vous avez construites à partir de vos plans.

Un module Terraform est n'importe quel ensemble de modèles Terraform dans un dossier. Par exemple, nous pourrions avoir un dossier appelé vpcdans infrastructure-modulesqui 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/stageet infrastructure-live/prodpour créer la scène et produire des VPC. Par exemple, voici ce queinfrastructure-live/stage/main.tf pourrait ressembler:

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 moduleressource et pointez son sourcechamp 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 les sources du module ). L'avantage de l'URL Git est que nous pouvons spécifier un git sha1 ou une balise ( ref=v0.0.4) spécifique . Désormais, non seulement nous définissons notre infrastructure comme un ensemble de petits modules, mais nous pouvons également mettre à jour ces modules et les mettre à jour ou les restaurer soigneusement si nécessaire.

Nous avons créé un certain nombre de produits réutilisables, testés et documentés packages d'infrastructure pour créer des VPC, des clusters Docker, des bases de données, etc., et sous le capot, la plupart d'entre eux ne sont que des modules Terraform versionnés.

Etat

Lorsque vous utilisez Terraform pour créer des ressources (par exemple, des instances EC2, des bases de données, des VPC), il enregistre des informations sur ce qu'il a créé dans un .tfstatefichier. Pour apporter des modifications à ces ressources, tous les membres de votre équipe doivent avoir accès à ce même .tfstatefichier, mais vous ne devez PAS l'archiver dans Git (voir ici pour une explication ).

Au lieu de cela, nous vous recommandons de stocker les .tfstatefichiers dans S3 en activant Terraform Remote State , qui va automatiquement pousser / extraire les derniers fichiers chaque fois que vous exécutez Terraform. Assurez-vous d' activer la gestion des versions dans votre compartiment S3 afin de pouvoir revenir aux .tfstatefichiers plus anciens au cas où vous corrompriez d'une manière ou d'une autre la dernière version. Cependant, une remarque importante: Terraform ne fournit pas de verrouillage . Donc, si deux membres de l'équipe courentterraform apply en même temps sur le même .tfstatefichier, ils peuvent finir par écraser les modifications de l'autre.

Pour résoudre ce problème, nous avons créé un outil open source appelé Terragrunt , qui est un wrapper léger pour Terraform qui utilise Amazon DynamoDB pour fournir le verrouillage (qui devrait être totalement gratuit pour la plupart des équipes). Consultez Ajouter le verrouillage automatique de l'état à distance et la configuration à Terraform avec Terragrunt pour plus d'informations.

Lectures complémentaires

Nous venons de commencer une série d'articles de blog intitulée Un guide complet de Terraform qui décrit en détail toutes les meilleures pratiques que nous avons apprises pour utiliser Terraform dans le monde réel.

Mise à jour: la série d'articles de blog Guide complet de Terraform est devenue si populaire que nous l'avons développée dans un livre intitulé Terraform: Up & Running !

Yevgeniy Brikman
la source
Je pense que c'est la bonne réponse. Utilisez des modules, modifiez-les et séparez les environnements.
wrangler
Est-ce que l'étape de configuration à distance doit être réexécutée chaque fois que vous voulez travailler sur un composant / environnement / module / autre terraform différent si vous n'utilisez pas terragrunt ou un autre wrapper?
jmreicha
@jmreicha: Vous devez exécuter remote configsi vous venez de vérifier vos configurations Terraform ou si vous souhaitez modifier une configuration distante précédente. Terraform 0.9 introduira le concept de backends, ce qui simplifiera beaucoup de choses. Voir ce PR pour plus de détails.
Yevgeniy Brikman
Juste pour que je comprenne - je travaille sur une «scène» d'environnement, puis je commence à travailler sur «prod». J'aurai besoin de réexécuter la remote configcommande pour pointer sur l'état prod. En supposant un état différent par environnement. Est-ce correct? J'attends avec impatience la v0.9.
jmreicha
Si vous envisagez de déployer exactement le même ensemble de .tffichiers dans deux environnements différents, oui, vous devez exécuter remote configchaque fois que vous basculez. Ceci est évidemment très sujet aux erreurs, donc je ne recommande pas d'utiliser cette technique. Au lieu de cela, consultez la disposition de fichier Terraform recommandée dans cet article de blog et comment utiliser les modules Terraform dans cet article de blog .
Yevgeniy Brikman
9

Auparavant remote configautorisé, cela 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

Consultez la documentation pour plus de détails.

Shantanu
la source
La source distante doit-elle être reconfigurée à chaque fois que vous souhaitez travailler sur un composant / environnement / module / autre terraform différent?
jmreicha
6

Couvert plus en profondeur 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 de terraform?

Utilisez git pour les fichiers TF. Mais ne archivez pas les fichiers State (c'est-à-dire tfstate). Utilisez plutôt Terragruntpour la synchronisation / le verrouillage des fichiers d'état sur S3.

mais est-ce que je commets aussi tfstate?

Non.

Cela devrait-il résider quelque part comme S3?

Oui

Snowcrash
la source
2

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éez des modules pour des collections logiques de ressources. Exemple: si votre objectif est de déployer une API, qui nécessite une base de données, des machines virtuelles haute disponibilité, une mise à l'échelle automatique, un DNS, un PubSub et un stockage d'objets, toutes ces ressources doivent être modélisées dans un seul module.
  2. Évitez de créer des modules qui utilisent une seule ressource. Cela peut être fait et cela a été fait et de nombreux modules du registre le font, mais c'est une pratique qui facilite l'accessibilité des ressources plutôt que l'orchestration de l'infrastructure. Exemple: un module pour AWS EC2 aide l'utilisateur à accéder à EC2 en rendant les configurations complexes plus simples à appeler, mais un module comme l'exemple en 1. assiste l'utilisateur lors de l'orchestration de l'infrastructure axée sur les applications, les composants ou les services.
    1. Évitez les déclarations de ressources dans votre espace de travail. Il s'agit davantage de garder votre code en ordre et organisé. Comme les modules sont facilement versionné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 à une dérive car il n'y a pas de modèle commun pour votre infrastructure.
  2. Utilisez 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 modifiez la variable d'environnement (var.stage est populaire), le plan change en fonction de vos besoins. En règle générale, les environnements doivent varier le moins possible, la quantité, l'exposition et la capacité étant généralement les configurations variables. Le développeur peut déployer 1 VM avec 1 cœur et 1 Go de RAM dans une topologie privée, mais la production peut être 3 VM avec 2 cœurs et 4 Go de RAM avec une topologie publique supplémentaire. Vous pouvez bien sûr avoir plus de variantes: dev peut exécuter le processus de base de données sur le même serveur que l'application pour réduire les coûts, mais la production peut avoir une instance de base de données dédiée. Tout cela peut être géré en modifiant une seule variable, des instructions ternaires et une interpolation.

Séparation des tâches

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

  1. Décomposez votre infrastructure par tâches, responsabilités ou équipes. Exemple: contrôle informatique central des services partagés sous-jacents (réseaux virtuels, sous-réseaux, adresses IP publiques, groupes de journaux, ressources de gouvernance, bases de données multi-locataires, clés partagées, etc.) tandis que l'équipe API contrôle uniquement les ressources nécessaires à leur service (VM, LB) , PubSub, etc.) et utilisent les services informatiques centraux via des sources de données et des recherches d'état à distance.
    1. Gérez l'accès des équipes. Exemple: le service informatique central peut avoir des droits d'administrateur, mais l'équipe API n'a accès qu'à un ensemble restreint d'API de cloud public.

Cela aide également à résoudre les problèmes de publication, 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 des parallèles avec la stratégie multi-comptes d'AWS. Lisez pour plus d'informations.

CI / CD

C'est un sujet qui lui est propre, mais Terraform fonctionne très bien dans un bon pipeline. L'erreur la plus courante ici est de traiter l'IC comme une solution miracle. Techniquement, Terraform ne doit provisionner l'infrastructure qu'au cours des étapes d'un pipeline d'assemblage. Cela serait distinct de ce qui se passe dans les étapes de CI où l'on valide et teste généralement les modèles.

NB Écrit sur mobile, veuillez donc excuser toute erreur.

Henry Dobson
la source
0

Avant que les réponses aient été très solides et informatives, je vais essayer d'ajouter mes 2 cents ici

Recommandations courantes pour structurer le code

  1. Il est plus facile et plus rapide de travailler avec un plus petit nombre de ressources:

    • Cmds terraform planetterraform apply effectuent tous deux des appels d'API cloud pour vérifier l'état des ressources.
    • Si vous avez toute votre infrastructure dans une seule composition, cela peut prendre plusieurs minutes (même si vous avez plusieurs fichiers dans le même dossier).
  2. Le rayon de l'explosion est plus petit avec moins de ressources:

    • Isoler les ressources non liées les unes des autres en les plaçant dans des compositions séparées (dossiers) réduit le risque en cas de problème.
  3. Démarrez votre projet en utilisant l'état distant:

  4. Essayez de pratiquer une structure cohérente et une convention de dénomination:

    • Comme le code procédural, Terraform doit être écrit pour que les gens le lisent en premier, la cohérence sera utile lorsque des changements se produiront dans six mois.
    • Il est possible de déplacer des ressources dans un fichier d'état Terraform, mais cela peut être plus difficile à faire si vous avez une structure et une dénomination incohérentes.
  5. Gardez les modules de ressources aussi simples que possible.

  6. Ne codez pas en dur les valeurs qui peuvent être transmises en tant que variables ou découvertes à l'aide de sources de données.

  7. Utilisez des datasources et en terraform_remote_stateparticulier comme un lien entre les modules d'infrastructure au sein 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 vous présentons donc ci-dessous une disposition de code recommandée.

NOTE: juste comme référence à ne pas suivre strictement puisque chaque projet a ses propres spécificités

.
├── 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
Exequiel Barrirero
la source
0

Je pense qu'il y a peu de bonnes pratiques à suivre lors de l'utilisation de terraform pour orchestrer l'infrastructure

  1. N'écrivez plus le même code (réutilisabilité)
  2. Gardez la configuration de l'environnement séparée pour la maintenir facilement.
  3. Utilisez le backend distant s3 (chiffré) et la base de données dynamo pour gérer le verrouillage d'accès concurrentiel
  4. Créez un module et utilisez ce module dans l'infrastructure principale plusieurs fois, c'est comme une fonction réutilisable qui peut être appelée plusieurs fois en passant un paramètre différent.

Gérez plusieurs environnements

La plupart du temps, la méthode recommandée consiste à utiliser l '«espace de travail» de terraform pour gérer les multiples environnements, mais je pense que l'utilisation de l'espace de travail peut varier en fonction du mode de travail dans une organisation. L'autre consiste à stocker le code Terraform pour chacun de vos environnements (par exemple, stage, prod, QA) pour séparer les états de l'environnement. Cependant, dans ce cas, nous copions simplement le même code à plusieurs endroits.

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

J'ai suivi une approche différente pour gérer et éviter la duplication du même code terraform en conservant dans chaque dossier d'environnement car je pense que la plupart du temps, tout l'environnement serait à 90% identique.

├── deployment
 ├── 01-network.tf
 ├── 02-ecs_cluster.tf
 ├── 03-ecs_service.tf
 ├── 04-eks_infra.tf
 ├── 05-db_infra.tf
 ├── 06-codebuild-k8s.tf
 ├── 07-aws-secret.tf
 ├── backend.tf
 ├── provider.tf
 └── variables.tf
├── env
 ├── dev
  ├── dev.backend.tfvar
  └── dev.variables.tfvar
 └── prod
 ├── prod.backend.tfvar
 └── prod.variables.tfvar
├── modules
 └── aws
 ├── compute
  ├── alb_loadbalancer
  ├── alb_target_grp
  ├── ecs_cluster
  ├── ecs_service
  └── launch_configuration
 ├── database
  ├── db_main
  ├── db_option_group
  ├── db_parameter_group
  └── db_subnet_group
 ├── developertools
 ├── network
  ├── internet_gateway
  ├── nat_gateway
  ├── route_table
  ├── security_group
  ├── subnet
  ├── vpc
 └── security
 ├── iam_role
 └── secret-manager
└── templates

Configuration liée aux environnements

Gardez la configuration et les paramètres liés à l'environnement séparés dans un fichier de variables et transmettez cette valeur pour configurer l'infrastructure. par exemple comme ci-dessous

  • dev.backend.tfvar

      region = "ap-southeast-2"
      bucket = "dev-samplebackendterraform"
      key = "dev/state.tfstate"
      dynamo_db_lock = "dev-terraform-state-lock"
  • dev.variable.tfvar

    environment                     =   "dev"
    vpc_name                        =   "demo"
    vpc_cidr_block                  =   "10.20.0.0/19"
    private_subnet_1a_cidr_block    =   "10.20.0.0/21"
    private_subnet_1b_cidr_block    =   "10.20.8.0/21"
    public_subnet_1a_cidr_block     =   "10.20.16.0/21"
    public_subnet_1b_cidr_block     =   "10.20.24.0/21"

Saut conditionnel de la partie infrastructure

Créez une configuration dans un fichier de variable spécifique à env et en fonction de cette variable, décidez de créer ou d'ignorer cette partie. De cette manière, en fonction des besoins, la partie spécifique de l'infrastructure peut être ignorée.

variable vpc_create {
   default = "true"
}

module "vpc" {
  source = "../modules/aws/network/vpc"
  enable = "${var.vpc_create}"
  vpc_cidr_block = "${var.vpc_cidr_block}"
  name = "${var.vpc_name}"
 }

 resource "aws_vpc" "vpc" {
    count                = "${var.enable == "true" ? 1 : 0}"
    cidr_block           = "${var.vpc_cidr_block}"
    enable_dns_support   = "true"
   enable_dns_hostnames = "true"
}

La commande ci-dessous est requise pour initialiser et exécuter les modifications infra pour chaque environnement, cd dans le dossier d'environnement requis.

  terraform init -var-file=dev.variables.tfvar -backend-config=dev.backend.tfvar ../../deployment/

  terraform apply -var-file=dev.variables.tfvar ../../deployment

Pour référence: https://github.com/mattyait/devops_terraform

Mahattam
la source
0

Je n'aime pas l'idée de sous-dossiers car cela entraînera des sources différentes par environnement et cela a tendance à dériver.

La meilleure approche est d'avoir une seule pile pour tous les environnements (disons dev, preprod et prod). Pour travailler sur un seul environnement, utilisez terraform workspace.

terraform workspace new dev

Cela crée un nouvel espace de travail. Cela inclut un fichier d'état dédié et la variable que terraform.workspacevous pouvez utiliser dans votre code.

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${terraform.workspace}"
}

De cette façon, vous obtiendrez des seaux appelés

  • mon-tf-test-bucket-dev
  • my-tf-test-bucket-preprod
  • my-tf-test-bucket-prod

après avoir appliqué aux espaces de travail ci-dessus (à utiliser terraform workspace select <WORKSPACE>pour changer d'environnement). Pour rendre le code même résistant à plusieurs régions, procédez comme suit:

data "aws_region" "current" {}

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${data.aws_region.current.name}-${terraform.workspace}"
}

pour obtenir (pour la région us-east-1)

  • my-tf-test-bucket-us-east-1-dev
  • my-tf-test-bucket-us-east-1-preprod
  • my-tf-test-bucket-us-east-1-prod
Magister Halderian
la source
0

Quelques bonnes pratiques Terraform à suivre:

  1. Évitez le codage en dur: parfois, les développeurs ont créé manuellement des ressources directement. Vous devez marquer ces ressources et utiliser l'importation terraform pour les inclure dans les codes. Un échantillon:

    account_number = "123456789012" account_alias = "mycompany"

  2. Exécutez Terraform à partir d'un conteneur Docker: Terraform publie un conteneur Docker officiel qui vous permet de contrôler facilement la version que vous pouvez exécuter.

Il est recommandé d'exécuter le conteneur Terraform Docker lorsque vous définissez votre tâche de génération dans le pipeline CI / CD.

TERRAFORM_IMAGE=hashicorp/terraform:0.11.7
TERRAFORM_CMD="docker run -ti --rm -w /app -v ${HOME}/.aws:/root/.aws -v ${HOME}/.ssh:/root/.ssh -v `pwd`:/app $TERRAFORM_IMAGE"

Pour en savoir plus, veuillez consulter mon blog: https://medium.com/tech-darwinbox/how-darwinbox-manages-infrastructure-at-scale-with-terraform-371e2c5f04d3

ND1772
la source
0

J'aimerais contribuer à ce fil.

  • Il s'agira probablement d'AWS S3 + DynamoDB, sauf si vous utilisez Terraform Cloud.
  • Infrastructure séparée (réseau + RBAC) des backends de production et non-prod.
  • Prévoyez de désactiver l'accès aux fichiers d'état (accès réseau et RBAC) depuis l'extérieur d'un réseau désigné (par exemple, pool d'agents de déploiement).
  • Ne conservez pas l'infrastructure backend Terraform avec l'environnement d'exécution. Utilisez un compte séparé.
  • Activez la gestion des versions des objets sur vos backends Terraform pour éviter de perdre les modifications et les fichiers d'état, et afin de conserver l'historique des états Terraform.

Dans certains cas particuliers, un accès manuel aux fichiers d'état Terraform sera requis. Des opérations telles que la refactorisation, la rupture de modifications ou la correction de défauts nécessiteront l'exécution d'opérations d'état Terraform par le personnel d'exploitation. Pour de telles occasions, prévoyez un accès contrôlé extraordinaire à l'état Terraform à l'aide d'un hôte bastion, d'un VPN, etc.

Consultez un blog de bonnes pratiques plus long qui couvre cela en détails, y compris des instructions pour les pipelines CI / CD.

Piotr Gwiazda
la source
-1

Si vous êtes toujours à la recherche de la meilleure solution, jetez un œil aux espaces de travail qui peuvent remplacer le maintien de différentes structures de dossiers d'environnement peuvent avoir des variables spécifiques à l'espace de travail.

Comme Yevgeniy Brikman l'a mentionné, il est préférable d'avoir une structure de modules.

Rajendra
la source
-1

Utilisez le cloud terraform pour gérer et enregistrer les états, ainsi que les conseils ci-dessus.

Den Zalman
la source