Hoe deploy je meerdere omgevingen in uw Terraform project zonder code dupliceren

De auteur heeft de Free and Open Source Fund gekozen om een donatie te ontvangen als onderdeel van het Write for DOnations-programma.

Inleiding

Terraform biedt geavanceerde functionaliteiten die steeds handiger worden als uw project in grootte en complexiteit toeneemt. Het is mogelijk de kosten van het onderhoud van complexe infrastructurele definities voor meerdere omgevingen te verminderen door uw code te structuren om reproducties te minimaliseren en tool-geassisteerde werkstromen in te voeren voor gemakkelijke testen en deployments.

Terraform associeert een state met een backend, die bepaalt waar en hoe de state wordt opgeslagen en opgehaald. Elke state heeft maar één backend en is verbonden met een infrastructuurconfiguratie. Bepaalde backends, zoals local of s3, kunnen meerdere states bevatten. In dat geval wordt de paaring van state en infrastructuur aan de backend een workspace beschrijven. Workspaces laten u meerdere unieke instanties van dezelfde infrastructuurconfiguratie uitvoeren zonder ze in aparte backends op te slaan.

In deze handleiding zult u eerst meerdere infrastructuurinstanties uitvoeren door middel van verschillende werkruimten. Vervolgens zult u een stateful resource implementeren, die in deze handleiding een DigitalOcean Volume zal zijn. U zult tenslotte verwijzen naar vooraf gemaakte modules uit het Terraform Register, die u kunt gebruiken om uw eigen aan te vullen.

Vereisten

Om deze handleiding te voltooien, heb je nodig:

  • Een persoonlijke toegangstoken voor DigitalOcean, die u kunt maken via het DigitalOcean Control Panel. U kunt de instructies vinden in de DigitalOcean productdocumenten, Hoe een persoonlijke toegangstoken aan te maken.
  • Terraform geïnstalleerd op uw lokale machine en een project opgericht met de DO provider. Voltooi Stap 1 en Stap 2 van de handleiding Hoe Terraform gebruiken met DigitalOcean en zorg ervoor dat de projectmap terraform-advanced heet in plaats van loadbalance. Tijdens Stap 2 neemt u de variabele pvt_key en de SSH-sleutelbron niet mee.

Opmerking: Deze handleiding is specifiek getest met Terraform 1.0.2.

Meerdere infrastructuurinstanties deployeren met werkruimten

Meerdere werkruimten zijn handig als u een aangepaste versie van uw hoofdinfrastructuur wilt deployen of testen zonder een apart project aan te maken en opnieuw authentication keys in te stellen. Zodra u een functie heeft ontwikkeld en getest met de aparte status, kunt u de nieuwe code integreren in de hoofdwerkruimte en misschien de extra status verwijderen. Wanneer u een Terraform-project init-t, ongeacht de backend, maakt Terraform een werkruimte genaamd default. Het is altijd aanwezig en u kunt het nooit verwijderen.

Hoewel meerdere werkruimten echter geen geschikte oplossing zijn voor het maken van meerdere omgevingen, zoals voor staging en productie, slaat workspaces, die alleen de status volgen, de code of zijn aanpassingen niet op.

Omdat werkruimtes de daadwerkelijke code niet volgen, moet je de coder scheiding tussen meerdere werkruimtes beheren op het niveau van de versiebeheer (VCS) door ze te koppelen aan hun infrastructuurvarianten. Hoe je dit kunt bereiken, hangt af van de VCS-tool zelf; bijvoorbeeld, in Git-branches zou een passende abstractie zijn. Om het beheren van de code voor meerdere omgevingen te vergemakkelijken, kun je ze opbreken in herbruikbare modules, zodat je vermeidt dat je vergelijkbare code herhaald voor elke omgeving.

Resources in Workspaces Implementeren

Je gaat nu een project maken dat een Droplet implementeert, die je vanuit meerdere werkruimtes gaat toepassen.

Je bewaart de Droplet-definitie in een bestand genaamd droplets.tf.

Er van uitgaande dat je in de directory terraform-advanced bent, maak en open het voor bewerking door het volgende uit te voeren:

  1. nano droplets.tf

Voeg de volgende regels toe:

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-18-04-x64"
  name   = "web-${terraform.workspace}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

Deze definitie zal een Droplet maken die Ubuntu 18.04 draait met één CPU-kern en 1 GB RAM in de fra1-regio. De naam zal de naam van de huidige werkruimte bevatten waaruit het wordt geïmplementeerd. Zodra je klaar bent, bewaar en sluit het bestand.

Apply het project voor Terraform om zijn acties uit te voeren met:

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

De uitvoer zal ongeveer zo uitzielen:

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.web zal worden gecreëerd + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-default" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ...

