Hoe Flexibiliteit te verbeteren met Terraform variabelen, afhankelijkheden en condities

Inleiding

Hashicorp Configuration Language (HCL), die Terraform gebruikt, biedt veel nuttige structuren en mogelijkheden die aanwezig zijn in andere programmeertalen. Door gebruik te maken van lussen in uw infrastructuurcode kunt u codeherhalting drastisch verminderen en de leesbaarheid verhogen, wat makkelijkere toekomstige refactoring en grotere flexibiliteit mogelijk maakt. HCL biedt ook enkele algemene gegevensstructuren, zoals lijsten en tabellen (die respectievelijk in andere talen arrays en woordenboeken worden genoemd), evenals condities voor het afgaan van een uitvoerbaarheidspad.

Uniek voor Terraform is de mogelijkheid om handmatig de resources op te geven waarop men afhankelijk is. Terwijl de uitvoeringsgrafiek die het bij het uitvoeren van uw code bouwt al de gedetecteerde koppelingen bevat (die in de meeste gevallen correct zijn), kan het voorkomen dat u zich in nood aanhoudt om een afhankelijkheidsrelatie in te stellen die Terraform niet heeft kunnen detecteren.

In dit artikel zullen we de gegevensstructuren die HCL biedt, haar lussen voor resources (het sleutelwoord count, for_each en for), condities voor het afhandelen van bekende en onbekende waarden, en de afhankelijkheden tussen resources bekijken.

Vereisten

  • Een DigitalOcean Persoonlijke Toegangstoken, dat u kunt maken via het DigitalOcean controlepaneel. U kunt instructies vinden in de DigitalOcean productdocumenten, Hoe een Persoonlijk Toegangstoken te maken.
  • Terraform geïnstalleerd op uw lokale machine en een project opgezet met de DigitalOcean provider. Voltooi Stap 1 en Stap 2 van de Hoe Terraform gebruiken met DigitalOcean handleiding, en zorg ervoor dat uw projectmap terraform-flexibility noemt, in plaats van loadbalance. Tijdens Stap 2 hoeft u de variabele pvt_key en de SSH-sleutelbron niet bij het configureren van de provider op te nemen.

Opmerking: Deze handleiding is specifiek getest met Terraform 1.0.2.

Data Typen in HCL

Voordat u meer leert over loops en andere functies van HCL die uw code flexibeler maken, gaat u eerst over de beschikbare data typen en hun toepassingen.

Het Hashicorp Configuratie taal ondersteunt primitieve en complexe datatypes. Primitieve datatypes zijn strings, getallen en booleaan waarden, die de basissoorten zijn die niet uit andere soorten kunnen worden afgeleid. Complexe typen, op de ander hand, groeperen meerdere waarden samen in een enkele waarde. De twee soorten complexe waarden zijn structuurlijke en collectie typen. Structuurlijke typen bieden aan om waarden van verschillende soorten te groeperen samen. Een belangrijk voorbeeld zijn de definities van bronnen die je gebruikt om te specificeren wat je infrastructuur zou moeten lijken. In vergelijking met de structuurlijke typen, groeperen collectie typen ook waarden, maar alleen waarden van dezelfde soort. Bekendstaande drie collectie typen beschikbaar in HCL die we interesseren zijn: lijsten, mapjes en sets.

Lijsten

.

Lijsten zijn gelijk aan arrays in andere programmeertalen. Ze bevatten een bekend aantal elementen van dezelfde soort, die via de array notatie ([]) door hun hele-getalindex, startend bij 0, worden toegankelijk gemaakt. Hier is een voorbeeld van een variabel declaratie met namen van Dropletten die je in de volgende stappen deploy zal in de cloud:

variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third"]
}

Voor de type, heb je gespecifieerd dat het een lijst is waarvan de elementen type string zijn en dan zijn default waarde gegeven. In HCL betekent een lijst met voegels gescheiden door haakjes.

Maps

Kaarten zijn verzamelingen van sleutel-waardeparen, waar elke waarde wordt aangetoond door middel van zijn sleutel van het type string. Er zijn twee manieren om kaarten binnen haakjes te specificeren: door gebruik te maken van kolommen (:) of gelijkheidstekens (=) voor het specificeren van waarden. In beide gevallen moet de waarde tussen aanhalingstekens worden geplaatst. Bij het gebruik van kolommen moet de sleutel ook worden afgekapt.

