Ga naar inhoud

Aan de slag met Terraform

In dit artikel

Informatie

Terraform is een tool voor infrastructure as code, ontwikkeld door HashiCorp. De gewenste staat van de infrastructuur wordt beschreven in configuratiebestanden geschreven in HCL, en Terraform brengt de echte resources in lijn met die beschrijving door de API van de serviceprovider aan te roepen via een specifieke module die bekend staat als een provider. Elke uitgevoerde operatie wordt vastgelegd in een state-bestand, zodat de tool weet wat er al bestaat en bij de volgende run alleen de ontbrekende wijzigingen toepast. Terraform ondersteunt het vooraf bekijken van wijzigingen voordat ze worden toegepast, het bijhouden van de configuratie in versiebeheer en het reproduceren van identieke omgevingen, wat het een handige manier maakt om servers, netwerken en services te beheren, ongeacht wie ze host.

Wanneer je slechts één server hebt, is het handmatig bestellen sneller. Zodra er vijftien zijn, op verschillende tijdstippen aangemaakt door verschillende beheerders, weet niemand meer waarom de ene Ubuntu 20.04 draait terwijl de machine ernaast 22.04 draait. Een configuratiebestand houdt die geschiedenis automatisch bij en zorgt er ook voor dat je dezelfde omgeving kunt herstellen zonder een reeks handelingen uit het hoofd te hoeven reproduceren.

Met onze provider ziet de workflow er als volgt uit. Het bestand bevat de preset, de locatie, het besturingssysteem en het verkeersplan, waarna terraform apply de bestelling plaatst en wacht tot de implementatie is voltooid. Het opnieuw uitvoeren hiervan dupliceert niets, aangezien Terraform de resources die het heeft aangemaakt onthoudt. Het terraform plan commando toont de geplande wijzigingen zonder ze daadwerkelijk uit te voeren.

De provider werkt met de volledige catalogus, inclusief VPS, VDS, dedicated en GPU-servers, extra IP-adressen, SSH-keys en DNS-zones. Een volledige referentie voor de resources en data sources is beschikbaar in de Terraform Registry en in de hostkey-cloud/terraform-provider-hostkey-com repository. Wat volgt is het basisscenario: het bestellen van een virtuele server.

Wat je nodig hebt om met Terraform te werken

  • Een account in het Invapi control panel met voldoende saldo, aangezien het bestellen van een server een betaalde operatie is;
  • een API key;
  • een SSH key;
  • Terraform 1.0 of nieuwer.

Let op

Het account moet ten minste één server hebben. Invapi maakt geen sessie aan voor een account zonder services, en de authenticatie mislukt met No appropriate servers found. Als het account nieuw is, bestel dan de eerste server via het control panel en maak de rest aan met Terraform.

Stap 1. Terraform installeren

Terraform werkt op Linux, macOS en Windows, en je kunt het op twee manieren installeren: via een pakketbeheerder of handmatig door het vooraf gecompileerde binary te downloaden en uit te pakken.

Windows

Download het archief, pak terraform.exe uit in een specifieke map zoals C:\terraform, en voeg die map toe aan de Path omgevingsvariabele.

Sluit daarna de terminal en open deze opnieuw, aangezien de nieuwe Path waarde pas wordt toegepast na een herstart. Om de installatie te verifiëren:

terraform -v

Linux

wget https://releases.hashicorp.com/terraform/1.15.8/terraform_1.15.8_linux_amd64.zip
unzip ./terraform_1.15.8_linux_amd64.zip
sudo mv ./terraform /usr/local/bin
terraform -v

macOS

brew install terraform
terraform -v

Stap 2. Een API key aanmaken

De key wordt aangemaakt in het Invapi control panel. Klik op je gebruikersnaam in de rechterbovenhoek en selecteer API keys:

Klik op Add new en vul het formulier in.

Veld Waarde
Name 5-30 tekens, alleen Latijnse letters, cijfers, _ en -
Restrict a new API key only for the server Any
IP ACL Leeg laten om toegang vanaf elk adres toe te staan
Set login notification method None
Active Selected

Het veld Restrict a new API key only for the server koppelt de key aan een enkele service, en de provider moet nieuwe servers kunnen bestellen, dus de waarde moet Any zijn.