Typ yes wanneer je wordt gevraagd om de Droplet te déploynen in de default werkruimte.

De naam van de Droplet zal web-default zijn, omdat de werkruimte waarmee je begint default heet. Je kunt de werkruimtes weergeven om te bevestigen dat het de enige beschikbare is:

  1. terraform workspace list

De uitvoer zal ongeveer zo uitzielen:

Output
* default

De asterisk (*) betekent dat je momenteel die werkruimte hebt geselecteerd.

Maak en schakel over naar een nieuwe werkruimte genaamd testing, die je zal gebruiken om een andere Droplet te déployn, door workspace new uit te voeren:

  1. terraform workspace new testing

De uitvoer zal ongeveer zo uitzielen:

Output
Created and switched to workspace "testing"! You're now on a new, empty workspace. Workspaces isolate their state, so if you run "terraform plan" Terraform will not see any existing state for this configuration.

Je plant opnieuw de部署 van de Droplet door het volgende uit te voeren:

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

De uitvoer zal vergelijkbaar zijn met de vorige run:

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.web zal worden gecreëerd + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-testing" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ...

Merk op dat Terraform van plan is om een Droplet genaamd web-testing te déployn, wat anders is genaamd dan web-default. Dit komt omdat de default en testing werkruimtes afzonderlijke staten hebben en geen kennis hebben van elkaars bronnen — zelfs al stammen ze uit dezelfde code.

Om te bevestigen dat je in de testing werkruimte bent, geef je de huidige werkruimte weer met workspace show:

  1. terraform workspace show

De uitvoer zal de naam van de huidige werkruimte zijn:

Output
testing

Om een werkruimte te verwijderen, moet je eerst alle geïmporteerde bronnen ervan vernietigen. Vervolgens, als het actief is, moet je overschakelen naar een andere met behulp van workspace select. Aangezien de testing-werkruimte hier leeg is, kun je direct overschakelen naar default:

  1. terraform workspace select default

Je ontvangt de output van Terraform die het omschakelen bevestigt:

Output
Switched to workspace "default".

Je kunt het vervolgens verwijderen door workspace delete uit te voeren:

  1. terraform workspace delete testing

Terraform voert vervolgens de verwijdering uit:

Output
Deleted workspace "testing"!

Je kunt de Droplet die je hebt geïmporteerd in de default-werkruimte verwijderen door het volgende uit te voeren:

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

Typ yes wanneer je wordt gevraagd om het proces te voltooien.

In dit gedeelte heb je gewerkt in meerdere Terraform-werkruimtes. In het volgende gedeelte ga je een stateful bron implementeren.

Implementeren van Stateful Bronnen

Stateless bronnen slaan geen gegevens op, dus je kunt deze snel maken en vervangen, omdat ze niet uniek zijn. Stateful bronnen daarentegen bevatten gegevens die uniek zijn of niet eenvoudig opnieuw kunnen worden gemaakt; daarom vereisen ze aanhoudende gegevensopslag.

Aangezien je zulke bronnen mogelijk moet verwijderen, of meerdere bronnen dezelfde gegevens vereisen, is het beste om deze op te slaan in een aparte entiteit, zoals DigitalOcean Volumes.

Volumina bieden extra opslagruimte. Ze kunnen worden gekoppeld aan Droplets (servers), maar zijn ervan gescheiden. In deze stap definieer je het Volume en koppel je het aan een Droplet in droplets.tf.

Open het voor bewerking:

  1. nano droplets.tf

Voeg de volgende regels toe:

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-18-04-x64"
  name   = "web-${terraform.workspace}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

resource "digitalocean_volume" "volume" {
  region                  = "fra1"
  name                    = "new-volume"
  size                    = 10
  initial_filesystem_type = "ext4"
  description             = "New Volume for Droplet"
}

resource "digitalocean_volume_attachment" "volume_attachment" {
  droplet_id = digitalocean_droplet.web.id
  volume_id  = digitalocean_volume.volume.id
}

Hier definieer je twee nieuwe bronnen, het Volume zelf en een Volume-attachment. Het Volume zal 10GB zijn, geformatteerd als ext4, genaamd new-volume en zich in dezelfde regio bevinden als de Droplet. Aangezien het Volume en de Droplet aparte entiteiten zijn, moet je een Volume-attachment object definiëren om ze te koppelen. volume_attachment neemt de Droplet- en Volume-ID’s en instructeert de DigitalOcean-cloud om het Volume beschikbaar te maken voor de Droplet als een schijfapparaat.

Wanneer je klaar bent, sla dan het bestand op en sluit het.

Plan deze configuratie door het volgende uit te voeren:

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

