En head-to-head sammenligning af Azure Terrafy & Terraformer

Du er under tidspres. Du ved, at du kun er et par klik væk fra at være færdig i Azure-portalen. Let nok. Et par uger senere bliver du bedt om at genskabe ressourcerne med de samme konfigurationer. Ikke så let alligevel... Eller er det?

Claes Rytlig
Software Engineer

Hos cVation har vi længe udnyttet "Infrastructure as Code" (IaC) til at provisionere ressourcer til Azure. Faktisk er det den eneste måde, vi opretter Azure-ressourcer på. Det er dog ikke uhørt, at nogen har lavet det, der kan klassificeres som "Portal Driven Development", hvilket betyder, at en eller flere Azure-ressourcer er blevet oprettet ved hjælp af Azure Portalen.


Infrastruktur som kode (IaC)

Der er flere tilgængelige værktøjer, når man beslutter sig for at udnytte IaC. Et af de mest populære er "Terraform", som er udviklet og vedligeholdt af HashiCorp. Gennem årene har mange tredjepartsudviklere udvidet mulighederne for, hvad der kan gøres indbygget ved hjælp af Terraform. I dette blogindlæg tester vi to værktøjer, der giver ekstra muligheder for hvad og hvordan Terraform kan anvendes. De to værktøjer er henholdsvis "Azure Terrafy" og "Terraformer".

Målet med begge værktøjer er enkelt: Konverter eksisterende infrastruktur til Terraform-kode.

Opsætningen i Azure

Til testene har jeg oprettet to ressourcegrupper, der indeholder nogle få ressourcer. Ressourcegruppe 1 indeholder følgende:

Ressourcegruppe 2 indeholder følgende:

Begge ressourcegrupper har kun få ressourcer for at det er let at forstå, hvad der importeres. Nogle af ressourcerne har dog flere lag af konfiguration. For eksempel har ‘app service’ (tf-demo2-app) ressourcen’ et Nginx Docker-billede konfigureret- som vist herunder.

Indholdet på websiden er ligegyldigt, men konfigurationen, ’hosting an image’ i Terraform vigtig, hvis vi ønsker at tage eksisterende infrastruktur og lykkes med at genprovisionere den.

Azure Terrafy 👻

Det første værktøj i rækken er Azure Terrafy (aztfy). Det er ret ligetil at bruge. Kør først den binære fil ‘aztfy’ i et tomt drev, og fortæl den derefter, hvilken Azure-ressourcegruppe, der skal bruges som kilde. Bagefter er et funktionelt sæt Terraform-konfigurationsfiler tilgængeligt.

Systemet, der kører aztfy, skal have Azure CLI installeret og kræver, at det er blevet autentificeret ved hjælp af 'az login'.

Først skal du oprette de nødvendige mapper for hver af ressourcegrupperne - og lad os så køre værktøjet.

Når kommandoen er kørt, bliver vi mødt med følgende:

Værktøjet har fundet 6 ressourcer i alt, inklusiv ressourcegruppen. I venstre side er der pærer (💡). Disse indikerer, at aztfy med kan importere ressourcen. Desværre kan det tredje element, en virtuel maskine, ikke importeres automatisk af aztfy og har brug for en hjælpende hånd. Heldigvis giver værktøjet mulighed for nemt at identificere ressourcer, der ikke kan importeres.

Først specificerer vi ressourcetypen i Terraform (azurerm_virtual_machine) og angiver derefter et symbolsk navn, der vil blive brugt i konfigurationen - ét voilà, ressourcen kan nu importeres. Bemærk, at vi også aktivt kan springe uønskede ressourcer over.

Efter cirka 2 eller 3 minutter bliver vi mødt af:

Easy peasy. Nu har aztfy genereret et par filer, inklusiv Terraform state-filer. Af de genererede filer der indeholder konfigurationer, som vi nok ønsker at ændre, er provider.tf- og main.tf-filerne.

Provider.tf indeholder ’provider-blokken’ og Terraform-blokken, der angiver hvilken version af 'azurerm' vi skal bruge.

Main.tf indeholder alle de importerede ressourcer, inklusive den virtuelle maskine, som vi manuelt skulle inkludere i importen.

Når vi kører ‘Terraform plan’, får vi følgende:

Succes! Vores portal-drevene udvikling er nu blevet oversat til Terraform-filer og aktivt kodificeret.

Lad os prøve med vores ‘app-service’:

Aztfy fandt 110 elementer relateret til app-tjenesten. Efter inspektion finder vi ud af, at 103 elementer er ‘snapshots’ gemt i Azure, og disse kan springes over. Igen ser det ud til, at nogle af ressourcerne har brug for en hjælpende hånd, før de kan importeres. Microsoft.Web/sites er den egentlige ‘app-service’ (nummer 2 på listen). En cool funktion ved "aztfy” er, at vi kan få anbefalinger, ved at trykke på "r" på en valgt ressource. Anbefalingerne kan være fordelagtige, hvis vi er i tvivl, hvilken Terraform type, der er tale om.

Desværre er ikke alle typer Terraform-ressourcer understøttet af anbefalinger. De ressourcetyper, der præsenteres i anbefalingerne, er i dette tilfælde kun delvist korrekte, mere specifikt er azurerm_app_servicen forkert, da det er en forældet Terraform-ressource – azure_linux_web_appen, der ikke præsenteres af anbefalingerne, er nødvendig i stedet.

