In diesem Artikel gehe ich darauf ein, wie man die Ressourcen mit Terraform in Azure in einer Kadenz von 5 Minuten provisionieren und wieder abbauen kann. Dieses Szenario kann durchaus bei BDD-Test vorkommen, bei deinen Ad-Hoc eine Testinfrastruktur hochgefahren werden muss.
Vorausetzungen
- Azure Account.
- Terraform ist installiert.
Ausgangslage
Währen der Provisionierung in der Pipeline, kann es immer wieder vokommen, dass bereits eine Ressource noch vorhanden sei, wenn diese rasch wieder erstellt werden muss. Dann sieht man folgende Fehlermeldung:
│ Error: waiting for creation/update of Server: (Name "sqldbserver" / Resource Group "rg-switzerland"): Code="NameAlreadyExists" Message="The name 'sqldbserver.database.windows.net' already exists. Choose a different name."
│
│ with azurerm_mssql_server.sqlsrv,
│ on main.tf line 52, in resource "azurerm_mssql_server" "sqlsrv":
│ 52: resource "azurerm_mssql_server" "sqlsrv" {
Ärgerlich, wenn man sich darauf verlassen möchte, dass die Test-Umgebung immer gleich aufgebaut werden soll.
Die Lösung
Um diesem Problem Herr zu werden, reicht es wenn man den Ressourcen einen zufälligen Namenszusatz vergibt. Dies kann mit dem Terraform Integer eine einfache Abhilfe geschaffen werden. Dazu braucht es im Terraform Script nur folgende Ressource:
resource "random_integer" "salt"{
min = 1
max = 99
}
Der Umstand, dass Zahlen zwischen 1 und 99 generiert werden, in einer Zufälligkeit, lässt die Wahrscheinlichkeit, dass eine Ressource bereits besteht und des zu einem Fehler kommt, minimieren.
Das Anlegen einer Ressource-Gruppe mit zufälligem Namenssuffix würde dann wie folgt aussehen.
# Create a resource group
resource "azurerm_resource_group" "rg" {
name = "rg-swiss-${random_integer.salt.result}"
location = "switzerlandnorth"
}
Mit einem Testscript dass fünf mal durchläuft mit einer realistischen Pause von 5min während den Ausführungen hat keinen Fehler ausgegeben.
$totalseconds = 0;
$stopwatch = New-Object -TypeName System.Diagnostics.Stopwatch
for ($index = 0; $index -lt 5; $index++) {
$stopwatch.Reset()
$stopwatch.Start()
$executable = "terraform.exe"
$initargument = "init"
$plangargument = "plan -out testplan"
$applyargument = "apply -auto-approve testplan"
$destroyargeument = "destroy -auto-approve"
Start-Process $executable -ArgumentList $initargument -Wait -NoNewWindow
Start-Process $executable -ArgumentList $plangargument -Wait -NoNewWindow
Start-Process $executable -ArgumentList $applyargument -Wait -NoNewWindow
Start-Process $executable -ArgumentList $destroyargeument -Wait -NoNewWindow
$stopwatch.Stop()
$totalseconds += $stopwatch.Elapsed.TotalSeconds
Start-Sleep -Seconds 480
}
Write-Host "Verstrichene Zeit $totalseconds"
Natürlich kann die Dauer mit der aktuellen Verfügbarkeit von Azure Dienste zusammenhängen. Bei der Vergabe der Namen für die Ressourcen ist es immer ratsam die Azure API der einzelnen Ressourcen zu konsultieren um keinen Fehler in der Länge des Namens zu generieren. Denn im Gegensatz zu früher, wo Namen noch wichtig waren, sind es heute nur noch Ressourcen, die nicht mehr für eine lange Existenz bestimmt sind, in Zeiten von DevOps Praktiken.
Fazit
Mit dieser Lösung kann sichergestellt werden, dass man sich Umgehungslösungen baut, die dann nur einen kleinen Zeitraum funktionieren. Ich hoffe der Artikel hat gefallen.