Het volgende kaartdefinitie met Droplet-namen voor verschillende omgevingen is geschreven met behulp van het gelijkheidsteken:

variable "droplet_env_names" {
  type = map(string)

  default = {
    development = "dev-droplet"
    staging = "staging-droplet"
    production = "prod-droplet"
  }
}

Als de sleutel begint met een nummer, moet u de kolomnotatie gebruiken:

variable "droplet_env_names" {
  type = map(string)

  default = {
    "1-development": "dev-droplet"
    "2-staging": "staging-droplet"
    "3-production": "prod-droplet"
  }
}

Sets

Sets ondersteunen geen elementenvolgorde, wat betekent dat het doorlopen van sets geen garantie biedt om elke keer dezelfde volgorde te produceren en dat hun elementen niet in een doelgerichte manier kunnen worden aangetroffen. Ze bevatten unieke elementen exact eenmaal herhaald en het opnieuw specificeren van hetzelfde element zal resulteren in hun samenvoeging, met slechts een enkele instantie aanwezig in de set.

Het declareren van een set lijkt op het declareren van een lijst, de enige verschillende zijn het type van de variabele:

variable "droplet_names" {
  type    = set(string)
  default = ["first", "second", "third", "fourth"]
}

Nu dat u heeft geleerd over de typen datastructuren die HCL biedt en de syntaxis van lijsten, kaarten en sets heeft overgeslagen, die we in deze handleiding gebruiken, zult u doorgaan met het testen van flexibele manieren om meerdere instanties van hetzelfde resource in Terraform uit te voeren.

Het aantal bronnen instellen met de count-key

In deze sectie zullen u meerdere instanties van dezelfde bron maken gebruikmakend van de count-key. De count-key is een parameter die beschikbaar is voor alle bronnen en specificeert hoe veel exemplaren te maken.

U kunt het werken ondervinden door een Droplets bron te schrijven, die u in een bestand droplets.tf op de projectmap schrijft die u als onderdeel van de voorwaarden heeft gemaakt. Maak het bestand open en schrijf de volgende lijnen:

  1. nano droplets.tf

Gebruik de volgende regels:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = 3
  image  = "ubuntu-20-04-x64"
  name   = "web"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

Dit code definieert een Droplet bron genaamd test_droplet, die Ubuntu 20.04 draait met 1GB RAM en één CPU-core.

Bekijk dat de waarde van count is ingesteld op 3, wat betekent dat Terraform proberen zal om drie exemplaren van dezelfde bron te maken. Wanneer u klaar is, slaaf en sluit het bestand.

U kunt het project plannen om te zien welke acties Terraform zou uitvoeren door te runnen:

  1. terraform plan -var "do_token=${DO_PAT}"

De uitvoer zal er bijna gelijken:

Output
... 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: # digitalocean_droplet.test_droplet[0] wordt gecreated + resource "digitalocean_droplet" "test_droplet" { ... name = "web" ... } # digitalocean_droplet.test_droplet[1] wordt gecreated + resource "digitalocean_droplet" "test_droplet" { ... name = "web" ... } # digitalocean_droplet.test_droplet[2] wordt gecreated + resource "digitalocean_droplet" "test_droplet" { ... name = "web" ... } Plan: 3 to add, 0 to change, 0 to destroy. ...

De uitvoer van deze opdracht zal drie instellingen van een test_droplet aanmaken met dezelfde naam web. Dit is mogelijk, maar wordt niet geadvanceerd gebruikt, dus laten we de definitie van de Dropleten aanpassen om de naam van elke instantie uniek te maken. Open droplets.tf voor het editeren:

  1. nano droplets.tf

Bewerk de gehighlighteerde lijn:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = 3
  image  = "ubuntu-20-04-x64"
  name   = "web.${count.index}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

Sla de wijzigingen op en sluit de bestand

De count object biedt de index parameter, die de index van de huidige iteratie bevat, beginnend met 0. De huidige index wordt ingevoegd in de naam van de Droplet door string interpolatie, wat je toe staat dynamisch een string te bouwen door variabelen te substitueren. Je kunt het project opnieuw plannen om de wijzigingen te zien:

  1. terraform plan -var "do_token=${DO_PAT}"

