Mit Terraform Infrastruktur bei gridscale definieren und ausrollen

Wie du mit Terraform und gridscale eine einfache Infrastruktur bereitstellst

gridscale unterstützt Infrastructure as Code (IaC). Über unseren Terraform-Provider kannst du deine benötigten Cloud-Ressourcen in einfachen, maschinenlesbaren Code definieren. 

Die Beispiele geben dir einen ersten Einblick in Terraform und IaC.

Hilfreiche Links zu weiteren Informationen:

Zwei weitere Tutorials helfen dir bei der Einrichtung von Terraform:

Für einen umfassenden Überblick sind weiterhin folgende Links hilfreich:

Am Ende dieses Tutorials kannst du folgende Infrastruktur über Terraform bereitstellen: 

  • VM 1, OS: Rocky Linux mit Public IP und SSH-Key
  • VM 2, OS: Ubuntu (24.04) mit root-Passwort
  • Internes Netzwerk mit einer benutzerdefinierten Größe: VM 1 und VM 2 werden daran angebunden
  • PaaS gridSQL (MariaDB): ebenfalls im selben, internen Netzwerk

Zur Einrichtung benötigst du zunächst einen Server. In dieser Beispielkonfiguration wird eine VM (Alma Linux 9) bei gridscale verwendet und Terraform dort eingerichtet. Es soll ein dedizierter User myuser genutzt werden, der Terraform ausführen darf.

1. Installation Terraform

$ sudo yum install yum-utils -y
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

Nachdem die benötigten Repos eingebunden sind, prüfe die Version und ob die Pakete gefunden werden:

$ yum info terraform

Last metadata expiration check: 0:00:52 ago on Thu 13 Feb 2025 08:52:21 AM CET.
Available Packages
Name: terraform
Version: 1.10.5
Release: 1
Architecture: x86_64
Size: 27 M
Source: terraform-1.10.5-1.src.rpm
Repository: hashicorp

Danach wird die Installation gestartet.

$ sudo yum install terraform -y

Überprüfe jetzt noch die Ausgabe auf der Kommandozeile und ob alles wie erwartet funktioniert:

$ terraform version

Terraform v1.10.5
on linux_amd64

An diesem Punkt ist Terraform auf dem Server installiert, nun kann es mit der Einrichtung weitergehen.

Im Verzeichnis befindet sich nun der Ordner .terraform.d. Wechsle in diesen Unterordner, um die nächsten Schritte durchzuführen.

$ ls -al | grep terraform

drwxr-xr-x. 2 myuser myuser 4096 Feb 13 08:54 .terraform.d
$ cd .terraform.d/

2. API Token

Du benötigst einen API-Token mit schreibenden Rechten. Diesen erstellst du im Cloud-Panel im Kontext deines Benutzerprofils.

3. Einrichtung Terraform

Erstelle zunächst eine Datei namens provider.tf. In dieser wird der zuvor erstellte API-Key in folgenden Format eingebunden:

Provider "gridscale" {
               uuid = "deine uuid"
               token = "dein Token"
}

Erstelle eine Datei mit dem Namen server.tf und füge Folgendes ein:

terraform {
  required_providers {
    gridscale = {
      source = "gridscale/gridscale"
    }
  }
}

Im Anschluss initialisierst du Terraform:

$ terraform init

Initializing the backend...
Initializing provider plugins...
- Finding latest version of gridscale/gridscale...
- Installing gridscale/gridscale v2.1.0...
- Installed gridscale/gridscale v2.1.0 (self-signed, key ID 0159FE074E77BC96)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
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.
$ terraform plan

No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes
are needed.

Bisher hast du keine Komponenten definiert, teste daher mit einer Ressouce. Füge die resource der Konfiguration des Demoservers hinzu. Deine server.tf-Datei sollte danach so aussehen:

$ cat server.tf

terraform {
  required_providers {
    gridscale = {
      source = "gridscale/gridscale"
    }
  }
}

resource "gridscale_server" "demo" {
  name   = "demo"
  cores  = 1
  memory = 2
  power  = true
}

Lasse dir jetzt anzeigen, was umgesetzt werden soll:

$ terraform plan

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:
  # gridscale_server.demo will be created
  + resource "gridscale_server" "demo" {
      + auto_recovery           = (known after apply)
      + availability_zone       = (known after apply)
      + change_time             = (known after apply)
      + console_token           = (known after apply)
      + cores                   = 1
      + create_time             = (known after apply)
      + current_price           = (known after apply)
      + hardware_profile        = (known after apply)
      + id                      = (known after apply)
      + legacy                  = (known after apply)
      + location_uuid           = (known after apply)
      + memory                  = 2
      + name                    = "demo"
      + power                   = true
      + status                  = (known after apply)
      + usage_in_minutes_cores  = (known after apply)
      + usage_in_minutes_memory = (known after apply)
      + user_data_base64        = (known after apply)
      + hardware_profile_config (known after apply)
    }
Plan: 1 to add, 0 to change, 0 to destroy.
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions
if you run "terraform apply" now.

