Meine ersten Schritte mit Terraform

In diesem Artikel ist die Vorgehensweise beschrieben wie man eine Terraform Umgebung für Tests auf- und wieder abbauen kann. Hierzu habe ich Microsoft Azure verwendet. Diese ist im Rahmen der dotnet user group Seite geschehen um so die Tests mit Browserstack auf einer virtuellen Umgebung durchführen zu können.

Vorausetzungen

Ziel

Das Ziel soll sein, dass eine Testumgebung bestehend aus folgenden Komponenten

  • SQL Server
  • App Service hochfährt, die automatisierten Tests durchläuft und danach gelöscht wird.

Vorgehensweise

Die nachfolgenden Schritte beschreiben die Vorgehensweise in 3 Schritten.

  • Identifizieren der benötigten Ressourcen
  • Identifizieren der Terraform Ressourcen
  • Zusammenführen

Identifizieren der Terraform Ressourcen

Wirf man ein Auge auf die Azure Automation, so sticht die sehr grosse JSON-Datei ins Auge. Sie kann als Anhaltspunkt verwendet werden, muss aber nicht. Schaut man sich das so an, dann sind das eine Menge an Ressourcen, die da Verwendung finden. Nun stellt Terraform unter folgendem Link, die aktuellen Ressourcen für Azure zur Verfügung. Folgende Ressourcen können dafür Verwendung finden:

Zusammenführen

Nun muss das Ganze in einer Terraform Datei zusammengeführt werden. Hierzu wird ein Ordner erstellt, zum Beispiel dotnet-usergroup-bern-terraform-configuration. In diesem Ordner ist dann eine main.tf Datei zu erstellen, die die ganze Terraform Konfiguration beinhaltet. Diese Datei sieht dann wie so aus:

# Configure the dotnet-user-group test environment

terraform{
    required_providers{
        azurerm = {
            source = "hashicorp/azurerm"
            version = ">=2.26"
        }
    }
}

provider "azurerm"{
    features{}
}

resources "azurerm_resource_group" "bddtest"{
    name = "bddtest-dotnet-usergroup"
    location = "switzerlandnorth"
}

// SQL configuration
resource "azurerm_storage_account" "bddtest"{
    name = "bdd-test-dotnet-usergroup"
    resource_group_name = azurerm_resource_group.bddtest.name
    location = azurerm_resource_group.bddtest.location
    account_tier = "Free"
    account_replication_type = "GRS"
}

resource "azurerm_sql_server" "bddtest" {
  name                         = "bddtest-sqlserver"
  resource_group_name          = azurerm_resource_group.bddtest.name
  location                     = azurerm_resource_group.bddtest.location
  version                      = "12.0"
  administrator_login          = "4dm1n157r470r"
  administrator_login_password = "4-v3ry-53cr37-p455w0rd"
}

resource "azurerm_mssql_database" "bddtest" {
  name           = "bddtest-dnugberndev"
  server_id      = azurerm_sql_server.bddtest.id
  collation      = "SQL_Latin1_General_CP1_CI_AS"
  license_type   = "LicenseIncluded"
  max_size_gb    = 4
  read_scale     = false
  sku_name       = "Basic"
  zone_redundant = false

  extended_auditing_policy {
    storage_endpoint                        = azurerm_storage_account.example.primary_blob_endpoint
    storage_account_access_key              = azurerm_storage_account.example.primary_access_key
    storage_account_access_key_is_secondary = true
    retention_in_days                       = 6
  }

// App Service configuration (Web Apps)
resource azurerm_app_service_plan "bddtest"{
    name = "bddtest-appserviceplan"
    location = azurerm_resource_group.bddtest.location
    resource_groupe_name = azurerm_resource_group.bddtest.name

    sku{
        tier = "Basic"
        size = "F1"
        name = "F1"
    }
}
 

Natürlich sind hier noch nich alle definitiven Werte eingetragen, sodass während der Build-Zeit diese Konfiguration erstellt wird. Diesen Punkt werde ich in Zukunft behandeln.

Erstellung der Ressourcen
Nun ist es an der Zeit, zu sehen ob die Konfiguration, die da entstanden ist, auch ohne Fehler angewendet werden kann.
Hierzu bin ich wie folgt vorgegangen:
1. Anmelden in Azure (Diese Methode habe ich gewählt, weil bei mir der Browser oder die Browser ein wenig gezickt haben.)

az login --use-device-code

Nach erfolgter Anmeldung, sind die Azure-Abos ersichtlich.

[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "YYYYYYYY",
    "id": "0000000-11111-2222-3333-555555555555",
    "isDefault": true,
    "managedByTenants": [],
    "name": "Pay-As-You-Go",
    "state": "Enabled",
    "tenantId": "ZZZZZZZ",
    "user": {
      "name": "hansmustter@windowslive.com",
      "type": "user"
    }
  },
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "XXXXXXX",
    "id": "0000000-11111-2222-3333-444444444444",
    "isDefault": false,
    "managedByTenants": [],
    "name": "Visual Studio Enterprise mit MSDN",
    "state": "Enabled",
    "tenantId": "XXXXXX",
    "user": {
      "name": "hansmuster@windowslive.com",
      "type": "user"
    }
  }
]

Nun, wenn man die Subscription wechseln will, muss man mit den Azure CLI-Werkzeugen folgenden Befehl ausführen:

az account list