De uitvoer zal er bijna gelijk zijn aan dit:

Output
... 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: # digitalocean_droplet.test_droplet[0] wordt gemaakt + resource "digitalocean_droplet" "test_droplet" { ... name = "web.0" ... } # digitalocean_droplet.test_droplet[1] wordt gemaakt + resource "digitalocean_droplet" "test_droplet" { ... name = "web.1" ... } # digitalocean_droplet.test_droplet[2] wordt gemaakt + resource "digitalocean_droplet" "test_droplet" { ... name = "web.2" ... } Plan: 3 to add, 0 to change, 0 to destroy. ...

Dit keer zullen de drie instanties van test_droplet hun index in hun namen hebben, waardoor ze makkelijker te volgen zijn.

Je kent nu hoe je meerdere instanties van een bron kan maken met behulp van de count-key, alsook hoe je een item uit een lijst opfetch en gebruiken tijdens provisioning. Volgende lees je hoe je de naam van een Droplet uit een lijst fetcht.

Het ophalen van naamnen uit een lijst

In situaties waar meerdere instellingen van dezelfde bron een aangepaste naam nodig hebben, kunt u ze dynamisch op basis van een lijst variabeel definieren die u definieert. Tijdens de rest van deze tutorial zien we diverse manieren om Droplet deployments te automatiseren met behulp van een lijst namen, promotend flexibiliteit en gemak.

U bent eerst een bestand aan te maken genaamd variables.tf en het openen voor het eden:

  1. nano variables.tf

Voeg de volgende regels toe:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third", "fourth"]
}

Sla het en sluit het bestand af. Dit code definieert een lijst genaamd droplet_names, met de string first, second, third, en fourth.

Open droplets.tf voor het eden:

  1. nano droplets.tf

Bewerk de gehighlighteerde regels:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = length(var.droplet_names)
  image  = "ubuntu-20-04-x64"
  name   =  var.droplet_names[count.index]
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

Om beter flexibiliteit te bieden, in plaats van handmatig een constante aantal elementen te specificeren, geeft u de lengte van de droplet_names lijst aan de count parameter, welke altijd de aantal elementen in de lijst teruggeeft. Voor de naam haalt u het element uit de lijst die geordineerd is bij count.index, gebruikkend de array-bracket notatie. Sla het en sluit het bestand als je klaar is.

Probeer het project opnieuw te plannen. U krijgt output gelijk aan dit:

Output
... 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: Een DigitalOcean-dropleten wordt gemaakt. + resource "digitalocean_droplet" "test_droplet" { ... + name = "first" ... } Een tweede DigitalOcean-dropleten wordt gemaakt. + resource "digitalocean_droplet" "test_droplet" { ... + name = "second" ... } Een derde DigitalOcean-dropleten wordt gemaakt. + resource "digitalocean_droplet" "test_droplet" { ... + name = "third" ... } Een vierde DigitalOcean-dropleten wordt gemaakt. + resource "digitalocean_droplet" "test_droplet" { ... + name = "fourth" ... Plan: 4 to add, 0 to change, 0 to destroy. ...

Uit deze wijzigingen zou er vier Dropletten worden geïnstalleerd, naar volgorde van de elementen in de lijst droplet_names.

Je hebt geleerd over count, zijn functies en syntaxis, en hebt hem samen met een lijst gebruikt om resource-instanties te modificeren. Nu zie je zijn voordelen, en hoe je ze overcomes.

Onderstaande de Disadvantages van count

Nu dat je weet hoe count wordt gebruikt, laten we het nageven wat zijn nadelen zijn wanneer je de lijst die hij wordt gebruikt met modificeert.

Probeer nu de Dropletten op de cloud te deployeren:

  1. terraform apply -var "do_token=${DO_PAT}"

Gebruik ja als je wordt aangevraagd. De einde van je uitvoer zal er bijna gelijk zijn aan dit:

Output
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Nu maak je nog een Droplet instantie aan door de droplet_names lijst te vergroten. Open variables.tf voor het editeren:

  1. nano variables.tf

Voeg een nieuw element toe aan de beginnen van de lijst:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["zero", "first", "second", "third", "fourth"]
}

Wanneer je klaar is, sla je werk af en sluit je het bestand.