Het veld IP ACL beperkt de toegang tot de vermelde adressen. Dit verhoogt de beveiliging, maar bij een dynamisch IP-adres stopt de key met werken zodra het adres verandert. Laat het veld dus leeg wanneer je begint, en vermeld bij continuous integration de adressen van je build-servers.

Klik op Create. De key wordt slechts één keer getoond.

Let op

Sla de key onmiddellijk op, aangezien we alleen de hash bewaren en de waarde niet hersteld kan worden. Als je deze verliest, moet je een nieuwe aanmaken.

Stap 3. De configuratie voorbereiden

Configuratievoorbeelden

Klaar voor gebruik beschikbare configuratievoorbeelden zijn beschikbaar in de provider repository. Zie voor een basisinstelling het voorbeeld examples/basic.

Maak een projectmap aan, bijvoorbeeld hostkey-terraform. Configuratiebestanden gebruiken de extensie .tf en hun namen zijn willekeurig, aangezien Terraform elk .tf bestand in de map samenvoegt tot één configuratie. Ons voorbeeld gebruikt drie bestanden.

main.tf

Het eerste blok legt de provider en de vereiste Terraform-versie vast.

terraform {
  required_providers {
    hostkey = {
      source  = "hostkey-cloud/hostkey-com"
      version = "~> 0.2"
    }
  }
  required_version = ">= 1.0"
}

provider "hostkey" {}

Opmerking

Vanaf versie 0.2 wordt de provider afzonderlijk gepubliceerd voor elk facturatiesysteem. Het hostkey-com pakket werkt met invapi.hostkey.com, dus er hoeft geen API endpoint gekozen te worden en het provider-blok blijft leeg.

Vervolgens volgt de cataloguscontrole. Deze blokken maken geen resources aan en worden niet in rekening gebracht; ze vragen alleen de API om de lijsten met beschikbare presets en verkeersplannen:

data "hostkey_presets" "selected" {
  location = var.location
  name     = var.preset_name
}

data "hostkey_traffic_plans" "for_preset" {
  location    = var.location
  instance_id = data.hostkey_presets.selected.presets[0].id
}

output "catalog_preset" {
  value = data.hostkey_presets.selected.presets
}

output "catalog_traffic_plans" {
  value = data.hostkey_traffic_plans.for_preset.traffic_plans
}

Deze controle is het waard om twee redenen. De provider vereist een exacte naamovereenkomst, en de catalogus bevat vergelijkbare namen voor verkeersplannen, zoals bijvoorbeeld 3 TB / 1 Gbps VM en 3Tb traffic (1Gbps) VM. Bovendien hangt de inhoud van de catalogus af van de locatie en verandert deze in de loop van de tijd, dus een preset die vandaag beschikbaar is, kan morgen niet meer beschikbaar zijn.

De server zelf wordt hierna beschreven:

resource "hostkey_server" "web" {
  preset_name       = var.preset_name
  location_name     = var.location
  traffic_plan_name = var.traffic_plan_name
  deploy_period     = "monthly"

  os_name   = "Ubuntu 22.04"
  root_pass = var.root_pass
  ssh_key   = file(pathexpand(var.ssh_public_key_path))

  power_state = "on"

  cancellation_type   = 1
  cancellation_reason = "terraform"

  tags = {
    env = "demo"
  }

  timeouts {
    create = "90m"
    update = "90m"
    delete = "30m"
  }
}

Het timeouts blok bepaalt hoe lang Terraform wacht tot een operatie is voltooid. Implementatie duurt meestal een paar minuten, maar als het wachten wordt afgebroken door een timeout, blijft de bestelling betaald terwijl Terraform het spoor verliest.

Het argument cancellation_type ingesteld op 1 annuleert de service onmiddellijk, terwijl 0 de service laat doorlopen tot het einde van de betaalde periode.

Opmerking

Het argument hostname is bewust weggelaten uit het voorbeeld. Wanneer dit wordt weggelaten, genereert de provider een unieke naam zoals tf-44067425, en verschijnt de service onder die naam in het control panel. De naam binnen het besturingssysteem kan afwijken, aangezien Invapi deze niet doorgeeft aan de gast, dus de enige manier om dit te controleren is door hostname uit te voeren op de server zelf.

De SSH-key in de accountopslag wordt apart aangemaakt:

resource "hostkey_ssh_key" "deploy" {
  name = "tf-deploy"
  key  = file(pathexpand(var.ssh_public_key_path))
}