[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "YYYYYYYY",
    "id": "0000000-11111-2222-3333-555555555555",
    "isDefault": false,
    "managedByTenants": [],
    "name": "Pay-As-You-Go",
    "state": "Enabled",
    "tenantId": "ZZZZZZZ",
    "user": {
      "name": "hansmustter@windowslive.com",
      "type": "user"
    }
  },
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "XXXXXXX",
    "id": "0000000-11111-2222-3333-444444444444",
    "isDefault": true,
    "managedByTenants": [],
    "name": "Visual Studio Enterprise mit MSDN",
    "state": "Enabled",
    "tenantId": "XXXXXX",
    "user": {
      "name": "hansmuster@windowslive.com",
      "type": "user"
    }
  }
]

das die Default Subscription geändert hat.

  1. Nun muss der Plan von Terraform initiiert werden.
.\terraform.exe plan -out .\myplan
terraform init
  1. Anschliessend muss
.\terraform.exe plan -out .\myplan

ausgeführt werden. Wobei der Out Parameter optional ist. Bei der Ausführung speichert Terraform mit diesem Parameter den Plan als Datei im aktuellen Verzeichnis oder in dem angegeben im out-Parameter, ab. Verlief alles nach Plan, so zeigt Terraform den Plan an. Die + Zeichen deuten darauf hin, dass diese Ressourcen erstellt werden. Der nachfolgende Plan ist der Übersicht halber symbolisch dargestellt. In Wirklichkeit ist dieser um einiges länger.

------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_app_service.bddtest will be created
  + resource "azurerm_app_service" "bddtest" {
      + app_service_plan_id            = (known after apply)
      + app_settings                   = {
          + "SOME_KEY" = "some-value"
        }
      + client_affinity_enabled        = false
      + client_cert_enabled            = false
      + default_site_hostname          = (known after apply)
      + enabled                        = true
      + https_only                     = false
      + id                             = (known after apply)
      + location                       = "switzerlandnorth"
      + name                           = "bddtest-dnug-bern"
      + outbound_ip_addresses          = (known after apply)
      + possible_outbound_ip_addresses = (known after apply)
      + resource_group_name            = "bddtest-dotnet-usergroup"
      + site_credential                = (known after apply)

      + auth_settings {
          + additional_login_params        = (known after apply)
          + allowed_external_redirect_urls = (known after apply)
          + default_provider               = (known after apply)
          + enabled                        = (known after apply)
          + issuer                         = (known after apply)
          + runtime_version                = (known after apply)
          + token_refresh_extension_hours  = (known after apply)
          + token_store_enabled            = (known after apply)
          + unauthenticated_client_action  = (known after apply)

          + active_directory {
              + allowed_audiences = (known after apply)
              + client_id         = (known after apply)
              + client_secret     = (sensitive value)
            }          
....

Plan: 7 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

This plan was saved to: .\MyPlan

To perform exactly these actions, run the following command to apply:
    terraform apply ".\\MyPlan"
  1. Nun wird der Plan mit
terraform apply

zur Ausführung gebracht.

  1. Eine kurze Rechenphase und der Plan der ausgeführt werden wird, wird angezeigt. Die Bestätigung mit „Yes“ lässt Terraform nun seine Arbeit verrichten.
terraform apply
  1. Sobald die Bestätigung mit „YES“ erfolgte, schreitet Terraform zur Tat. Die Fortschritte sind dann wie folgt:
terraform progress indikator
  1. Wenn alles richtig gemacht worden ist, dann zeigt Terraform den Status der Operation an.
terraform status

Hier noch die erstellten Ressourcen im Azure Portal.

azure ressourcen nach der terraform applizierung

Löschen der erstellten Ressourcen

Der Aufbau einer Umgebung ist das Eine. Das Abbauen das Andere. In der Dotnet User Group Bern, sollt diese Umgebung für die BDD (Behavior Driven Tests) hochgefahren und dann wieder abgebaut werden. Der Abbau geht dann wie nachfolgend beschrieben, sehr schnell.

  1. Mit dem Befehl
terraform.exe destroy

werden die Ressourcen dann abgebaut.

2. Nach einer kurzen Verarbeitungszeit auf dem ausführenden Client sieht man dann Ausführungsplan des oben bereits dargestellten Ausführungsplanes. Der Unterschied hier, bei jeder Resource ist nun ein vorangestellt, dass angibt das die Ressource gelöscht werden wird. Auch hier muss mit YES die Aktion bestätigt werden.

3. Sind alle Aktionen erfolgreich verlaufen so teilt terraform mit, dass die Ressourcen zerstört sind.

terraform destory

Auch im Azure Portal sind die Ressourcen nicht mehr zu finden.

azure nach dem abbau durch terraform destroy

Fazit

Mit Terrform ist es relativ einfach eine automatisierte Infrastruktur zu instantiieren und so den Prozess der Bereitstellung zu Beschleunigen. Wenn Dir dieser Artiekl gefallen hat, dann würde ich mich über ein Like freuen und nehme gerne Verbesserungsvorschläge an. Meine Reise mit Terraform ist noch nicht zu Ende und das hier gezeigt, einfache Beispiel, kann noch weiter verbessert werden. Weiter will ich zudem die Möglichkeiten erkunden, diese Lösung auch onPremise einzusetzen, da nicht in jeder Umgebung die Cloud als definierte Zielplattform gewünscht ist.

Weiterführende Links

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google Foto

Du kommentierst mit Deinem Google-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s