Plannen van het project:

  1. terraform plan -var "do_token=${DO_PAT}"

U krijgt een uitvoer als bijvoorbeeld dit:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create ~ update in-place Terraform will perform the following actions: # digitalocean_droplet.test_droplet[0] wordt in-plaats geupdate ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "first" -> "zero" ... } # digitalocean_droplet.test_droplet[1] wordt in-plaats geupdate ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "second" -> "first" ... } # digitalocean_droplet.test_droplet[2] wordt in-plaats geupdate ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "third" -> "second" ... } # digitalocean_droplet.test_droplet[3] wordt in-plaats geupdate ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "fourth" -> "third" ... } # digitalocean_droplet.test_droplet[4] wordt gecreerd + resource "digitalocean_droplet" "test_droplet" { ... + name = "fourth" ... } Plan: 1 to add, 4 to change, 0 to destroy. ...

De uitvoer laat zien dat Terraform de eerste vier Dropleten hernoemd zou en een vijfde genaamd vierde zou maken, omdat Terraform de elementen (Dropleten) als een ondersteund lijst met indexnummers identificeert. Zo is dit hoe Terraform initieel de vier Dropleten beschouwt:

Index Number 0 1 2 3
Droplet Name first second third fourth

Wanneer de nieuwe Droplet zero aan de begin van de lijst wordt toegevoegd, ziet zijn interne lijstrepresentatie er dan als volgens:

Index Number 0 1 2 3 4
Droplet Name zero first second third fourth

De vier initiële Dropleten zijn nu naar rechts verplaatst. Terraform vergelijkt daarna twee statestijlen die worden weergegeven in tabellen: op positie 0, de Droplet werd first genoemd, en omdat hij in de tweede tabel verschilt, plannen ze een actie voor update. Dit gaat door tot aan positie 4, waar er geen comparabele element is in de eerste tabel, en in plaats daarvan wordt een Droplet provisioning actie gepland.

Dit betekent dat het toevoegen van een nieuwe element aan de lijst ergens anders dan aan het einde zou leiden tot gewijzigingen in bronnen die niet nodig zijn. Gelijkmatige update-acties worden gepland als er een element uit de droplet_names lijst wordt verwijderd.

Het voornaamste probleem van het gebruik van count voor het deployen van een dynamische aantal verschillende instellingen van dezelfde bron is de slechte resource-tracking wanneer sommige attributen worden ingeleverd vanuit een variabele. Voor een constante aantal constante instanties is count een simpele oplossing die goed werkt. In situaties als deze, waar enkele attributen worden ingeleverd vanuit een variabele, is de for_each loop, die je later in deze tutorial leren zal, een veel betere keuze.

Refereren naar de huidige bron (self)

Een andere nadelige kant van count is dat refereren aan een arbitraire instelling van een bron door haar index niet mogelijk is in sommige gevallen.

De belangrijkste voorbeeld is destroy-time provisioners, die worden uitgevoerd wanneer de bron wordt geplanned te worden vernietigd. De reden is dat de opgevraagde instelling mogelijk niet bestaat (het is al vernietigd) of zou leiden tot een mutuale afhankelijkheidscyclus. In zooveel gevallen kan je slechts de huidige bron bereiken via de self-keyword.

Om zijn gebruik te demonstreren, zal u nu een verwijderingsmoment lokale voorbereider toevoegen aan de test_droplet definitie, die een bericht weergeeft als het wordt uitgevoerd. Open droplets.tf voor bewerking:

  1. nano droplets.tf

Voeg de volgende getoonde regels toe:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = length(var.droplet_names)
  image  = "ubuntu-20-04-x64"
  name   =  var.droplet_names[count.index]
  region = "fra1"
  size   = "s-1vcpu-1gb"

  provisioner "local-exec" {
    when    = destroy
    command = "echo 'Droplet ${self.name} is being destroyed!'"
  }
}

Bewaar en sluit het bestand.

De local-exec voorbereider voert een opdracht uit op de lokale machine waar Terraform wordt uitgevoerd. Omdat het parameter when is ingesteld op destroy, zal het alleen worden uitgevoerd als het resource wordt verwijderd. De uitgevoerde opdracht echo’t een string naar stdout, die de naam van het huidige resource vervangt met self.name.