Mittels terraform apply wird der Plan umgesetzt und der Server erstellt. Nach erfolgreichem Durchlauf siehst du den Server in deinem gridscale Panel.

ℹ️ Information
Im Standard wirst du aufgefordert, den Befehl mit yes zu bestätigen. Danach beginnt die Bereitstellung. Um dies zu überspringen, füge auto-approve an den Befehl an. Nun startet Terraform ohne eine weitere Abfrage zur Bestätigung:

$ terraform apply -auto-approve

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:
  # gridscale_server.demo will be created
  + resource "gridscale_server" "demo" {
      + auto_recovery           = (known after apply)
      + availability_zone       = (known after apply)
      + change_time             = (known after apply)
      + console_token           = (known after apply)
      + cores                   = 1
      + create_time             = (known after apply)
      + current_price           = (known after apply)
      + hardware_profile        = (known after apply)
      + id                      = (known after apply)
      + legacy                  = (known after apply)
      + location_uuid           = (known after apply)
      + memory                  = 2
      + name                    = "demo"
      + power                   = true
      + status                  = (known after apply)
      + usage_in_minutes_cores  = (known after apply)
      + usage_in_minutes_memory = (known after apply)
      + user_data_base64        = (known after apply)
      + hardware_profile_config (known after apply)
    }
Plan: 1 to add, 0 to change, 0 to destroy.
gridscale_server.demo: Creating...
gridscale_server.demo: Still creating... [10s elapsed]
gridscale_server.demo: Still creating... [20s elapsed]
gridscale_server.demo: Creation complete after 27s [id=2e657977-9546-47f3-9e0f-0fb366a3dc70]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Ein Blick in das entsprechende Projekt zeigt dir nun den zuvor definierten Server im Cloud-Panel:

Terraform Panel

Terraform ist nun lauffähig und dein Setup erfolgreich getestet. Bevor du nun einen kompletten Server inklusive Storage und Netzwerk erstellst, lösche den Server wieder mit terraform destroy.

4. VM 1 mit Rocky Linux

Zu Beginn wurde eine Infrastruktur mit mehreren Einzelkomponenten definiert.

Erstelle nun den ersten Server, damit alle notwendigen Bestandteile erfasst sind. Es empfiehlt sich, Schritt für Schritt vorzugehen und den Code zwischenzeitlich zu prüfen. Syntaxfehler o. Ä. fallen so zeitnah auf und können leichter korrigiert werden. 

Du benötigst zunächst Informationen, die außerhalb von Terraform selber definiert wurden. Da wir das gridscale-Template für Rocky Linux nutzen, geben wir dies entsprechend als Data Source data in unserer Konfigurationsdatei an. Auch die Informationen zu Netzwerken und deinem SSH-Key sind bei gridscale hinterlegt. 

Die IDs sind im Panel aufrufbar und können via API oder bequem mit unserem Kommandozeilen-Tool gscloud abgefragt werden.

ℹ️ Weitere Informationen
Hier findest du weitere Informationen zur Nutzung unseres Kommandozeilentools. →

Die UUID deines SSH-Keys findest du im Panel unter Benutzereinstellungen → SSH-Keys → Infos.

Trage über diese Kanäle nun die Informationen zusammen und schreibe diese in die server.tf-Datei. 

Zum Schluss benötigst du noch Resource-Blöcke. Diese beschreiben die jeweiligen Infrastruktur-Objekte.

In eine Liste zusammengefasst soll deine erste VM bestehen aus:

  • gridscale-Template Rocky Linux
  • SSH Key (hinterlegt im Cloud-Panel)
  • gridscale-FW-Template Admin Server
  • Storage: 10GB, Performance-Klasse: High
  • Hostname rockyserver
  • 1 Core, 2 GB RAM
  • Öffentliche IPv4, keine IPv6
  • Internes Netzwerk: Custom Range

Innerhalb der server.tf sollte das Setup so beschrieben sein:

$ cat server.tf

terraform {
  required_providers {
    gridscale = {
      source = "gridscale/gridscale"
    }
  }
}

# Terraform Data

data "gridscale_template" "rock-template" {
    name = "Rocky Linux"
}
data "gridscale_sshkey" "sshkey-user"{
  resource_id = "my-sshkey-uuid"
}
data "gridscale_public_network" "pubnet"{
}

# Network

resource "gridscale_network" "internal-net"{
  name = "intern-terraform-network"
  dhcp_active = true
  dhcp_range = "192.168.1.0/26"
  timeouts {
      create="10m"
  }
}
resource "gridscale_ipv4" "ipv4" {
  name = "ipv4rocky"
  timeouts {
      create="10m"
  }
}

# Server 1