Når Terraform-filerne er blevet oprettet, så lad os prøve at køre en "Terraform-plan" og se hvordan det går:

Det ser ud til, at azurerm_app_service_planen er blevet afløst af azurerm_service_planen. Udover advarslen ser det ud til, at alt er godt... I hvert fald på overfladen. Med henvisning til den indledende præsentation af ‘app-service', havde vi et Nginx docker-billede inkluderet på vores app-tjeneste, men i den genererede konfiguration, er det ingen steder at finde. Det ville kræve en yderligere manuel konfiguration at få det inkluderet.

Next up: Terraformer

Næste værktøj i rækken er Terraformer. Det er ikke så ligetil som Terrafy, primært på grund af flere muligheder i kommandolinje-inputs.

I modsætning til aztfy kræver Terraformer, at man indstiller et par miljøvariabler (subscription id, application ID, application secret og tenant ID) på grund af en igangværende bug, hvor der skal bruges en serviceprincipal i stedet for en brugerkonto. Da Terraformer ikke kun er begrænset til Azure, er der også behov for en ’provider block’, der angiver, at vi ønsker at bruge Azure.

Når de er indstillet og "Terraform init" er kørt, kan vi begynde at importere. Terraformer har en del konfigurationer, og det er muligt at konvertere hver ressource til sin egen fil, men til denne demo vil vi bruge den kompakte version, som genererer alle vores konfigurationer til en enkelt fil.

Når importen er færdig, får vi følgende filer:

Når vi kører "Terraform plan" på den nyligt genererede kode, får vi en masse fejl relateret til ’the managed disk’, der angiver, at de angivne argumenter er forkerte.

I modsætning til “Aztfy” returneres for meget af værktøjet. En hel del af de genererede konfigurationerne er ikke nødvendige for at provisionere en given ressource. Den første fejl er relateret til et fejldomæne (fault-domain) og kræver, at der gives et ’VM-scale set ID’. Det giver dog ikke så meget mening, da vi kun har en enkelt VM uden availability-sets aktiveret. Dette skal blot slettes fra konfigurationen. Desværre fortsætter det samme mønster ned gennem fejlmeddelelserne, og der er indsat konfigurationer, hvor de ikke er nødvendige.

Nu gentager vi den samme procedure for vores ‘app-service’. Når importen er fuldført, og vi tester, om konfigurationen kan implementeres, bliver vi mødt af følgende:

Ikke helt uventet, får vi lignende fejl, som ved den forrige demo. Nogle af konfigurationerne skulle have været udelukket fra importen. Som med Aztfy er den samme advarsel til stede, med hensyn til app-tjenesten. Den har importeret en nu forældet version af app-tjenesten.

Efter at have fjernet nogle af fejlene, er vi nu i stand til at køre en vellykket ‘Terraform plan'. Selvom vi fra planen bliver præsenteret for "0 at tilføje, 1 at ændre, 0 at ødelægge", hvilket betyder, at Terraformer ikke har importeret alle tre ressourcer (app-serviceplan, app-service og ressource gruppe). App-serviceplanen mangler desværre og skal skrives uden hjælp fra ’toolet’.

Dommen og næste skridt

Efter at have testet begge tools, er det indlysende, at de begge fungerer, som en nem måde at kodificere eksisterende infrastruktur på, men ingen af dem giver en gylden løsning. “Aztfy” er den klare vinder i denne test, hvad angår brugervenlighed, da der ikke var behov for mange præ-konfigurationer. Samtidig giver aztfy’s brugergrænseflade et klart overblik over, hvad der kan og ikke kan importeres. "Terraformer" på den anden side giver for mange irrelevante indstillinger i de importerede filer, hvilket forårsager en masse fejl og kræver et par tweaks i filerne for at skabe en vellykket ‘Terraform plan’. Yderligere er de genererede filer temmelig statiske, hvilket kræver en masse refaktorering for at øge genanvendeligheden, specifikt ved at definere variabler og output, og går man et skridt videre, også at definere ressourcerne i genanvendelige moduler. Derudover er ‘Terraform state’ filen, der bruges af Terraform, som standard også gemt lokalt, men bør gemmes eksternt på en sikker måde.

Da de testede eksempler var ret enkle, er det ikke svært at forestille sig en ressourcegruppe indeholdende en del flere ressourcer end kun en VM eller en simpel ‘app service’. Vi kan derfor konkludere, at det uden tvivl er fordelagtigt og lettere at have defineret infrastrukturen til at begynde med, frem for at importere den senere. Hvis der er behov for import, er det dog fantastisk at vide, at der er værktøjer derude til at fremskynde denne proces og begge værktøjer hjælper med at springe en af de største forhindringer over nemlig; at definere ressourcerne.

Læs flere blogs?

DevOps – Implementering og forankring i organisationen

Organisationer, der lykkes med at arbejde med DevOps går 2.555 gange hurtigere fra commits til produktion end andre organisationer. Alene derfor kan det være en rigtig god idé, at se på sin organisation og på ’plejer’ og opnå en helt ny måde at arbejde på.

Læs bloggen her