Omdat u in de volgende sectie de Droplets anders zal maken, moet u de momenteel geïmplementeerde ones vernietigen door de volgende opdracht uit te voeren:

  1. terraform destroy -var "do_token=${DO_PAT}"

Geef yes mee bij het aangeven. U zult de local-exec voorbereider vier keer zien worden uitgevoerd:

Output
... digitalocean_droplet.test_droplet[0] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet first is being destroyed!'"] digitalocean_droplet.test_droplet[1] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet second is being destroyed!'"] digitalocean_droplet.test_droplet[1] (local-exec): Droplet second is being destroyed! digitalocean_droplet.test_droplet[2] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet third is being destroyed!'"] digitalocean_droplet.test_droplet[2] (local-exec): Droplet third is being destroyed! digitalocean_droplet.test_droplet[3] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet fourth is being destroyed!'"] digitalocean_droplet.test_droplet[3] (local-exec): Droplet fourth is being destroyed! digitalocean_droplet.test_droplet[0] (local-exec): Droplet first is being destroyed! ...

In deze stap heeft u de nadelen van count geleerd. Nu zal u over de for_each loopstructuur leren, die deze nadelen overkomt en op een bredere reeks van variabele typen werkt.

Lussen met for_each

In deze sectie zal u de for_each lus, haar syntaxis en hoe ze flexibelheid biedt bij het definiëren van resources met meerdere instanties overwegden.

voor elk is een parameter die beschikbaar is voor elke bron, maar in contrast met count, die een aantal instanties vereist om te maken, accepteert voor elk een map of een set. Elk element van de gegeven collectie wordt één keer doorlopen en er wordt een instantie gemaakt voor het. voor elk accepteert een map of een set. Elke element van de gegeven collectie wordt één keer doorlopen en er wordt een instantie gemaakt voor het. De sleutel en waarde zijn beschikbaar onder de each keyword als attributen (de paars waarde each.key en each.value, respectievelijk). Wanneer een set wordt geleverd, heeft de sleutel en waarde dezelfde waarde.Omdat het de huidige element in de each object biedt, hoef je niet manueel de gewenste element te accessen zoals je dat deed met lijsten. Bij gebruik van sets is dat niet mogelijk omdat sets intern geen herkenbare volgorde hebben. Lijsten kunnen ook worden geleverd, maar ze moeten eerst worden geconvertiseerd naar een set met de toset functie.De voornaamste voordeel van het gebruik van voor elk, naast het mogelijkheid alle drie collectie data types te enumeratieren, is dat alleen de betrokken elementen worden verandert, gemaakt of verwijderd. Als je de volgorde van de elementen in de input wijzigt, worden geen acties geplande, en als je een element toevoegt, verwijdert of modificeert uit de input, worden aanpassende acties geplande alleen voor dat element.Laten we de Droplets resource van count naar voor elk converteren en zien hoe het werkt in praktijk. Open droplets.tf voor editering door te runnen:Bewerk de gethighlighted lijnen:Je kan de local-exec provisioner verwijderen. Wanneer je klaar is, sla je wijzigingen op en sluit je het bestand af.

  1. nano droplets.tf
terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  for_each = toset(var.droplet_names)
  image    = "ubuntu-20-04-x64"
  name     = each.value
  region   = "fra1"
  size     = "s-1vcpu-1gb"
}

De eerste regel vervangt count en roept for_each aan, door het droplet_names lijst in de vorm van een verzameling mee te geven gebruik makend van de toset functie, die automatisch de gegeven invoer converteert. Voor de Droplet naam geef je each.value, die de waarde van het huidige element uit de verzameling van Droplet namen bevat.

Project plannen door uit te voeren:

  1. terraform plan -var "do_token=${DO_PAT}"

De uitvoer zal details van de stappen weergeven die Terraform zou ondernemen:

Output
... 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: # digitalocean_droplet.test_droplet["first"] zal worden aangemaakt + resource "digitalocean_droplet" "test_droplet" { ... + name = "first" ... } # digitalocean_droplet.test_droplet["fourth"] zal worden aangemaakt + resource "digitalocean_droplet" "test_droplet" { ... + name = "fourth" ... } # digitalocean_droplet.test_droplet["second"] zal worden aangemaakt + resource "digitalocean_droplet" "test_droplet" { ... + name = "second" ... } # digitalocean_droplet.test_droplet["third"] zal worden aangemaakt + resource "digitalocean_droplet" "test_droplet" { ... + name = "third" ... } # digitalocean_droplet.test_droplet["zero"] zal worden aangemaakt + resource "digitalocean_droplet" "test_droplet" { ... + name = "zero" ... } Plan: 5 to add, 0 to change, 0 to destroy. ...