resource "gridscale_storage" "rocky-storage" {
  name = "Rocky Linux Storage"
  capacity = 10
  storage_type = "storage_high"
  template {
    template_uuid = data.gridscale_template.rock-template.id
    hostname = "rockyserver"
    sshkeys = [data.gridscale_sshkey.sshkey-user.id]
  }
  timeouts {
    create="10m"
  }
}
resource "gridscale_server" "rocky-server" {
  name   = "Rocky Linux Server"
  cores  = 1
  memory = 2
  power  = false
  storage {
    object_uuid = gridscale_storage.rocky-storage.id
  }
  network {
    object_uuid = gridscale_network.internal-net.id
  }
  network {
    object_uuid = data.gridscale_public_network.pubnet.id
    firewall_template_uuid = "3b9d003b-2d05-4a0f-9af2-5c175ade35a4"
  }
  ipv4 = gridscale_ipv4.ipv4.id
}

Du hast nun einen vollwertigen Server erstellt. Um deine Infrastruktur weiter auszubauen, füge einen weiteren Server und eine MySQL-Instanz als PaaS hinzu.

5. Datenbank und zweiten Server hinzufügen

Nutze für die Datenbank den von gridscale zur Verfügung gestellten PaaS MySQL in der Version 8. 

Eine gridSQL ist per Definition in einem privaten Netzwerk. Da du bereits bei Server1 ein internes Netz eingerichtet hast, kannst du dieses auch hier verwenden. 

Lege außerdem eine Obergrenze für die Anzahl der Kerne fest. Ohne diese Angabe würde die Datenbank automatisch bis 32 Kerne skalieren (mehr dazu auch in unserer Product Documentation).

Füge den zweiten Server hinzu:

  • Ubuntu 24.04 LTS 
  • Boot-Storage: 10 GB, Performance: Default
  • Zweiter Storage für Daten (Rocket Storage) mit 30 GB
  • Integration in das bestehende, interne Netzwerk
  • Hostname ubuntuserver
  • Root-Passwort gesetzt (kein SSH-Key)

Damit sollte die server.tf jetzt wie folgt aussehen:

$ cat server.tf

terraform {
  required_providers {
    gridscale = {
      source = "gridscale/gridscale"
    }
  }
}

# Terraform Data

data "gridscale_template" "rock-template" {
    name = "Rocky Linux"
}
data "gridscale_sshkey" "sshkey-user"{
  resource_id = "my-sshkey-uuid"
}
data "gridscale_public_network" "pubnet"{
}
data "gridscale_template" "ubu-template" {
    name = "Ubuntu 24.04 LTS"
}

# Network

resource "gridscale_network" "internal-net"{
  name = "intern-terraform-network"
  dhcp_active = true
  dhcp_range = "192.168.1.0/26"
  timeouts {
      create="10m"
  }
}
resource "gridscale_ipv4" "ipv4" {
  name = "ipv4rocky"
  timeouts {
      create="10m"
  }
}

# Server 1

resource "gridscale_storage" "rocky-storage" {
  name = "Rocky Linux Storage"
  capacity = 10
  storage_type = "storage_high"
  template {
    template_uuid = data.gridscale_template.rock-template.id
    hostname = "rockyserver"
    sshkeys = [data.gridscale_sshkey.sshkey-user.id]
  }
  timeouts {
    create="10m"
  }
}
resource "gridscale_server" "rocky-server" {
  name   = "Rocky Linux Server"
  cores  = 1
  memory = 2
  power  = false
  storage {
    object_uuid = gridscale_storage.rocky-storage.id
  }
  network {
    object_uuid = gridscale_network.internal-net.id
  }
  network {
    object_uuid = data.gridscale_public_network.pubnet.id
    firewall_template_uuid = "3b9d003b-2d05-4a0f-9af2-5c175ade35a4"
  }
  ipv4 = gridscale_ipv4.ipv4.id
}

# MySQL PaaS

resource "gridscale_mysql8_0" "terra-mysql-test" {
  name = "my mysql"
  network_uuid = gridscale_network.internal-net.id
    release = "8.0"
    performance_class = "insane"
  max_core_count = 20
    mysql_default_time_zone = "Europe/Berlin"
}

# Server 2

resource "gridscale_storage" "server2-storage" {
  name = "Ubuntu Boot Storage"
  capacity = 10
  storage_type = "storage"
  template {
    template_uuid = data.gridscale_template.ubu-template.id
    hostname = "ubuntuserver"
    password = "myplainpw"
    password_type = "plain"
  }
  timeouts {
    create="10m"
  }
}
resource "gridscale_storage" "local-data" {
  name = "Ubuntu local Storage (Data) "
  capacity = 30
  storage_variant = "local"
  timeouts {
    create="10m"
  }
}
resource "gridscale_server" "ubu-server" {
  name   = "Ubuntu Linux Server"
  cores  = 1
  memory = 2
  power  = false
  storage {
    object_uuid = gridscale_storage.server2-storage.id
  }
  storage {
    object_uuid = gridscale_storage.local-data.id
  }
  network {
    object_uuid = gridscale_network.internal-net.id
  }
}

ℹ️ UUID ersetzen
Möchtest du diese Vorlage übernehmen, ersetzte die UUID des SSH-Keys mit deiner eigenen.

Damit ist die Erstellung deines ersten Terraform-Setups abgeschlossen.