De auteur heeft het Free and Open Source Fund geselecteerd om een donatie te ontvangen als onderdeel van het Write for Donations-programma.
Inleiding
Terraform-modules stellen u in staat om verschillende resources van uw infrastructuur te groeperen in één, geünificeerde resource. U kunt ze later hergebruiken met mogelijke aanpassingen, zonder de resource-definities telkens opnieuw te hoeven herhalen wanneer u ze nodig heeft, wat voordelig is voor grote en complex gestructureerde projecten. U kunt module-instanties aanpassen met behulp van door u gedefinieerde invoervariabelen en informatie uit hen halen met behulp van uitvoer. Naast het maken van uw eigen aangepaste modules, kunt u ook de kant-en-klare modules gebruiken die openbaar zijn gepubliceerd in de Terraform-registratie. Ontwikkelaars kunnen ze gebruiken en aanpassen met invoer zoals de modules die u maakt, maar hun broncode wordt opgeslagen in en opgehaald uit de cloud.
In deze zelfstudie maakt u een Terraform-module die meerdere Droplets achter een Load Balancer instelt voor redundantie. U zult ook de for_each
en count
loopfuncties van de HashiCorp Configuration Language (HCL) gebruiken om meerdere aangepaste instanties van de module tegelijk te implementeren.
Vereisten
- A DigitalOcean Personal Access Token, which you can create via the DigitalOcean control panel. You can find instructions in the DigitalOcean product document, How to Create a Personal Access Token.
- Terraform geïnstalleerd op uw lokale machine en een project opgezet met de DO-provider. Voltooi Stap 1 en Stap 2 van de zelfstudie Hoe Terraform te gebruiken met DigitalOcean, en zorg ervoor dat de projectmap de naam
terraform-modules
heeft, in plaats vanloadbalance
. Tijdens Stap 2 depvt_key
-variabele en de SSH-sleutelbron niet opnemen. - Bekendheid met HCL-datatypes en -lussen. Voor meer informatie, zie de zelfstudie Hoe de flexibiliteit te verbeteren door Terraform-variabelen, afhankelijkheden en voorwaarden te gebruiken.
- Bekendheid met Terraform-uitvoer en het gebruik ervan. U kunt de zelfstudie Hoe infrastructuurgegevens te beheren met Terraform-uitvoer volgen om hierover te leren.
Opmerking: Deze zelfstudie is specifiek getest met Terraform 1.1.3
.
Module Structuur en Voordelen
In deze sectie leer je welke voordelen modules bieden, waar ze meestal in het project worden geplaatst, en hoe ze gestructureerd moeten zijn.
Op maat gemaakte Terraform-modules worden gemaakt om verbonden componenten te omvatten die vaak samen worden gebruikt en ingezet in grotere projecten. Ze zijn zelfstandig en bundelen alleen de bronnen, variabelen en providers die ze nodig hebben.
Modules worden meestal opgeslagen in een centrale map aan de root van het project, elk in zijn respectievelijke submap eronder. Om een schone scheiding tussen modules te behouden, ontwerp ze altijd met een enkel doel en zorg ervoor dat ze nooit submodules bevatten.
Het is handig om modules te maken van je bronstructuren wanneer je merkt dat je ze herhaalt met zeldzame aanpassingen. Het verpakken van een enkele bron als module kan overbodig zijn en verwijdert geleidelijk de eenvoud van de algehele architectuur.
Voor kleine ontwikkelings- en testprojecten is het niet nodig om modules op te nemen omdat ze in die gevallen niet veel verbetering bieden. Met hun mogelijkheid tot aanpassing zijn modules het bouwelement van complex gestructureerde projecten. Ontwikkelaars gebruiken modules voor grotere projecten vanwege de aanzienlijke voordelen bij het vermijden van code duplicatie. Modules bieden ook het voordeel dat definities slechts op één plaats hoeven te worden gewijzigd, waarna ze worden doorgevoerd in de rest van de infrastructuur.
Volgende zul je modules definiëren, gebruiken en aanpassen in je Terraform-projecten.
Het maken van een Module
In deze sectie zul je meerdere Droplets en een Load Balancer definiëren als Terraform-resources en ze verpakken in een module. Je zult ook de resulterende module aanpasbaar maken met behulp van module-invoer.
Je zult de module opslaan in een map genaamd droplet-lb
, onder een map genaamd modules
. Als je ervan uitgaat dat je je bevindt in de terraform-modules
-map die je hebt aangemaakt als onderdeel van de vereisten, maak beide dan in één keer aan door het volgende uit te voeren:
Het -p
-argument geeft aan mkdir
opdracht om alle mappen in het opgegeven pad te maken.
Navigeer ernaartoe:
Zoals werd opgemerkt in de vorige sectie, bevatten modules de resources en variabelen die ze gebruiken. Vanaf Terraform 0.13
moeten ze ook definities bevatten van de providers die ze gebruiken. Modules vereisen geen speciale configuratie om aan te geven dat de code een module vertegenwoordigt, omdat Terraform elke map die HCL-code bevat beschouwt als een module, zelfs de hoofdmap van het project.
Variabelen die zijn gedefinieerd in een module worden blootgesteld als de invoer ervan en kunnen worden gebruikt in resource-definities om ze aan te passen. De module die je gaat maken, zal twee invoeren hebben: het aantal Droplets om te maken en de naam van hun groep. Maak een bestand genaamd variables.tf
aan en open het voor bewerking, waar je de variabelen zult opslaan:
Voeg de volgende regels toe:
Sla het bestand op en sluit het af.
Je zult de Droplet-definitie opslaan in een bestand met de naam droplets.tf
. Maak het aan en open het voor bewerking:
Voeg de volgende regels toe:
Voor de parameter count
, die aangeeft hoeveel instanties van een bron moeten worden gemaakt, geef je de variabele droplet_count
door. De waarde ervan wordt gespecificeerd wanneer de module wordt aangeroepen vanuit de hoofdprojectcode. De naam van elke ingezette Droplet zal verschillend zijn, wat je bereikt door het indexnummer van de huidige Droplet toe te voegen aan de meegeleverde groepsnaam. Het implementeren van de Droplets zal plaatsvinden in de regio fra1
en ze zullen Ubuntu 20.04 uitvoeren.
Als je klaar bent, sla het bestand op en sluit het af.
Met de Droplets nu gedefinieerd, kun je doorgaan met het maken van de Load Balancer. Je zult de definitie van de bron opslaan in een bestand met de naam lb.tf
. Maak het aan en open het voor bewerking door het volgende uit te voeren:
Voeg de definitie van de bron toe:
Je definieert de Load Balancer met de groepsnaam in de naam om het onderscheidbaar te maken. Je implementeert het in de regio fra1
samen met de Droplets. De volgende twee secties specificeren de doel- en bewakingspoorten en protocollen.
De gemarkeerde droplet_ids
blok neemt de ID’s van de Droplets aan die beheerd moeten worden door de Load Balancer. Aangezien er meerdere Droplets zijn en hun aantal niet van tevoren bekend is, gebruik je een for
-lus om door de verzameling Droplets (digitalocean_droplet.droplets
) te traverseren en hun ID’s te nemen. Je omringt de for
-lus met haakjes ([]
) zodat de resulterende verzameling een lijst zal zijn.
Sla het bestand op en sluit het af.
Je hebt nu de Droplet, Load Balancer en variabelen voor je module gedefinieerd. Je moet de providervereisten definiëren, waarbij je aangeeft welke providers de module gebruikt, inclusief hun versie en waar ze zich bevinden. Sinds Terraform 0.13
moeten modules expliciet de bronnen van niet door Hashicorp onderhouden providers definiëren; dit komt doordat ze deze niet erven van het ouderproject.
Je slaat de providervereisten op in een bestand met de naam provider.tf
. Maak het klaar voor bewerking door het volgende uit te voeren:
Voeg de volgende regels toe om de digitalocean
provider te vereisen:
Sla het bestand op en sluit het af wanneer je klaar bent. De droplet-lb
module vereist nu de digitalocean
provider.
Modules ondersteunen ook uitvoer, die je kunt gebruiken om interne informatie over de status van hun resources te extraheren. Je zult een uitvoer definiëren die het IP-adres van de Load Balancer blootlegt, en deze opslaan in een bestand met de naam outputs.tf
. Maak het klaar voor bewerking:
Voeg de volgende definitie toe:
Deze uitvoer haalt het IP-adres van de Load Balancer op. Sla het bestand op en sluit het af.
De module droplet-lb
is nu functioneel compleet en klaar voor implementatie. U zult het aanroepen vanuit de hoofdcode, die u zult opslaan in de hoofdmap van het project. Navigeer eerst daar naartoe door twee keer omhoog te gaan door uw bestandsdirectory:
Vervolgens maakt u een bestand genaamd main.tf
aan en opent u het voor bewerking, waarin u de module zult gebruiken:
Voeg de volgende regels toe:
In deze verklaring roept u de module droplet-lb
aan die zich bevindt in de opgegeven map als source
. U configureert de invoer die het biedt, droplet_count
en group_name
, die is ingesteld op group1
zodat u later onderscheid kunt maken tussen instanties.
Aangezien de uitvoer van het Load Balancer IP is gedefinieerd in een module, wordt deze niet automatisch weergegeven wanneer u het project toepast. De oplossing hiervoor is om een andere uitvoer te maken die de waarde ophaalt (loadbalancer_ip
).
Sla het bestand op en sluit het af wanneer u klaar bent.
Initialiseer de module door het volgende uit te voeren:
De uitvoer ziet er als volgt uit:
OutputInitializing modules...
- groups in modules/droplet-lb
Initializing the backend...
Initializing provider plugins...
- Finding digitalocean/digitalocean versions matching "~> 2.0"...
- Installing digitalocean/digitalocean v2.19.0...
- Installed digitalocean/digitalocean v2.19.0 (signed by a HashiCorp partner, key ID F82037E524B9C0E8)
...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
U kunt proberen het project te plannen om te zien welke acties Terraform zou uitvoeren door het volgende uit te voeren:
De uitvoer zal vergelijkbaar zijn met dit:
Deze uitvoer geeft aan dat Terraform drie Droplets zal aanmaken, genaamd group1-0
, group1-1
en group1-2
, en ook een Load Balancer genaamd group1-lb
, die het verkeer naar en van de drie Droplets zal beheren.
Je kunt proberen het project toe te passen op de cloud door het volgende uit te voeren:
Voer ja
in wanneer daarom wordt gevraagd. De uitvoer zal alle acties tonen en het IP-adres van de Load Balancer zal ook worden getoond:
Je hebt een module gemaakt met een aanpasbaar aantal Droplets en een Load Balancer die automatisch wordt geconfigureerd om het inkomende en uitgaande verkeer te beheren.
Hernoemen van Gedeployde Bronnen
In de vorige sectie heb je de module geïmplementeerd die je hebt gedefinieerd en heb je deze groups
genoemd. Als je ooit de naam wilt wijzigen, zal het eenvoudigweg hernoemen van de module-aanroep niet de verwachte resultaten opleveren. Het hernoemen van de aanroep zal Terraform dwingen bronnen te vernietigen en opnieuw te maken, wat leidt tot overmatige downtime.
Bijvoorbeeld, open main.tf
om te bewerken door het volgende uit te voeren:
Hernoem de module groups
naar groups_renamed
, zoals hieronder gemarkeerd:
Sla het bestand op en sluit het af. Initialiseer vervolgens het project opnieuw:
Je kunt nu het project plannen:
De uitvoer zal lang zijn, maar er zal iets vergelijkbaars uitzien als dit:
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
- destroy
Terraform will perform the following actions:
# module.groups.digitalocean_droplet.droplets[0] zal worden vernietigd
...
# module.groups_renamed.digitalocean_droplet.droplets[0] zal worden gemaakt
...
Terraform zal je vragen de bestaande instanties te vernietigen en nieuwe te maken. Dit is destructief en onnodig, en kan leiden tot ongewenste downtime.
In plaats daarvan kun je met behulp van het moved
-blok Terraform instrueren om oude bronnen onder de nieuwe naam te verplaatsen. Open main.tf
om te bewerken en voeg de volgende regels toe aan het einde van het bestand:
Als je klaar bent, sla je het bestand op en sluit je het af.
Je kunt nu het project plannen:
Wanneer je plant met het moved
-blok aanwezig in main.tf
, wil Terraform de bronnen verplaatsen in plaats van ze opnieuw aan te maken:
OutputTerraform will perform the following actions:
# module.groups.digitalocean_droplet.droplets[0] is verplaatst naar module.groups_renamed.digitalocean_droplet.droplets[0]
...
# module.groups.digitalocean_droplet.droplets[1] is verplaatst naar module.groups_renamed.digitalocean_droplet.droplets[1]
...
Het verplaatsen van resources verandert hun positie in de Terraform-state, wat betekent dat de daadwerkelijke cloudresources niet worden gewijzigd, vernietigd of opnieuw gemaakt.
Omdat je de configuratie aanzienlijk zult wijzigen in de volgende stap, vernietig je de ingezette resources door het volgende uit te voeren:
Voer ja
in wanneer hierom wordt gevraagd. De uitvoer eindigt met:
Output...
Destroy complete! Resources: 4 destroyed.
In deze sectie heb je resources hernoemd in je Terraform-project zonder ze daarbij te vernietigen. Je gaat nu meerdere instanties van een module vanuit dezelfde code implementeren met behulp van for_each
en count
.
Het implementeren van meerdere module-instanties
In deze sectie gebruik je count
en for_each
om de droplet-lb
-module meerdere keren te implementeren met aanpassingen.
Gebruik van count
Een manier om meerdere exemplaren van dezelfde module tegelijk te implementeren, is door het aantal door te geven aan de count
-parameter, die automatisch beschikbaar is voor elke module. Open main.tf
om te bewerken:
Wijzig het zodat het er zo uitziet, verwijder de bestaande outputdefinitie en het verplaatste
-blok:
Door count
in te stellen op 3
, geef je Terraform de opdracht om de module drie keer te implementeren, elk met een andere groepsnaam. Wanneer je klaar bent, sla het bestand op en sluit het.
Plan de implementatie door het volgende uit te voeren:
De uitvoer zal lang zijn en er zal zo uitzien:
Terraform geeft details in de uitvoer dat elk van de drie module-instanties drie Droplets en een Load Balancer zou hebben die eraan zijn gekoppeld.
Met behulp van for_each
Je kunt for_each
gebruiken voor modules wanneer je complexere instantieaanpassingen nodig hebt, of wanneer het aantal instanties afhankelijk is van externe gegevens (vaak gepresenteerd als kaarten) die niet bekend zijn tijdens het schrijven van de code.
Je gaat nu een kaart definiëren die groepsnamen koppelt aan Droplet-tellingen en instanties van droplet-lb
volgens die kaart implementeren. Open main.tf
om te bewerken door het volgende uit te voeren:
Wijzig het bestand zodat het er als volgt uitziet:
Je definieert eerst een kaart genaamd group_counts
die aangeeft hoeveel Droplets een bepaalde groep moet hebben. Vervolgens roep je de module droplet-lb
aan, maar geef je aan dat de for_each
-lus moet werken op var.group_counts
, de kaart die je net daarvoor hebt gedefinieerd. droplet_count
neemt each.value
, de waarde van het huidige paar, die het aantal Droplets voor de huidige groep is. group_name
ontvangt de naam van de groep.
Sla het bestand op en sluit het af wanneer je klaar bent.
Probeer de configuratie toe te passen door het volgende uit te voeren:
De uitvoer zal gedetailleerd beschrijven welke acties Terraform zou ondernemen om de twee groepen met hun Droplets en Load Balancers te maken:
In deze stap heb je count
en for_each
gebruikt om meerdere aangepaste instanties van dezelfde module vanuit dezelfde code te implementeren.
Conclusie
In deze tutorial heb je Terraform-modules gemaakt en geïmplementeerd. Je hebt modules gebruikt om logisch gekoppelde bronnen samen te voegen en aangepast om meerdere verschillende instanties vanuit een centrale code-definitie te implementeren. Je hebt ook uitvoer gebruikt om attributen van bronnen die in de module zijn opgenomen te tonen.
Als je meer wilt weten over Terraform, bekijk dan onze serie Hoe infrastructuur te beheren met Terraform.
Source:
https://www.digitalocean.com/community/tutorials/how-to-build-a-custom-terraform-module