In tegenstelling tot het gebruik van count, gaat Terraform nu elke instantie individueel in acht en niet als elementen van een geordende lijst. Elke instantie is gekoppeld aan een element van de gegeven verzameling, zoals aangegeven door de getoonde stringelementen in de haakjes naast elk resource dat wordt aangemaakt.

U kunt uw project op de cloud toepassen door uit te voeren:

  1. terraform apply -var "do_token=${DO_PAT}"

Type yes wanneer u gevraagd wordt. Wanneer het klaar is, verwijderd u een element uit de droplet_names lijst om te demonstreren dat andere instanties niet worden beïnvloed. Open variables.tf voor bewerking:

  1. nano variables.tf

Modify the list to look like this:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third", "fourth"]
}

Sla de wijzigingen op en sluit de bestand

Bepaal het project opnieuw, en u krijgt de volgende uitvoer:

Output
... 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: # de digitale oceaan droplet.test_droplet["zero"] wordt verwijderd - resource "digitalocean_droplet" "test_droplet" { ... - name = "zero" -> null ... } Plan: 0 to add, 0 to change, 1 to destroy. ...

Dit keer zou Terraform alleen de verwijderde instance (zero) destructeren, en zou niet aan de andere instances toekomen, wat de juiste gedrag is.

In deze stap hebben u geleerd over for_each, hoe u hem gebruikt, en welke voordelen hij biedt over count. Nu leer je over de for loop, zijn syntaxis en gebruik, en wanneer het kan worden gebruikt om bepaalde taken te automatiseren.

Looping met behulp van for

De for-loop werkt op collecties en maakt een nieuwe collectie door elk element van de input te transformeren. De exacte type van de output wordt afhankelijk van of de loop wordt begrensd door haakjes ({}) of vierkantjes ([]), die respectievelijk een lijst of een map oplever. Daarom is het geschikt voor het query-resources en vormen structuurde uitvoer voor latere processering.

De algemene syntaxis van de for-loop is:

for element in collection:
transform(element)
if condition

Naar gelijkenheid met andere programmeerlinguïsten, beginnen ze je eerst met de benaming van de traverse variabele (element) en specificeren je het collectie om te enumeratene. De lichaam van de loop is de transformatie-stap, en de optionele if clausecan worden gebruikt voor filterings van de ingangs collectie.

Je zal nu een paar voorbeelden gebruiken met uitvoer. Je zal ze opslaan in een bestand genaamd outputs.tf. Maak het bestand voor bewerkingsdoelen door de volgende commando’s te runnen:

  1. nano outputs.tf

Voeg de volgende lijnen toe aan de uitvoer van paren met de namen van geïnstalleerde Droplets en hun IP-adressen:

terraform-flexibility/outputs.tf
output "ip_addresses" {
  value = {
    for instance in digitalocean_droplet.test_droplet:
    instance.name => instance.ipv4_address
  }
}

Dit code specificeert een uitvoer genaamd ip_addresses, en specificeert een for loop dat iteraties over de instanties van de test_droplet resource hebt gemaakt die je in de vorige stappen aanpast hebt. Omdat de loop omgevouwd is bij curly brackets, zijn de uitvoer een map. De transformatie-stap voor maps is gelijk aan lambda functies in andere programmeerlinguïten, en hier maakt hij een key-value pair door de naam van de instantie als de key te combineren met haar privé-IP als waarde.

Sla de file sluiten en refreshen de Terraform staat om rekening te houden met de nieuwe uitvoer door de volgende commando’s te runnen:

  1. terraform refresh -var "do_token=${DO_PAT}"

De Terraform refresh commando updaten de lokale staat met de werkelijke staat van de infrastructuur in de cloud.

Dan controleer de inhoud van de uitvoer:

Output
ip_addresses
= { "first" = "ip_address" "fourth" = "ip_address" "second" = "ip_address" "third" = "ip_address" }