De acties die Terraform zal plannen, zijn de volgende:

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.web zal worden gecreëerd + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-default" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } # digitalocean_volume.volume zal worden gecreëerd + resource "digitalocean_volume" "volume" { + description = "New Volume for Droplet" + droplet_ids = (known after apply) + filesystem_label = (known after apply) + filesystem_type = (known after apply) + id = (known after apply) + initial_filesystem_type = "ext4" + name = "new-volume" + region = "fra1" + size = 10 + urn = (known after apply) } # digitalocean_volume_attachment.volume_attachment zal worden gecreëerd + resource "digitalocean_volume_attachment" "volume_attachment" { + droplet_id = (known after apply) + id = (known after apply) + volume_id = (known after apply) } Plan: 3 to add, 0 to change, 0 to destroy. ...

De uitvoerdetails geven aan dat Terraform een Droplet, een Volume en een Volume-attachment zal maken, die het Volume met de Droplet koppelt.

Je hebt nu een Volume (een stateful resource) gedefinieerd en gekoppeld aan een Droplet. In het volgende gedeelte ga je door voorbeelden van openbare, voorbereide Terraform-modules die je kunt opnemen in je project.

Referentie naar voorgedefinieerde modules

Naast het maken van uw eigen aangepaste modules voor uw projecten, kunt u ook voorgedefinieerde modules en providers van andere ontwikkelaars gebruiken, die openbaar beschikbaar zijn op Terraform Register.

In de modules sectie kunt u de database met beschikbare modules doorzoeken en sorteerbaar maken op provider om de module te vinden met de functionaliteit die u nodig heeft. Eens u een heeft gevonden, kunt u de omschrijving lezen, die de invoer- en uitvoergegevens van de module op lijst biedt, evenals haar afhankelijkheden van externe modules en providers.

U zult nu de DigitalOcean SSH-sleutelmodule aan uw project toevoegen. U zal de code van de bestaande definities afscheiden in een bestand dat ssh-key.tf heet. Maak er een en open het voor bewerking door het uit te voeren:

  1. nano ssh-key.tf

Voeg de volgende regels toe:

module "ssh-key" {
  source         = "clouddrove/ssh-key/digitalocean"
  key_path       = "~/.ssh/id_rsa.pub"
  key_name       = "new-ssh-key"
  enable_ssh_key = true
}

Dit code definieert een instantie van de module clouddrove/droplet/digitalocean uit het register en stelt enkele van de aangeboden parameters in. Het zou een publieke SSH-sleutel moeten toevoegen aan je account door deze te lezen vanuit ~/.ssh/id_rsa.pub.

Wanneer je klaar bent, bewaar en sluit het bestand.

Voordat je deze code plan maakt, moet je de gerefereerde module downloaden door het volgende uit te voeren:

  1. terraform init

Je zult een uitvoer krijgen die vergelijkbaar is met het volgende:

Output
Initializing modules... Downloading clouddrove/ssh-key/digitalocean 0.13.0 for ssh-key... - ssh-key in .terraform/modules/ssh-key Initializing the backend... Initializing provider plugins... - Reusing previous version of digitalocean/digitalocean from the dependency lock file - Using previously-installed digitalocean/digitalocean v2.10.1 Terraform has been successfully initialized! ...

Je kunt nu de code plannen voor de wijzigingen:

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

Je zult een uitvoer krijgen die vergelijkbaar is met 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: ... # module.ssh-key.digitalocean_ssh_key.default[0] zal worden gemaakt + resource "digitalocean_ssh_key" "default" { + fingerprint = (known after apply) + id = (known after apply) + name = "devops" + public_key = "ssh-rsa ... demo@clouddrove" } Plan: 4 to add, 0 to change, 0 to destroy. ...

De uitvoer toont dat je de SSH-sleutelbron zou maken, wat betekent dat je de module hebt gedownload en aangeroepen vanuit je code.

Conclusie

Grotere projecten kunnen gebruik maken van enkele geavanceerde functies die Terraform biedt om complexiteit te verminderen en onderhoud gemakkelijker te maken. Workspaces stellen je in staat nieuwe toevoegingen aan je code te testen zonder de stabiele hoofdinstallaties aan te raken. Je kunt workspaces ook koppelen aan een versiebeheersysteem om codewijzigingen bij te houden. Het gebruik van voorbereide modules kan de ontwikkeltijd ook verkorten, maar kan in het toekomst extra kosten of tijd met zich meebrengen als de module verouderd raakt.

Deze handleiding is onderdeel van de Hoe Toeleggen op Infrastructuur met Terraform reeks. De reeks beslaat verschillende 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-deploy-multiple-environments-with-workspaces-in-your-terraform-project