L’auteur a sélectionné la Fondation Wikimedia pour recevoir une donation dans le cadre du programme Write for Donations.
Introduction
L’Infrastructure as Code (IaC) est une pratique visant à automatiser le déploiement et les modifications de l’infrastructure en définissant les états des ressources et leurs relations dans le code. L’exécution de ce code crée ou modifie ensuite les ressources réelles dans le cloud. L’IaC permet aux ingénieurs d’utiliser un outil IaC tel que Terraform (par HashiCorp) pour provisionner l’infrastructure.
Avec l’IaC, les modifications apportées à votre infrastructure peuvent passer par le même processus de revue de code que votre code d’application. Vous pouvez stocker le code dans un système de contrôle de version (comme Git) pour conserver un historique de l’état de votre infrastructure, et vous pouvez automatiser davantage le processus de déploiement avec des outils de niveau supérieur tels qu’une plateforme de développement interne en libre-service (IDP).
Terraform est une plateforme agnostique populaire d’outil IaC en raison de son large soutien pour de nombreuses plateformes, incluant GitHub, Cloudflare et DigitalOcean. La plupart des configurations Terraform sont écrites en utilisant un langage déclaratif appelé le Langage de Configuration HashiCorp (HCL).
Le Kit de Développement Cloud pour Terraform (CDKTF) est un outil construit sur Terraform qui vous permet de définir l’infrastructure en utilisant un langage de programmation familier (tel que TypeScript, Python, ou Go) au lieu du HCL. Cet outil peut offrir une courbe d’apprentissage moins abrupte pour les développeurs non familiers avec le HCL, tout en permettant aux développeurs d’utiliser des fonctionnalités de programmation natives telles que les boucles, les variables, et les fonctions.
Dans ce tutoriel, vous commencerez par installer l’interface en ligne de commande cdktf
. Ensuite, vous rédigerez un projet CDKTF en TypeScript et définirez le projet avec deux serveurs NGINX qui sont équilibrés par un équilibreur de charge. Vous utiliserez ensuite cdktf
pour déployer l’infrastructure. À la fin de ce tutoriel, vous aurez un projet CDKTF à partir duquel vous pourrez développer pour étendre votre infrastructure.
Remarque: Ce tutoriel a été testé avec CDKTF 0.11.2
et Terraform 1.2.2
.
Prérequis
Pour accomplir ce tutoriel, vous aurez besoin de :
- A good understanding of Infrastructure-as-Code (IaC). You can learn about IaC in Infrastructure as Code Explained.
- A DigitalOcean account. If you do not have one, sign up for a new account.
- A DigitalOcean Personal Access Token, which you can create via the DigitalOcean console. Instructions on how to do that can be found at How to Generate a Personal Access Token.
- A password-less SSH key added to your DigitalOcean account. You can add that by following How To Use SSH Keys with DigitalOcean Droplets. When you add the key to your account, remember the name you give it, as you will need it in this tutorial. For CDKTF to accept the name of your key, it must start with a letter or underscore and may contain only letters, digits, underscores, and dashes.
- Terraform installé sur votre machine locale, que vous pouvez configurer avec « Étape 1 – Installation de Terraform » dans Comment utiliser Terraform avec DigitalOcean.
- Node.js installé sur votre machine locale. Vous pouvez trouver des instructions pour cela dans la série Comment installer Node.js et créer un environnement de développement local.
- Être à l’aise en programmation avec JavaScript. Pour développer vos compétences, consultez la série Comment coder en JavaScript.
- Être à l’aise avec les fonctionnalités de base de TypeScript. Si vous n’êtes pas à l’aise avec TypeScript, la série de tutoriels Comment coder en TypeScript est une bonne ressource pour vous mettre à niveau.
- A code editor or integrated development environment (IDE) that supports TypeScript. If you are not currently using one, try Visual Studio Code. You can also read up on How To Work With TypeScript in Visual Studio Code.
Étape 1 — Installation de l’interface de ligne de commande cdktf
Pour commencer, vous installerez l’outil en ligne de commande cdktf
.
L’interface de ligne de commande cdktf
est disponible en tant que package NPM. Si vous recherchez cdktf
sur npmjs.com, vous trouverez deux packages portant des noms similaires : cdktf
et cdktf-cli
.
Conceptuellement, CDKTF est une couche d’abstraction au-dessus de Terraform. Il se compose de deux parties :
-
Une bibliothèque contenant un ensemble de constructions natives du langage (telles que des fonctions et des classes) pour définir l’infrastructure. Cette partie est encapsulée dans le paquet npm
cdktf
. Par exemple, vous pouvez voir l’utilisation des classesApp
etTerraformStack
du paquetcdktf
dans le projet CDKTF d’exemple suivant : -
un adaptateur qui analyse les constructions dans le projet CDKTF et les réduit à un ensemble de documents JSON, qui sont ensuite ingérés dans Terraform de la même manière que HCL est ingéré. Cet adaptateur est encapsulé dans un outil CLI appelé
cdktf
, fourni par le paquetcdktf-cli
.
Pour installer l’outil CLI cdktf
, vous avez besoin du paquet cdktf-cli
. Vous pouvez installer ce paquet globalement en utilisant npm
, yarn
, ou un gestionnaire de paquets de votre choix.
Pour installer cdktf-cli
avec npm
, exécutez ce qui suit:
Remarque: Il y aura probablement une version plus récente du paquet cdktf-cli
après la publication de cet article. Vous pouvez essayer de suivre le tutoriel avec la dernière version en exécutant npm install --global cdktf-cli@latest
à la place, mais sachez que certaines sorties peuvent différer légèrement.
Alternativement, vous pouvez utiliser Homebrew sur macOS ou Linux pour installer l’outil CLI cdktf
avec la formule cdktf
:
Pour vérifier que l’installation a réussi, exécutez la commande cdktf
sans arguments:
Vous verrez une sortie similaire à ce qui suit :
OutputPlease pass a command to cdktf, here are all available ones:
cdktf
Commands:
cdktf init Create a new cdktf project from a template.
cdktf get Generate CDK Constructs for Terraform providers and modules.
cdktf convert Converts a single file of HCL configuration to CDK for Terraform.
cdktf deploy [stacks...] Deploy the given stacks
cdktf destroy [stacks..] Destroy the given stacks
cdktf diff [stack] Perform a diff (terraform plan) for the given stack
cdktf list List stacks in app.
cdktf login Retrieves an API token to connect to Terraform Cloud.
cdktf synth Synthesizes Terraform code for the given app in a directory.
cdktf watch [stacks..] [experimental] Watch for file changes and automatically trigger a deploy
cdktf output [stacks..] Prints the output of stacks
cdktf debug Get debug information about the current project and environment
cdktf completion generate completion script
Options:
--version Afficher le numéro de version
--disable-logging Ne pas écrire de fichiers journaux. Pris en charge en utilisant l'environnement CDKTF_DISABLE_LOGGING.
--disable-plugin-cache-env Ne pas définir automatiquement TF_PLUGIN_CACHE_DIR.
--log-level Niveau de journalisation à écrire.
-h, --help Show help
Options can be specified via environment variables with the "CDKTF_" prefix (e.g. "CDKTF_OUTPUT")
La sortie vous montre les commandes disponibles. Dans le reste de ce tutoriel, vous gagnerez de l’expérience en utilisant cdktf init
, cdktf get
, cdktf deploy
et cdktf destroy
.
Maintenant que vous avez installé le CLI cdktf
, vous pouvez définir l’infrastructure en écrivant un code TypeScript.
Étape 2 — Création d’un nouveau projet CDKTF
Dans cette étape, vous utiliserez le CLI cdktf
que vous venez d’installer pour créer un projet de base CDKTF, sur lequel vous travaillerez dans les étapes suivantes.
Créez un répertoire qui abritera le projet CDKTF en exécutant la commande suivante :
Ensuite, accédez au répertoire nouvellement créé :
Utilisez la commande cdktf init
pour créer une structure de projet CDKTF sur laquelle vous travaillerez :
CDKTF permet aux développeurs de définir l’infrastructure en utilisant TypeScript, Python, Java, C# ou Go. L’option --template=typescript
indique à cdktf
de générer ce projet CDKTF en utilisant TypeScript.
Terraform (et donc CDKTF) garde une trace des ressources qu’il gère en enregistrant leurs définitions et leurs états dans des fichiers appelés fichiers d’état Terraform. L’option --local
indique à CDKTF de conserver ces fichiers d’état localement sur la machine exécutant cdktf
(chaque fichier suit la structure de nommage terraform.<stack>.tfstate
).
Après avoir exécuté la commande, l’interface en ligne de commande peut vous demander l’autorisation d’envoyer des rapports de plantage à l’équipe CDKTF pour les aider à améliorer le produit:
Output? Do you want to send crash reports to the CDKTF team? See https://www.terraform.io/cdktf/create-and-deploy/configuration-file for
more information (Y/n)
Tapez Y
si vous consentez ou N
si vous êtes en désaccord, puis appuyez sur ENTRÉE
.
cdktf
va ensuite créer le squelette du projet et installer les packages. Lorsque le projet est généré, vous verrez une sortie similaire à ce qui suit:
Output Your cdktf typescript project is ready!
cat help Print this message
Compile:
npm run get Import/update Terraform providers and modules (you should check-in this directory)
npm run compile Compile typescript code to javascript (or "npm run watch")
npm run watch Watch for changes and compile typescript in the background
npm run build Compile typescript
Synthesize:
cdktf synth [stack] Synthesize Terraform resources from stacks to cdktf.out/ (ready for 'terraform apply')
Diff:
cdktf diff [stack] Perform a diff (terraform plan) for the given stack
Deploy:
cdktf deploy [stack] Deploy the given stack
Destroy:
cdktf destroy [stack] Destroy the stack
Test:
npm run test Runs unit tests (edit __tests__/main-test.ts to add your own tests)
npm run test:watch Watches the tests and reruns them on change
Upgrades:
npm run upgrade Upgrade cdktf modules to latest version
npm run upgrade:next Upgrade cdktf modules to latest "@next" version (last commit)
Vous verrez également de nouveaux fichiers ajoutés au répertoire infra
. Les fichiers les plus importants sont cdktf.json
et main.ts
.
cdktf.json
est le fichier de configuration pour le projet CDKTF. Si vous ouvrez le fichier, il affichera quelque chose comme ce qui suit:
La propriété app
définit la commande qui sera exécutée pour synthétiser le code TypeScript en JSON compatible avec Terraform. Cette propriété indique que main.ts
est le point d’entrée du projet CDKTF.
Si vous ouvrez le fichier main.ts
, vous verrez quelque chose de similaire à ce qui suit :
Dans le langage de CDKTF, une collection de ressources d’infrastructure connexes peut être regroupée dans une pile. Par exemple, les ressources constituant une application API, telles que des gouttelettes, des équilibreurs de charge et des enregistrements DNS, peuvent être regroupées dans une seule pile nommée APIStack
. Chaque pile conserve son propre état et peut être déployée, modifiée ou détruite indépendamment des autres piles. Une utilisation courante des piles est d’avoir une pile pour la production et une pile distincte pour le développement.
Une application est un conteneur pour plusieurs piles. Par exemple, une application peut regrouper les piles de divers microservices.
Le projet de structure CDKTF généré dans main.ts
contient une seule classe de pile appelée MyStack
, qui ne définit actuellement aucune ressource. Une instance de MyStack
est créée avec le nom infra
, contenue dans une application appelée app
. Dans les étapes suivantes, vous définirez des ressources d’infrastructure dans le constructeur de MyStack
.
Après avoir créé le projet, la prochaine étape consiste à configurer le projet CDKTF avec des fournisseurs.
Étape 3 — Installation du fournisseur DigitalOcean
Dans cette étape, vous installerez le fournisseur DigitalOcean dans le projet CDKTF.
Fournisseurs sont des bibliothèques qui fournissent des instructions à Terraform (utilisé par cdktf
en interne) sur comment créer, mettre à jour et supprimer des ressources sur des fournisseurs de cloud, des fournisseurs SaaS et d’autres plateformes exposant des interfaces de programmation d’applications (API). Les fournisseurs encapsulent la logique d’appel de ces API amont dans des fonctions standard que Terraform peut appeler.
Par exemple, si vous vouliez créer un nouveau Droplet DigitalOcean sans Terraform, vous devriez envoyer une requête POST
à l’endpoint /v2/droplets
de l’API DigitalOcean. Avec Terraform, vous installeriez plutôt le fournisseur DigitalOcean et définiriez une ressource digitalocean_droplet
, semblable à l’extrait d’exemple suivant :
Vous pouvez ensuite utiliser l’outil CLI cdktf
pour traduire ce code TypeScript en JSON compatible avec Terraform et le transmettre au fournisseur, qui effectuera les appels API appropriés pour créer le Droplet en votre nom.
Maintenant que vous comprenez ce qu’est un fournisseur, vous pouvez configurer le fournisseur DigitalOcean pour votre projet CDKTF.
Ouvrez le fichier cdktf.json
et ajoutez la chaîne digitalocean/digitalocean
au tableau terraformProviders
:
digitalocean/digitalocean
est l’identifiant du fournisseur DigitalOcean sur le Terraform Registry.
Enregistrez et fermez le fichier.
Ensuite, exécutez cdktf get
pour télécharger et installer le fournisseur.
cdktf get
téléchargera le fournisseur, extraira le schéma, générera les classes TypeScript correspondantes et l’ajoutera en tant que module TypeScript sous .gen/providers/
. Cette génération automatique de code vous permet d’utiliser n’importe quel fournisseur Terraform et modules HCL avec CDKTF, et c’est ainsi que CDKTF peut fournir une complétion de code dans les éditeurs qui le prennent en charge.
Une fois que cdktf get
a fini de s’exécuter, vous verrez une sortie similaire à ce qui suit :
OutputGenerated typescript constructs in the output directory: .gen
Vous verrez également un nouveau répertoire appelé .gen
contenant le code généré du fournisseur.
Dans cette étape, vous avez installé le fournisseur digitalocean/digitalocean
dans le projet. À l’étape suivante, vous configurerez le fournisseur DigitalOcean avec les informations d’identification nécessaires pour authentifier le fournisseur auprès de l’API DigitalOcean.
Étape 4 — Configuration du fournisseur DigitalOcean
À cette étape, vous allez configurer le fournisseur DigitalOcean avec votre jeton d’accès personnel DigitalOcean, ce qui permet au fournisseur d’appeler l’API DigitalOcean en votre nom.
Différents fournisseurs requièrent et prennent en charge différentes informations d’identification pour s’authentifier avec l’API amont. Pour le fournisseur DigitalOcean, vous devez fournir votre jeton d’accès personnel DigitalOcean. Vous pouvez spécifier le jeton au fournisseur en le définissant comme la variable d’environnement DIGITALOCEAN_TOKEN
ou DIGITALOCEAN_ACCESS_TOKEN
.
Exécutez la commande suivante dans votre terminal pour définir la variable d’environnement pour cette session terminal.
Notez: En appelant export
, vous définissez la variable d’environnement uniquement pour cette session terminal. Si vous fermez et rouvrez le terminal ou exécutez les commandes cdktf
dans un terminal différent, vous devrez exécuter à nouveau la commande export
pour que la variable d’environnement prenne effet.
Ensuite, vous spécifierez le fournisseur dans la classe MyStack
, ce qui vous permettra de définir les ressources fournies par le fournisseur dans votre pile. Mettez à jour le fichier main.ts
comme suit:
Le module pour le fournisseur est situé à ./.gen/providers/digitalocean
, qui a été généré automatiquement lorsque vous avez exécuté cdktf get
.
Vous avez configuré le fournisseur digitalocean/digitalocean
avec des informations d’identification à cette étape. Ensuite, vous commencerez à définir l’infrastructure qui fait partie de l’objectif de ce tutoriel.
Étape 5 — Définition des applications Web sur les gouttes
Dans cette étape, vous définirez deux serveurs NGINX, chacun servant des fichiers différents, déployés sur deux gouttes Ubuntu 20.04 identiques.
Vous commencez par la définition des deux gouttes. Modifiez main.ts
avec les modifications surlignées:
Vous utilisez une boucle native en JavaScript (Array.prototype.map()
) pour éviter la duplication de code.
Tout comme si vous créiez la goutte via la console, plusieurs paramètres doivent être spécifiés:
image
– la distribution Linux et la version sur lesquelles votre goutte fonctionnera.région
– le centre de données où la goutte fonctionnera.taille
– la quantité de ressources CPU et mémoire à réserver pour la goutte.nom
– un nom unique utilisé pour faire référence à la goutte.
Les valeurs pour image
, région
et taille
doivent être des choses prises en charge par DigitalOcean. Vous pouvez trouver les valeurs valides (appelées slugs) pour toutes les images de distribution Linux prises en charge, les tailles de Droplet et les régions sur la page Slugs de l’API DigitalOcean. Vous pouvez trouver une liste complète des attributs requis et facultatifs sur la page de documentation digitalocean_droplet
.
Ajout d’une clé SSH
Dans le cadre des prérequis, vous avez téléchargé une clé publique SSH sans mot de passe sur votre compte DigitalOcean et noté son nom. Vous utiliserez maintenant ce nom pour récupérer l’ID de la clé SSH et le transmettre dans la définition de votre Droplet.
Étant donné que la clé SSH a été ajoutée manuellement à votre compte DigitalOcean, elle n’est pas une ressource gérée par votre configuration Terraform actuelle. Si vous essayiez de définir une nouvelle ressource digitalocean_ssh_key
, cela créerait une nouvelle clé SSH au lieu d’utiliser celle existante.
Au lieu de cela, vous allez définir une nouvelle source de données digitalocean_ssh_key
. En Terraform, les sources de données sont utilisées pour récupérer des informations sur l’infrastructure qui ne sont pas gérées par la configuration Terraform actuelle. En d’autres termes, elles fournissent une vue en lecture seule de l’état de l’infrastructure externe préexistante. Une fois qu’une source de données est définie, vous pouvez utiliser les données ailleurs dans votre configuration Terraform.
Toujours dans main.ts
et à l’intérieur du constructeur de MyStack
, définissez une nouvelle source de données DataDigitaloceanSshKey
, et transmettez le nom que vous avez attribué à votre clé SSH (ici, le nom est do_cdktf
):
Ensuite, mettez à jour la définition du Droplet pour inclure la clé SSH:
Lorsqu’il est provisionné, vous pouvez accéder au Droplet en utilisant une clé SSH privée au lieu d’un mot de passe.
Spécification du script de données utilisateur pour installer NGINX
Vous avez maintenant défini deux Droplets identiques exécutant Ubuntu, configurés avec un accès SSH. La prochaine tâche consiste à installer NGINX sur chaque Droplet.
Lors de la création d’un Droplet, un outil appelé CloudInit initialisera le serveur. CloudInit peut accepter un fichier appelé user data, qui peut modifier la manière dont le serveur est initialisé. Les données utilisateur peuvent être n’importe quels fichiers cloud-config
ou scripts que le serveur peut interpréter, tels que des scripts Bash.
Dans le reste de cette étape, vous allez créer un script Bash et le spécifier comme user data du Droplet. Le script installera NGINX dans le processus d’initialisation. De plus, le script remplacera également le contenu du fichier /var/www/html/index.html
(le fichier par défaut servi par NGINX) par le nom d’hôte et l’adresse IP du Droplet, ce qui amènera les deux serveurs NGINX à servir des fichiers différents. À l’étape suivante, vous placerez ces deux serveurs NGINX derrière un répartiteur de charge ; en servant des fichiers différents, il sera évident si le répartiteur de charge distribue correctement les requêtes ou non.
Toujours dans main.ts
, ajoutez une nouvelle propriété userData
à l’objet de configuration du Droplet:
Avertissement: Assurez-vous qu’il n’y a pas de nouvelles lignes avant le shebang (#!
) ; sinon, le script risque de ne pas être exécuté.
Lorsque le Droplet est provisionné pour la première fois, le script s’exécutera en tant qu’utilisateur root
. Il utilisera le gestionnaire de paquets d’Ubuntu, APT, pour installer le paquet nginx
. Il utilisera ensuite le service de métadonnées de DigitalOcean pour récupérer des informations sur lui-même, et écrira le nom d’hôte et l’adresse IP dans index.html
, qui est servi par NGINX.
Dans cette étape, vous avez défini les deux Droplets exécutant Ubuntu, configuré chacun avec un accès SSH, et installé NGINX en utilisant la fonctionnalité des données utilisateur. À l’étape suivante, vous définirez un équilibreur de charge qui se trouvera devant ces serveurs NGINX et le configurerez pour équilibrer la charge de manière cyclique.
Étape 6 — Définition d’un équilibreur de charge
Dans cette étape, vous définirez un Équilibreur de Charge DigitalOcean en définissant une instance de la ressource digitalocean_loadbalancer
.
Toujours dans main.ts
, ajoutez la définition suivante pour un équilibreur de charge à la fin du constructeur de la classe MyStack
:
L’argument forwardingRule
indique au répartiteur de charge d’écouter les requêtes HTTP sur le port 80
et de les rediriger vers chacun des Droplets sur le port 80
.
Les dropletIds
spécifient les Droplets vers lesquels le répartiteur de charge transmettra les requêtes. Il prend un nombre, mais la valeur de droplet.id
est une chaîne de caractères. Par conséquent, vous avez utilisé la fonction Fn.tonumber
de Terraform pour convertir la valeur de l’identifiant de Droplet de chaîne en nombre.
Remarque : Vous avez utilisé la fonction Terraform Fn.tonumber
ici au lieu de parseInt
natif à JavaScript car la valeur de droplet.id
est inconnue jusqu’à ce que le Droplet soit provisionné. Les fonctions Terraform sont conçues pour fonctionner sur des valeurs inconnues au moment de l’exécution avant que Terraform n’applique une configuration.
Enregistrez et fermez le fichier.
Vous avez maintenant défini deux Droplets et un répartiteur de charge qui se trouve devant eux. Votre fichier main.ts
devrait ressembler à ceci :
À l’étape suivante, vous utiliserez l’outil en ligne de commande cdktf
pour concrétiser l’intégralité de votre projet CDKTF.
Étape 7 — Provisioning Your Infrastructure
Dans cette étape, vous utiliserez l’outil en ligne de commande cdktf
pour provisionner les Droplets et les équilibreurs de charge que vous avez définis dans les étapes précédentes.
Assurez-vous d’être dans le répertoire infra/
et d’avoir défini la variable d’environnement DIGITALOCEAN_ACCESS_TOKEN
pour votre session terminal, puis exécutez la commande cdktf deploy
:
Vous devriez voir une sortie similaire à ce qui suit :
Outputinfra Initializing the backend...
infra Initializing provider plugins...
infra - Reusing previous version of digitalocean/digitalocean from the dependency lock file
infra - Using previously-installed digitalocean/digitalocean v2.19.0
infra Terraform has been successfully initialized!
infra Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
infra # digitalocean_droplet.bar (bar) will be created
+ resource "digitalocean_droplet" "bar" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ graceful_shutdown = false
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "bar"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "lon1"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ ssh_keys = [
+ "34377800",
]
+ status = (known after apply)
+ urn = (known after apply)
+ user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1"
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
# digitalocean_droplet.foo (foo) sera créé
+ resource "digitalocean_droplet" "foo" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ graceful_shutdown = false
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "foo"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "lon1"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ ssh_keys = [
+ "34377800",
]
+ status = (known after apply)
+ urn = (known after apply)
+ user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1"
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
# digitalocean_loadbalancer.lb (lb) sera créé
+ resource "digitalocean_loadbalancer" "lb" {
+ algorithm = "round_robin"
+ disable_lets_encrypt_dns_records = false
+ droplet_ids = (known after apply)
+ enable_backend_keepalive = false
+ enable_proxy_protocol = false
+ id = (known after apply)
+ ip = (known after apply)
+ name = "default"
+ redirect_http_to_https = false
+ region = "lon1"
+ size_unit = (known after apply)
+ status = (known after apply)
+ urn = (known after apply)
+ vpc_uuid = (known after apply)
+ forwarding_rule {
+ certificate_id = (known after apply)
+ certificate_name = (known after apply)
+ entry_port = 80
+ entry_protocol = "http"
+ target_port = 80
+ target_protocol = "http"
+ tls_passthrough = false
}
+ healthcheck {
+ check_interval_seconds = (known after apply)
+ healthy_threshold = (known after apply)
+ path = (known after apply)
+ port = (known after apply)
+ protocol = (known after apply)
+ response_timeout_seconds = (known after apply)
+ unhealthy_threshold = (known after apply)
}
+ sticky_sessions {
+ cookie_name = (known after apply)
+ cookie_ttl_seconds = (known after apply)
+ type = (known after apply)
}
}
Plan: 3 to add, 0 to change, 0 to destroy.
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: plan
To perform exactly these actions, run the following command to apply:
terraform apply "plan"
Please review the diff output above for infra
❯ Approve Applies the changes outlined in the plan.
Dismiss
Stop
Remarque : CDKTF est toujours en développement, et la sortie peut différer de celle indiquée ci-dessus.
Cet affichage répertorie toutes les ressources et propriétés que cdktf
prévoit de créer, mettre à jour et détruire. Certaines valeurs, telles que l’ID d’un Droplet, ne sont connues qu’après la provision de la ressource. Pour celles-ci, vous verrez (known after apply)
comme valeur de propriété dans la sortie.
Examinez la liste des ressources pour vous assurer qu’elle correspond à vos attentes. Ensuite, utilisez les touches fléchées pour sélectionner l’option Approuver et appuyez sur ENTRÉE
.
Vous verrez une sortie similaire à ce qui suit :
Outputinfra digitalocean_droplet.foo (foo): Creating...
digitalocean_droplet.bar (bar): Creating...
infra digitalocean_droplet.bar (bar): Still creating... [10s elapsed]
infra digitalocean_droplet.foo (foo): Still creating... [10s elapsed]
1 Stack deploying 0 Stacks done 0 Stacks waiting
Cette sortie vous indique que cdktf
communique avec l’API DigitalOcean pour créer le Droplet. cdktf
crée d’abord les Droplets car l’équilibreur de charge dépend de l’ID du Droplet, qui est inconnu tant que les Droplets ne sont pas provisionnés.
La création d’un Droplet prend généralement moins d’une minute. Une fois les Droplets provisionnés, cdktf
passe à la création de l’équilibreur de charge.
Outputinfra digitalocean_droplet.bar (bar): Creation complete after 54s [id=298041598]
infra digitalocean_droplet.foo (foo): Creation complete after 55s [id=298041600]
infra digitalocean_loadbalancer.lb (lb): Creating...
infra digitalocean_loadbalancer.lb (lb): Still creating... [10s elapsed]
Le répartiteur de charge peut prendre plus de temps. Après la création du répartiteur de charge, vous verrez un résumé indiquant que la pile a été déployée avec succès.
Outputinfra digitalocean_loadbalancer.lb (lb): Still creating... [1m30s elapsed]
infra digitalocean_loadbalancer.lb (lb): Creation complete after 1m32s [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1]
infra
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
No outputs found.
Vous pouvez maintenant visiter la console DigitalOcean, où vous pouvez voir un répartiteur de charge nommé par défaut
et deux Droplets en bonne santé nommés foo
et bar
, chacun servant de cible pour le répartiteur de charge.
Vous pouvez vérifier que NGINX fonctionne et sert correctement le contenu en visitant l’adresse IP de chaque Droplet. Vous devriez voir un texte similaire à ce qui suit:
Droplet: bar, IP Address: droplet_ip
Si vous ne voyez pas cette chaîne de texte ou si le serveur ne répond pas, vérifiez que les données utilisateur que vous avez spécifiées sont correctes et qu’aucun caractère (y compris les sauts de ligne) ne précède le shebang (#!
). Vous pouvez également vous connecter en SSH au Droplet en utilisant votre clé privée SSH et examiner les journaux de sortie générés par CloudInit à l’emplacement suivant : /var/log/cloud-init-output.log
:
Une fois que vous avez confirmé que les Droplets sont en ligne et servent du contenu, vous pouvez commencer à tester le répartiteur de charge. Vous pouvez le faire en envoyant quelques requêtes.
Exécutez la commande suivante depuis votre terminal pour envoyer dix requêtes au répartiteur de charge:
Vous devriez voir une sortie similaire à ce qui suit, bien que les adresses IP affichées seront différentes:
OutputDroplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Droplet: bar, IP Address: droplet_bar_ip
Droplet: foo, IP Address: droplet_foo_ip
Cela montre que les requêtes vers le répartiteur de charge ont été transmises à chaque Droplet cinq fois, ce qui indique que le répartiteur de charge fonctionne.
Note : Le répartiteur de charge ne répartit pas toujours équitablement entre les deux Droplets ; vous pouvez constater que quatre requêtes ont été envoyées à un Droplet et six à l’autre. Ce comportement est normal.
À cette étape, vous avez utilisé cdktf
pour provisionner vos ressources, puis vous avez utilisé la console DigitalOcean pour découvrir les adresses IP de vos Droplets et du répartiteur de charge. Ensuite, vous avez envoyé des requêtes à chaque Droplet et au répartiteur de charge pour confirmer leur fonctionnement.
À l’étape suivante, vous obtiendrez les adresses IP des Droplets et du répartiteur de charge sans vous connecter à la console DigitalOcean.
Étape 8 — Sortie d’informations
Lors de l’étape précédente, vous avez dû vous connecter à la Console DigitalOcean pour obtenir les adresses IP de votre Droplet et du répartiteur de charge. À cette étape, vous modifierez légèrement votre code afin que ces informations soient imprimées dans la sortie de la commande cdktf deploy
, vous évitant ainsi un détour par la console.
Terraform enregistre la configuration et l’état de ses ressources gérées dans des fichiers d’état. Pour votre pile infra
, le fichier d’état peut être trouvé à infra/terraform.infra.tfstate
. Vous pourrez trouver les adresses IP des Droplets et du répartiteur de charge à l’intérieur de ce fichier d’état.
Cependant, parcourir un gros fichier peut être inconfortable. CDKTF fournit la construction TerraformOutput
, que vous pouvez utiliser pour afficher les variables et les rendre disponibles en dehors de la pile. Toutes les sorties sont imprimées dans stdout
après l’exécution de cdktf deploy
. Exécuter cdktf output
peut également imprimer les sorties à tout moment.
Remarque : Bien que vous n’utilisiez que des sorties pour imprimer des informations dans la console dans ce tutoriel, sa véritable puissance provient des piles utilisant les sorties d’autres piles comme entrée, une fonctionnalité connue sous le nom de références inter-piles.
Mettez à jour le fichier main.ts
pour inclure les sorties des adresses IP du répartiteur de charge et des gouttes :
Enregistrez et fermez le fichier.
Exécutez cdktf deploy
pour actualiser le changement :
Dans la sortie, vous devriez voir quelque chose de similaire à ce qui suit :
Output─────────────────────────────────────────────────────────────────────────────
Changes to Outputs:
+ droplet0IP = "droplet_foo_ip"
+ droplet1IP = "droplet_bar_ip"
+ loadBalancerIP = "load_balancer_ip"
You can apply this plan to save these new output values to the Terraform
state, without changing any real infrastructure.
─────────────────────────────────────────────────────────────────────────────
Cette sortie vous indique qu’aucun changement d’infrastructure ne sera effectué, seulement ce qui est produit par la pile.
Utilisez les touches fléchées pour sélectionner Approuver, puis appuyez sur ENTRÉE
. À la fin de la sortie du terminal, vous devriez voir quelque chose de similaire à :
Outputinfra
droplet0IP = droplet_foo_ip
droplet1IP = droplet_bar_ip
loadBalancerIP = load_balancer_ip
Désormais, chaque fois que vous exécutez cdktf deploy
ou cdktf output
, l’adresse IP des gouttes et des répartiteurs de charge est imprimée dans la sortie du terminal, éliminant ainsi le besoin d’accéder à ces informations depuis la console DigitalOcean.
Vous avez maintenant provisionné deux gouttes et un répartiteur de charge et confirmé qu’ils fonctionnent. Vous pouvez utiliser le projet CDKTF que vous avez développé comme base pour définir une infrastructure plus sophistiquée (vous pouvez trouver une implémentation de référence sur do-community/digitalocean-cdktf-typescript
).
Les ressources provisionnées dans ce tutoriel entraîneront des frais. Si vous n’avez pas l’intention d’utiliser l’infrastructure créée, vous devriez la détruire. À l’étape suivante et finale, vous nettoierez le projet en détruisant les ressources créées dans ce tutoriel.
Étape 9 — Destruction de votre infrastructure
Dans cette étape, vous supprimerez toutes les ressources créées dans ce tutoriel.
Toujours dans le répertoire infra/
, exécutez cdktf destroy
:
Vous devriez voir une sortie similaire à ce qui suit :
Outputinfra Initializing the backend...
infra Initializing provider plugins...
infra - Reusing previous version of digitalocean/digitalocean from the dependency lock file
infra - Using previously-installed digitalocean/digitalocean v2.19.0
infra Terraform has been successfully initialized!
infra digitalocean_droplet.bar (bar): Refreshing state... [id=298041598]
digitalocean_droplet.foo (foo): Refreshing state... [id=298041600]
infra digitalocean_loadbalancer.lb (lb): Refreshing state... [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1]
infra Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
infra # digitalocean_droplet.bar (bar) will be destroyed
- resource "digitalocean_droplet" "bar" {
- backups = false -> null
- created_at = "2022-05-02T10:04:16Z" -> null
- disk = 25 -> null
- graceful_shutdown = false -> null
- id = "298041598" -> null
- image = "ubuntu-20-04-x64" -> null
- ipv4_address = "droplet_bar_public_ip" -> null
- ipv4_address_private = "droplet_bar_private_ip" -> null
- ipv6 = false -> null
- locked = false -> null
- memory = 1024 -> null
- monitoring = false -> null
- name = "bar" -> null
- price_hourly = 0.00744 -> null
- price_monthly = 5 -> null
- private_networking = true -> null
- region = "lon1" -> null
- resize_disk = true -> null
- size = "s-1vcpu-1gb" -> null
- ssh_keys = [
- "34377800",
] -> null
- status = "active" -> null
- tags = [] -> null
- urn = "do:droplet:298041598" -> null
- user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" -> null
- vcpus = 1 -> null
- volume_ids = [] -> null
- vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null
}
# digitalocean_droplet.foo (foo) sera détruit
- resource "digitalocean_droplet" "foo" {
- backups = false -> null
- created_at = "2022-05-02T10:04:16Z" -> null
- disk = 25 -> null
- graceful_shutdown = false -> null
- id = "298041600" -> null
- image = "ubuntu-20-04-x64" -> null
- ipv4_address = "droplet_foo_public_ip" -> null
- ipv4_address_private = "droplet_foo_private_ip" -> null
- ipv6 = false -> null
- locked = false -> null
- memory = 1024 -> null
- monitoring = false -> null
- name = "foo" -> null
- price_hourly = 0.00744 -> null
- price_monthly = 5 -> null
- private_networking = true -> null
- region = "lon1" -> null
- resize_disk = true -> null
- size = "s-1vcpu-1gb" -> null
- ssh_keys = [
- "34377800",
] -> null
- status = "active" -> null
- tags = [] -> null
- urn = "do:droplet:298041600" -> null
- user_data = "f9b1d9796d069fe504ce0d89439b6b664b14b1a1" -> null
- vcpus = 1 -> null
- volume_ids = [] -> null
- vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null
}
# digitalocean_loadbalancer.lb (lb) sera détruit
- resource "digitalocean_loadbalancer" "lb" {
- algorithm = "round_robin" -> null
- disable_lets_encrypt_dns_records = false -> null
- droplet_ids = [
- 298041598,
- 298041600,
] -> null
- enable_backend_keepalive = false -> null
- enable_proxy_protocol = false -> null
- id = "4f9ae2b7-b649-4fb4-beed-96b95bb72dd1" -> null
- ip = "load_balancer_ip" -> null
- name = "default" -> null
- redirect_http_to_https = false -> null
- region = "lon1" -> null
- size_unit = 1 -> null
- status = "active" -> null
- urn = "do:loadbalancer:4f9ae2b7-b649-4fb4-beed-96b95bb72dd1" -> null
- vpc_uuid = "bed80b32-dc82-11e8-83ec-3cfdfea9f3f0" -> null
- forwarding_rule {
- entry_port = 80 -> null
- entry_protocol = "http" -> nul
infra l
- target_port = 80 -> null
- target_protocol = "http" -> null
- tls_passthrough = false -> null
}
- healthcheck {
- check_interval_seconds = 10 -> null
- healthy_threshold = 5 -> null
- path = "/" -> null
- port = 80 -> null
- protocol = "http" -> null
- response_timeout_seconds = 5 -> null
- unhealthy_threshold = 3 -> null
}
- sticky_sessions {
- cookie_ttl_seconds = 0 -> null
- type = "none" -> null
}
}
Plan: 0 to add, 0 to change, 3 to destroy.
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: plan
To perform exactly these actions, run the following command to apply:
terraform apply "plan"
Please review the diff output above for infra
❯ Approve Applies the changes outlined in the plan.
Dismiss
Stop
Cette fois-ci, au lieu de montrer +
à côté de chaque ressource, il montre -
, ce qui indique que CDKTF prévoit de détruire la ressource. Examinez les modifications proposées, puis utilisez les touches fléchées pour sélectionner Approuver et appuyez sur ENTRÉE
. Le fournisseur DigitalOcean communiquera maintenant avec l’API DigitalOcean pour détruire les ressources.
Outputinfra digitalocean_loadbalancer.lb (lb): Destroying... [id=4f9ae2b7-b649-4fb4-beed-96b95bb72dd1]
infra digitalocean_loadbalancer.lb (lb): Destruction complete after 1s
infra digitalocean_droplet.bar (bar): Destroying... [id=298041598]
digitalocean_droplet.foo (foo): Destroying... [id=298041600]
Le load balancer a été supprimé en premier car il n’a pas de dépendances (aucune autre ressource ne fait référence au load balancer dans leurs entrées). Comme le load balancer fait référence aux Droplets, ils ne peuvent être détruits qu’après que le load balancer soit détruit.
Après que les ressources ont été détruites, vous verrez la ligne suivante imprimée dans la sortie :
OutputDestroy complete! Resources: 3 destroyed.
Conclusion
Dans ce tutoriel, vous avez utilisé CDKTF pour provisionner et détruire une page web équilibrée chargée, composée de deux serveurs NGINX Droplets DigitalOcean, servis derrière un répartiteur de charge. Vous avez également affiché des informations sur les ressources dans le terminal.
CDKTF est une couche d’abstraction au-dessus de Terraform. Une bonne compréhension de Terraform est utile pour comprendre CDKTF. Si vous souhaitez en savoir plus sur Terraform, vous pouvez lire la série How To Manage Infrastructure with Terraform, qui couvre Terraform en profondeur.
Vous pouvez également consulter la documentation officielle de CDK pour Terraform et les tutoriels pour en savoir plus sur CDKTF.