Terraform heeft de inhoud van de uitvoer ip_addresses geïnterpreteerd, die wordt gemaakt door de for lus. Deze lus werkt perfect voor elke aantal items – wat betekent dat je een nieuwe element toe kunt voegen aan de droplet_names lijst en de nieuwe Droplets zonder meer manuele ingrijpen automatisch zouden opduiken in deze uitvoer.

Door de for lus te schrijven in rechthoeken, kun je de uitvoer als lijst laten zien. Bijvoorbeeld, je kunt alleen de IP-adressen van de Droplets uitgeven, wat nuttig is voor externe software die de data moet parseren. De code zou er dan als volgende uitzien:

terraform-flexibility/outputs.tf
output "ip_addresses" {
  value = [
    for instance in digitalocean_droplet.test_droplet:
    instance.ipv4_address
  ]
}

Hier selecteert de transformatie de IP-adres attribuut. Het zou de volgende uitvoer geven:

Output
ip_addresses
= [ "ip_address", "ip_address", "ip_address", "ip_address", ]

Zoals eerder vermeld, kunt u ook de input collectie filteren met behulp van de if clausule. Hier is hoe je de loop schrijft om te filteren op de fra1 regio:

terraform-flexibility/outputs.tf
output "ip_addresses" {
  value = [
    for instance in digitalocean_droplet.test_droplet:
    instance.ipv4_address
    if instance.region == "fra1"
  ]
}

In HCL gebruikt je de == operator om de waarden van de twee kanten gelijkheid te controleren – hier controleert hij of instance.region gelijk is aan fra1. Als het zo is, passt de check en wordt de instance geproefd en toegevoegd aan de uitvoer, anders wordt het overgeslagen. De uitvoer van deze code zou hetzelfde zijn als de vorige voorbeelden, omdat alle Droplets volgens de definitie van de test_droplet bron in de fra1 regio zijn. De if conditie is ook handig wanneer je andere waarden in je project wilt filteren, bijvoorbeeld de Droplets grootte of distributie.

Om je in de volgende sectie op een andere manier te gaan bouwen, moet je de momenteel geïnstalleerde bronnen verwijderen door de volgende commando uit te voeren:

  1. terraform destroy -var "do_token=${DO_PAT}"

Gebruik ja als je wordt aangevraagd om het proces te voltooien.

We hebben de for-lus, haar syntaxis en voorbeelden van gebruik in outputten besproken. Nu leren we over conditieals en hoe ze samen met count kunnen worden gebruikt.

Directives and Conditionals

Een van de vorige secties heb je de count-sleutel gezien en hoe hij werkt. Nu leren we over ternaire conditieoperatorn, die je ook elders in je Terraform-code kan gebruiken, en hoe je ze samen met count kan gebruiken.

De syntaxis van de ternaire operator is:

condition ? value_if_true : value_if_false

condition is een expressie die naar een booleaan (true of false) evalueert. Als de conditie waar is, dan evalueert de expressie tot value_if_true. Op de andere hand, als de conditie fout is, de resultaat zal zijn value_if_false.

Het belangrijkste gebruik van ternaire operatoren is om de creatie van een enkele resource aan te passen op de inhoud van een variabeel. Dit kan worden gedaan door de resultaat van de comparatie (een of twee 1 of 0) te doorgeven aan de count sleutel van de gewenste bron.

Als je de ternaire operator gebruikt om een enkele element te halen uit een lijst of een set, kun je de functie one gebruiken. Wanneer de gegeven collectie leeg is, retourneert hij null. Bij een enkele element in de collectie, of werpt hij een fout wanneer er meer dan één is.

Lees variables.tf openen voor het editeren:

  1. nano variables.tf

Voeg de ondersteine lijnen toe:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third", "fourth"]
}

variable "create_droplet" {
  type = bool
  default = true
}

Dit code definieert de variabele create_droplet, die van type bool is. Sla het bestand close en sluit het af.

Dan, om de declaratie van de Droplet te modificeren, open droplets.tf voor het editeren door te runnen:

  1. nano droplets.tf

Bewerk je bestand als volgt:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = var.create_droplet ? 1 : 0
  image  = "ubuntu-20-04-x64"
  name   =  "test_droplet"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