Dit is niet hetzelfde als het ssh_key attribuut van hostkey_server. Het server-attribuut schrijft de key naar de machine tijdens de installatie van het besturingssysteem, terwijl de hostkey_ssh_key resource de key in het account opslaat voor later gebruik.

Het bestand eindigt met output blokken. Na de bestelling print Terraform het serveradres, de identifier en het factuurnummer, en terraform output main_ipv4 geeft op elk gewenst moment later het adres terug, wat handig is wanneer er iets anders volgt:

output "server_id" {
  value = hostkey_server.web.id
}

output "main_ipv4" {
  value = hostkey_server.web.main_ipv4
}

output "invoice" {
  value = hostkey_server.web.invoice
}

variables.tf

variable "location" {
  type    = string
  default = "FI"
}

variable "preset_name" {
  type    = string
  default = "vm.v2-pico"
}

variable "traffic_plan_name" {
  type    = string
  default = "3 TB / 1 Gbps VM"
}

variable "root_pass" {
  type      = string
  sensitive = true
}

variable "ssh_public_key_path" {
  type    = string
  default = "~/.ssh/id_ed25519.pub"
}

terraform.tfvars

Dit bestand bevat het wachtwoord, zodat het niet in versiebeheer wordt gezet:

root_pass = "StrongPass1%"

# De defaults kunnen hier worden overschreven
# location          = "NL"
# preset_name       = "vm.v3-pico"
# traffic_plan_name = "5 TB / 1 Gbps VM"

Let op

Het root-wachtwoord moet 8 tot 30 tekens lang zijn en een hoofdletter, een kleine letter, een cijfer en een van %, -, _, + bevatten. De tekens @ en # zijn niet toegestaan. Het wachtwoord wordt opgeslagen in het Terraform state-bestand en wordt in platte tekst verzonden in de e-mail over de gereedheid van de server, dus wijzig dit zodra de server is geïmplementeerd.

Stap 4. De provider initialiseren

De key wordt via een omgevingsvariabele doorgegeven zodat deze buiten de projectbestanden blijft:

$env:HOSTKEY_API_KEY = "your-key"

Gebruik in de Windows opdrachtprompt set HOSTKEY_API_KEY=your-key, en op Linux en macOS export HOSTKEY_API_KEY="your-key". De variabele is alleen van toepassing op de huidige terminal-sessie.

Opmerking

De key is al nodig tijdens de planning-fase, aangezien de provider de namen uit de configuratie vergelijkt met de catalogus en zonder API-toegang zal falen.

Vervolgens moet de provider worden gedownload:

terraform init

Terraform downloadt de provider en maakt een .terraform.lock.hcl bestand aan met de exacte versie. Dit bestand wordt naar de repository gecommit, aangezien het garandeert dat iedereen in het project met dezelfde geïnstalleerde versie werkt.

Stap 5. De configuratie valideren

De syntaxis wordt gecontroleerd zonder de API aan te roepen:

terraform validate

Een succesvolle controle geeft Success! The configuration is valid. weer.

Vervolgens volgt het plan, dat de geplande wijzigingen toont zonder ze uit te voeren:

terraform plan

De samenvattingsregel. Verwacht Plan: 2 to add, 0 to change, 0 to destroy, dit zijn de server en de SSH-key.

De opgeloste identifiers. De provider vult preset_id, os_id en traffic_plan_id in naast de namen, en als een naam niet in de catalogus wordt gevonden, mislukt het plan voordat er iets in rekening wordt gebracht.

De catalogus. De sectie Changes to Outputs somt de presets en verkeersplannen op, en de waarden in de configuratie moeten exact op dezelfde manier worden geschreven.

Stap 6. De server bestellen

terraform apply

Terraform toont het plan nogmaals en vraagt om bevestiging; typ yes en druk op Enter.

Let op

Vanaf dit punt wordt de bestelling in rekening gebracht. Sluit het terminalvenster niet en onderbreek het commando niet, anders blijft de bestelling in het control panel staan terwijl Terraform het spoor verliest.

De SSH-key wordt eerst aangemaakt, waarna de serverbestelling begint; Terraform heeft deze volgorde zelf bepaald op basis van de afhankelijkheden.

Daarna volgen de Still creating... regels, die elke tien seconden worden ververst, terwijl de provider de API pollt en wacht tot de installatie is voltooid. Ondertussen is de server zichtbaar in het control panel:

Zodra het klaar is, worden de waarden geprint. Het is de moeite waard om de SSH-toegang te controleren met het adres dat je hebt ontvangen:

De key die is opgegeven in het ssh_key attribuut is al aanwezig op de server, dus er wordt geen wachtwoord gevraagd. De nieuwe server verschijnt in het control panel naast de handmatig bestelde servers:

Stap 7. De configuratie wijzigen

Wijzigingen vallen in drie categorieën:

  • Veilige wijzigingen. Tags en de power state worden toegepast op een draaiende server, en het plan toont deze als update in-place.

  • Herinstallatie van het besturingssysteem. Het wijzigen van os_name, soft_name, root_pass of ssh_key herinstalleert het besturingssysteem op dezelfde server, wat betekent dat alle gegevens op de schijf verloren gaan.

  • Een nieuwe bestelling. Het wijzigen van preset_name, location_name, traffic_plan_name of deploy_period betekent dat de vorige server wordt geannuleerd en een nieuwe wordt besteld, waardoor je opnieuw in rekening wordt gebracht. Het plan markeert dergelijke wijzigingen als forces replacement.

Let op

Wijzigingen die leiden tot een herinstallatie verschijnen in het plan als update in-place, precies zoals een onschuldige tag-wijziging. De provider print een aparte waarschuwing over gegevensverlies, dus voordat je bevestigt, is het de moeite waard om niet alleen het plan, maar ook de waarschuwingen te lezen.

Stap 8. De resources verwijderen

terraform destroy

terraform destroy verwijdert alle resources die in de huidige Terraform state voor deze configuratie staan. Terraform toont de lijst met te verwijderen resources en vraagt om bevestiging. Voer yes in en druk op Enter.

Als je slechts één resource wilt verwijderen, kun je deze specificeren met -target. Bijvoorbeeld:

terraform destroy -target=hostkey_server.web

Hier is web de naam van de resource uit het resource "hostkey_server" "web" blok, niet de server-ID uit het control panel.

Een andere optie is om de resource uit de .tf bestanden te verwijderen en het volgende uit te voeren:

terraform apply

Terraform ziet dat de resource niet langer aanwezig is in de configuratie en zal deze uit de infrastructuur verwijderen.

De annulering van de service wordt uitgevoerd via Invapi, en de methode van annulering wordt bepaald door de parameter cancellation_type: 1 annuleert de service onmiddellijk, terwijl 0 deze annuleert aan het einde van de betaalde periode.

Informatie

Bij onmiddellijke annulering (cancellation_type = 1) wordt het ongebruikte deel van de betaalde periode naar rato van de werkelijke tijd dat de service draaide, teruggeschreven naar het accountsaldo.

Bestaande servers importeren

Servers die via het control panel zijn besteld, kunnen onder Terraform-beheer worden gebracht. De identifier wordt overgenomen uit de ID kolom in de serverlijst:

terraform import hostkey_server.web 19463

Na de import bevat de state de live data, namelijk de identifier, het adres, de status en de power state. Argumenten die bij het bestellen zijn gebruikt, worden niet overgenomen van het control panel, dus deze moeten handmatig in de configuratie worden beschreven. De eerste terraform apply na een import leidt niet tot een herinstallatie.

Probleemoplossing

Opmerking

No appropriate servers found bij het uitvoeren van plan. Controleer of het account ten minste één service heeft, aangezien Invapi geen sessie aanmaakt voor een account zonder services.

Opmerking

Catalog name resolve failed. De opgegeven preset, het besturingssysteem of de naam van het verkeersplan is niet aanwezig in de catalogus voor de geselecteerde locatie. Gebruik de hostkey_presets en hostkey_traffic_plans data sources om de beschikbare waarden op te vragen en breng de configuratie in lijn met deze waarden.

Opmerking

State pending:<invoice>. De bestelling is betaald maar de implementatie is nog niet voltooid, meestal omdat de verbinding is verbroken. Het opnieuw uitvoeren van terraform apply hervat het wachten en plaatst geen nieuwe bestelling. Als de factuur nog niet is betaald, betaal deze dan en voer terraform apply opnieuw uit. De live status van de service wordt getoond in het control panel.

Informatie

Meer over Terraform zelf is te vinden in de officiële HashiCorp documentatie, en de specifieke argumenten van de resources en data sources zijn gedocumenteerd in de Terraform Registry.

question_mark
Is there anything I can help you with?
question_mark
AI Assistant ×