Infrastructure Terraform
Terraform est un outil logiciel open-source d’infrastructure as code qui vous permet de créer, modifier et améliorer votre infrastructure de manière sûre et prévisible.
Le générateur d’infrastructure Terraform crée un projet d’infrastructure Terraform. L’application générée inclut les meilleures pratiques de sécurité grâce aux vérifications de sécurité Checkov.
Utilisation
Section intitulée « Utilisation »Générer un projet Terraform
Section intitulée « Générer un projet Terraform »Vous pouvez générer un nouveau projet Terraform de deux manières :
Exécuter ce générateur@aws/nx-plugin:terraform#project
pnpm nx g @aws/nx-plugin:terraform#project yarn nx g @aws/nx-plugin:terraform#project npx nx g @aws/nx-plugin:terraform#project bunx nx g @aws/nx-plugin:terraform#project- Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
- Ouvrez la console Nx dans VSCode
- Cliquez sur
Generate (UI)dans la section "Common Nx Commands" - Recherchez
@aws/nx-plugin - terraform#project - Remplissez les paramètres requis
- Cliquez sur
Generate
Composez votre commande5
Requis
nameRequisstringLe nom du projet.
typeenumPar défaut:applicationSi c'est une bibliothèque terraform (modules réutilisables) ou une application (déployable).
applicationlibrarydirectorystringPar défaut:packagesLe répertoire du nouveau projet.
subDirectorystringLe sous-répertoire dans lequel le projet est placé. Par défaut, il s'agit du nom du projet.
preferInstallDependenciesbooleanPar défaut:trueIndique s'il faut privilégier l'installation des dépendances après l'exécution du générateur. Définir sur false pour différer l'installation lors de l'exécution de plusieurs générateurs en lot (une installation s'exécute quand même si nécessaire pour que les générateurs suivants puissent calculer le graphe de projet Nx) ; installer une seule fois à la fin.
Sortie du générateur
Section intitulée « Sortie du générateur »Le générateur crée différentes structures de fichiers en fonction du type de projet :
Type Application
Section intitulée « Type Application »Pour les projets d’application (--type=application), le générateur crée une application Terraform complète avec gestion de l’état distant :
Répertoiresrc
- main.tf Fichier de configuration Terraform principal
- providers.tf Configuration du fournisseur avec backend S3
- variables.tf Définitions des variables d’entrée
- outputs.tf Définitions des valeurs de sortie
Répertoireenv Fichiers de variables spécifiques à l’environnement
- dev.tfvars Variables d’environnement de développement
Répertoirebootstrap Configuration de bootstrap pour l’état distant
- main.tf Bucket S3 et politiques pour le stockage de l’état
- providers.tf Configuration du fournisseur AWS
- variables.tf Définitions des variables de bootstrap
Répertoirescripts Helpers Node exécutés par les cibles nx
bootstrap,bootstrap-destroyetinit- aws-config.ts Résout le compte + la région via la chaîne de credentials AWS SDK
- bootstrap.ts Récupère/pousse le tfstate de bootstrap et exécute
terraform apply - bootstrap-destroy.ts Vide le bucket d’état et exécute
terraform destroy - init.ts Exécute
terraform initavec la configuration du backend S3 - env.ts Pointe
terraform initvers le cache de fournisseurs partagé
- checkov.yml Configuration Checkov, incluant les vérifications à ignorer
- project.json Configuration du projet et cibles de build
Type Bibliothèque
Section intitulée « Type Bibliothèque »Pour les projets de bibliothèque (--type=library), le générateur crée une structure plus simple pour les modules Terraform réutilisables :
Répertoiresrc
- main.tf Fichier de module Terraform principal
- checkov.yml Configuration Checkov, incluant les vérifications à ignorer
- project.json Configuration du projet et cibles de build
Implémenter votre infrastructure Terraform
Section intitulée « Implémenter votre infrastructure Terraform »Vous pouvez commencer à écrire votre infrastructure Terraform dans src/main.tf, par exemple :
locals { account_id = data.aws_caller_identity.current.account_id aws_region = data.aws_region.current.id}
resource "null_resource" "print_info" { # triggers = { # always_run = timestamp() # }
provisioner "local-exec" { command = "echo 'AWS Region: ${local.aws_region}, AWS Account: ${local.account_id}, Environment: ${var.environment}'" }}
# Declare your infrastructure hereresource "aws_s3_bucket" "my_bucket" { bucket = "my-unique-bucket-name"}Notez que le bucket S3 ci-dessus échouerait à l’analyse de sécurité Checkov, qui vérifie que le bucket a les paramètres de sécurité appropriés activés.
Dépendances entre projets
Section intitulée « Dépendances entre projets »Si vous souhaitez exécuter un module à partir d’un projet séparé (lib), vous pouvez le faire comme suit :
module "lib_module" { source = "../../path/to/my-lib/src"}Cela mettra automatiquement à jour le graphe Nx pour ajouter une dépendance entre votre application consommatrice et votre lib.
Configuration de l’environnement
Section intitulée « Configuration de l’environnement »Configurez les variables spécifiques à l’environnement dans les fichiers src/env/*.tfvars.
Pour ajouter de nouveaux environnements, créez un nouveau fichier src/env/<environment>.tfvars avec les variables spécifiques à l’environnement et ajoutez de nouvelles entrées pour apply, destroy, init, plan dans le project.json pour la nouvelle configuration d’environnement. Par exemple, supposons que nous voulions ajouter un environnement prod :
# Production environment variablesenvironment = "prod"aws_region = "us-west-2"{ "targets": { "apply": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform apply ../../../dist/packages/infra/terraform/dev.tfplan" }, "prod": { "command": "terraform apply ../../../dist/packages/infra/terraform/prod.tfplan" } }, "options": { "forwardAllArgs": true, "cwd": "{projectRoot}/src" }, "dependsOn": ["plan"] }, "destroy": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform destroy -var-file=env/dev.tfvars" }, "prod": { "command": "terraform destroy -var-file=env/prod.tfvars" } }, "options": { "forwardAllArgs": true, "cwd":"{projectRoot}/src" }, "dependsOn": ["init"] }, "init": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "env": { "TF_ENV": "dev" } }, "prod": { "env": { "TF_ENV": "prod" } } }, "options": { "forwardAllArgs": true, "commands": ["tsx {projectRoot}/scripts/init.ts {projectRoot}"], "cwd": "{workspaceRoot}" } }, "plan": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform plan -var-file=env/dev.tfvars -out=../../../dist/packages/infra/terraform/dev.tfplan" }, "prod": { "command": "terraform plan -var-file=env/prod.tfvars -out=../../../dist/packages/infra/terraform/prod.tfplan" } }, "options": { "forwardAllArgs": true, "cwd": "{projectRoot}/src" }, "dependsOn": ["init"] } }}Bootstrap de l’état distant (Projets d’application uniquement)
Section intitulée « Bootstrap de l’état distant (Projets d’application uniquement) »Avant de déployer votre infrastructure, vous devrez initialiser le backend d’état distant. Cela crée un bucket S3 pour stocker vos fichiers d’état Terraform :
pnpm nx bootstrap tf-infrayarn nx bootstrap tf-infranpx nx bootstrap tf-infrabunx nx bootstrap tf-infraCibles disponibles
Section intitulée « Cibles disponibles »Les cibles disponibles dépendent du type de votre projet :
Cibles communes (Application et Bibliothèque)
Section intitulée « Cibles communes (Application et Bibliothèque) »Valider votre infrastructure
Section intitulée « Valider votre infrastructure »Vous pouvez valider votre configuration Terraform en utilisant la cible validate :
pnpm nx validate tf-infrayarn nx validate tf-infranpx nx validate tf-infrabunx nx validate tf-infraLes projets Terraform utilisent terraform fmt pour vérifier le formatage.
Exécuter le Linter
Section intitulée « Exécuter le Linter »Pour invoquer le linter afin de vérifier votre projet, vous pouvez exécuter la cible lint.
pnpm nx lint tf-infrayarn nx lint tf-infranpx nx lint tf-infrabunx nx lint tf-infraCorriger les problèmes de Lint
Section intitulée « Corriger les problèmes de Lint »La majorité des problèmes de linting ou de formatage peuvent être corrigés automatiquement en exécutant avec l’argument --configuration=fix.
pnpm nx lint tf-infra --configuration=fixyarn nx lint tf-infra --configuration=fixnpx nx lint tf-infra --configuration=fixbunx nx lint tf-infra --configuration=fixDe même, si vous souhaitez corriger tous les problèmes de lint dans tous les packages de votre espace de travail, vous pouvez exécuter :
pnpm nx run-many --target lint --all --configuration=fixyarn nx run-many --target lint --all --configuration=fixnpx nx run-many --target lint --all --configuration=fixbunx nx run-many --target lint --all --configuration=fixIgnorer les problèmes de Lint
Section intitulée « Ignorer les problèmes de Lint »Pour éviter que les problèmes de linting ne vous ralentissent pendant le développement (en particulier si vous avez des problèmes non corrigeables automatiquement dans votre projet), vous pouvez exécuter un build avec la configuration skip-lint :
pnpm nx run-many --target build --configuration=skip-lintyarn nx run-many --target build --configuration=skip-lintnpx nx run-many --target build --configuration=skip-lintbunx nx run-many --target build --configuration=skip-lintCela ignore complètement la vérification du format pendant le build.
Tests de sécurité
Section intitulée « Tests de sécurité »Exécutez des vérifications de sécurité sur votre infrastructure en utilisant Checkov avec la cible checkov :
pnpm nx checkov tf-infrayarn nx checkov tf-infranpx nx checkov tf-infrabunx nx checkov tf-infraVous trouverez vos résultats de tests de sécurité dans le dossier dist racine, sous dist/packages/<my-terraform-project>/checkov.
Checkov s’exécute dans le cadre de build.
Les vérifications sont configurées dans le fichier checkov.yml du projet. Ajoutez un identifiant de vérification à skip-check pour le supprimer dans tout le projet :
skip-check: - CKV_AWS_115 # Concurrent execution limit - CKV_AWS_116 # Dead Letter QueuePour supprimer une vérification pour une seule ressource, ajoutez un commentaire #checkov:skip=<id>:<reason> à l’intérieur du bloc de ressource :
resource "aws_s3_bucket" "example" { #checkov:skip=CKV_AWS_18:Access logging not required for this bucket bucket = "example"}Exécuter les tests Terraform
Section intitulée « Exécuter les tests Terraform »La cible test exécute le framework de test natif de Terraform sur tous les fichiers .tftest.hcl de votre projet :
pnpm nx test tf-infrayarn nx test tf-infranpx nx test tf-infrabunx nx test tf-infraUn projet sans fichiers de test est un succès sans opération, vous pouvez donc ajouter des tests quand vous en avez besoin. build exécute cette cible, donc vos tests s’exécutent dans le cadre d’un build normal.
Chaque bloc run évalue votre configuration. Utilisez command = plan pour vérifier ce que Terraform ferait (cela développe tout le graphe de modules, donc cela détecte les erreurs au moment de la planification que validate ne peut pas détecter), ou command = apply pour créer de vraies ressources et faire des assertions sur leurs sorties. Déclarer mock_provider signifie qu’aucun appel d’API n’est effectué et qu’aucune credential AWS n’est nécessaire, ce qui permet de garder les tests plan rapides et sûrs à exécuter en CI :
mock_provider "aws" { mock_data "aws_caller_identity" { defaults = { account_id = "123456789012" } } mock_data "aws_region" { defaults = { region = "us-east-1" } }}
variables { aws_region = "us-east-1" environment = "dev"}
run "plan_is_valid" { command = plan
assert { condition = data.aws_caller_identity.current.account_id == "123456789012" error_message = "Unexpected account id" }}Définissez chaque variable requise par votre configuration dans le bloc variables, sinon l’exécution échoue avec “has a required variable … with no set value”.
Chaque cible qui exécute terraform init réutilise un cache de fournisseurs sous .terraform/plugin-cache dans la racine de votre espace de travail, de sorte que les fournisseurs sont téléchargés une seule fois plutôt qu’à chaque exécution. Chaque projet obtient son propre répertoire là-bas : deux exécutions de terraform init remplissant un cache en même temps peuvent chacune calculer un hash différent pour le même fournisseur, que terraform rejette ensuite contre votre .terraform.lock.hcl. Consultez la documentation Terraform pour plus d’informations.
Définissez TF_PLUGIN_CACHE_DIR dans votre environnement pour pointer le script init fourni vers un cache que vous gérez vous-même — un volume partagé entre les espaces de travail, par exemple. Notez que la cible test lit son chemin depuis project.json, donc modifiez-le là aussi.
Cibles réservées aux applications
Section intitulée « Cibles réservées aux applications »Les cibles suivantes ne sont disponibles que pour les projets de type application :
Planifier votre infrastructure
Section intitulée « Planifier votre infrastructure »Avant d’appliquer des modifications, vous pouvez voir ce que Terraform va faire en exécutant la cible plan :
pnpm nx plan tf-infrayarn nx plan tf-infranpx nx plan tf-infrabunx nx plan tf-infraCela créera un fichier de plan dans dist/packages/<my-terraform-project>/terraform/dev.tfplan.
plan dépend de assemble, donc il produit les artefacts que vos modules référencent, tels que les bundles Lambda et les métadonnées d’opérations générées, sans exécuter les contrôles de lint, test et vérification de type.
Initialiser Terraform
Section intitulée « Initialiser Terraform »Initialisez votre répertoire de travail Terraform avec la cible init :
pnpm nx run tf-infra:inityarn nx run tf-infra:initnpx nx run tf-infra:initbunx nx run tf-infra:initDéployer sur AWS
Section intitulée « Déployer sur AWS »Après la planification, vous pouvez déployer votre infrastructure sur AWS en utilisant la cible apply :
pnpm nx apply tf-infrayarn nx apply tf-infranpx nx apply tf-infrabunx nx apply tf-infraObtenir les sorties
Section intitulée « Obtenir les sorties »Récupérez les valeurs de sortie de votre configuration Terraform :
pnpm nx output tf-infrayarn nx output tf-infranpx nx output tf-infrabunx nx output tf-infraDétruire l’infrastructure
Section intitulée « Détruire l’infrastructure »Lorsque vous devez démanteler votre infrastructure, utilisez la cible destroy :
pnpm nx destroy tf-infrayarn nx destroy tf-infranpx nx destroy tf-infrabunx nx destroy tf-infraDétruire les ressources de bootstrap
Section intitulée « Détruire les ressources de bootstrap »Pour nettoyer les ressources de bootstrap (bucket S3 pour le stockage de l’état) :
pnpm nx bootstrap-destroy tf-infrayarn nx bootstrap-destroy tf-infranpx nx bootstrap-destroy tf-infrabunx nx bootstrap-destroy tf-infraCela vide le bucket d’état avant de le détruire, et résout la région à partir de la chaîne de credentials AWS SDK, de sorte qu’il s’exécute sans surveillance en CI.
Plus d’informations
Section intitulée « Plus d’informations »Pour plus d’informations sur Terraform, veuillez vous référer à la Documentation Terraform et à la Documentation du fournisseur AWS.