Voor count, gebruik je een ternaire operator om te returnen ofwel 1 als de variabele create_droplet waar is, ofwel 0 als falsch, wat resulteert in dat er geen Droplets worden geprovisioneerd. Sla het bestand close en sluit het af wanneer je klaar is.

Plan de uitvoering van het project met de variabele ingesteld op false door te runnen:

  1. terraform plan -var "do_token=${DO_PAT}" -var "create_droplet=false"

Je krijgt de volgende uitvoer:

Output
Changes to Outputs: + ip_addresses = {} You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.

Omdat create_droplet werd ingesteld in de waarde van false, is de count van instantiën 0, en zullen er geen Droplets worden gemaakt, dus zal er geen IP-adressen zijn om uit te voeren.

Uw review over hoe u de ternaire conditieoperator samen met de sleutel count gebruikt om een hoger niveau van flexibiliteit te bieden bij het kiezen of gewenste bronnen worden geïnstalleerd. Volgens je leerstappen zal je nu leren over expliciete resource-afhankelijkenheden voor je bronnen.

Expliciete Resource-Afhankelijkheden instellen

Terraform detecteert automatisch de afhankelijkheidsketens tussen bronnen en ordent ze in de juiste volgorde om opgebouwd te worden. In de meeste gevallen is Terraform in staat de relaties te detecteren door alle expressies in bronnen te scannen en een graf te bouwen.

Maar wanneer een resource, om te worden geprovisioneerd, toegangscontroleinstellingen moet hebben die al zijn geïnstalleerd bij de cloud-provider, is er geen duidelijke aanwijzing voor Terraform dat ze onderling afhankelijk zijn. Daarom zal Terraform niet weten dat ze onderling betrekking hebben. In dergelijke gevallen moeten de afhankelijkheden manueel specificeren met behulp van de depends_on argument.

De depends_on-sleutel is beschikbaar voor elke resource en wordt gebruikt om specifieke relaties tussen bronnen te specificeren. Geheime afhankelijkheidsrelaties ontstaan wanneer een resource afhankelijk is van een andere bron’s gedrag, zonder daarvan gebruik te maken in haar declaratie, wat Terraform zou doen om hem eenmaal te verbinden.

Hier is een voorbeeld van hoe depends_on wordt gespecificeerd in code:

resource "digitalocean_droplet" "droplet" {
  image  = "ubuntu-20-04-x64"
  name   = "web"
  region = "fra1"
  size   = "s-1vcpu-1gb"

  depends_on = [
    Bronnen...
  ]
}

Het accepteert een lijst van referenties naar andere bronnen, en het accepteert geen willekeurige expressies.

depends_on moet sparingelijk worden gebruikt, en alleen wanneer alle andere opties zijn uitgeputd. Het gebruik ervan betekent dat wat u probeert te declareren buiten de grenzen van Terraforms automatisch detectie systeem voor afhankelijkheden gaat; het kan betekenen dat de resource expliciet meer resources afhankelijk is dan hij nodig heeft.

U hebt nu leerd dat je met behulp van de depends_on-key expliciet extra afhankelijkenheden voor een resource kunt instellen, en wel wanneer dit nodig is.

Conclusie

In deze artikelen hebben we over de functies van HCL gesproken die de flexibiliteit en scalabiliteit van uw code verbeteren, zoals count om te specificeren hoe veel instanties van een resource te deployen en for_each als een geavanceerde manier om collectie data types te loopen en aanpassingen te maken bij instanties. Wanneer ze correct gebruikt worden, verminderen ze enorm de duplicatie van code en de operationele overlast van het beheer van de geïnstalleerde infrastructuur.

Je hebt ook leerd over conditieloos en ternaire operator, en hoe ze kunnen worden gebruikt om te controleren of een resource wordt geïnstalleerd. Terraform’s automatische afhankelijkheidssystematiek is erg competent, maar er kunnen momenten zijn waarin je handmatig de afhankelijkhedens van een resource moet specificeren met behulp van de depends_on-key.

Deze handleiding is onderdeel van de Hoe To Manage Infrastructure with Terraform reeks. De reeks behandelt een aantal Terraform onderwerpen, van het voor het eerst installeren van Terraform tot het beheren van complexe projecten.

Source:
https://www.digitalocean.com/community/tutorials/how-to-improve-flexibility-using-terraform-variables-dependencies-and-conditionals