Compendium
Published in

Compendium

Hvorfor og hvordan lage din egen terraform provider

Sammen med flere gode kollegaer hos Computas har jeg jobbet for Elvia de siste årene. Her har vi hatt stor suksess ved bruk av Terraform fra Hashicorp, og har også utviklet en egen Terraform provider for å styre våre tjenester.

Terraform er et verktøy for å skrive Infrastructure as Code. Det skrives i HashiCorp configuration language (HCL). Vi styrer alt mulig fra Terraform, som opprettelse av databaser, ad-grupper, devops-prosjekter, kjøretidsmiljøet i kubernetes og alt annet av sky-tjenester. Vi klikker altså aldri i Azure-portalen for å opprette en ressurs, men skriver heller hvilken ressurs vi vil ha i Terraform kode, og ruller det så ut i våre dev, test og prod-miljøer med terraform apply.

Ressurser som kan opprettes i Terraform er tilknyttet en provider. Feks benytter du Azure-provideren for å kunne opprette ressurser i Azure. Store skyleverandører og andre har laget providere slik at du allerede enkelt kan opprette ressurser for de store skyplattformene.

Men hva med de systemene du har laget selv? Hvis konfigurasjon av dem blir såpass omfattende at du gjerne skulle hatt “Infrastructure as Code” for dette kan det være en mulighet å lage din egen terraform provider. Sånn var det for oss med Elvias innloggingstjeneste som heter ElvID (Elvia ID).

Vårt case

Konfigurasjon for klientene må registreres i ElvID. For UserClients (Authorization code) må man registrere scopes, gyldige urler for redirects, CORS, innloggingsmetoder for sluttbrukere osv. For maskinclienter (client credentials) må det registres en client_id og client_secret, samt scopes.

Vi benyttet først et simpelt GUI for å registrere klientene, men det viste seg at det ikke var en tilstrekkelig. Over tid ble det stadig behov for nye klienter. Samtidig var det få personer som hadde tilgang og kompetanse til å registrere disse. Utviklerne flest måtte da vente på at denne jobben ble gjort av andre. Sikkerhetsmessig var det ikke heldig at secrets måtte manuelt genereres og kopieres over til vår secret-manager (via terraform). Dette manuelle arbeidet tok jo også endel tid og måtte også gjøres for hvert av våre miljøer.

Med nå rundt 100 slike klienter, som måtte registreres i 3 miljøer hadde det blitt veldig mye manuelt arbeid å gjøre det måten vi gjorde før. Løsningen for oss var å lage vår egen terraform provider.

Hvordan lage en terraform provider

Provideren vi har laget er opensourcet (her er github-repo). Både fordi vi synes det er fint å dele kode og at det gjør det lettere ved publisering i Terreaform Registry.

Schema for provideren

Under ser du utdrag fra kildekoden for vår provider. Her defineres blant annet en tenant_id som required input. Fullstendig kode finner du her.

Go kode i terraform provider

Les mer dokumentasjon om provider schema.

Resources

Terraform holder selv styr på status på hver resource du har rullet ut, og kaller selv riktig CRUD-operasjon ved terraform apply.

Se feks vår resource for machineclient. Fullstendig kode for resourceMachineClient finner du her.

Go kode i terraform provider
HCL kode for bruk i terraform

Merk at denne machineclient-en er ubrukelig uten en client_secret. Client_secret er en annen resource i vår provider. Mer om dette i avsnittet om moduler.

Se mer info om å lage resources på denne og påfølgende sider i terraforms guide.

Sikring av API

Vi brukte her tokens fra AzureAD, da vi allerede hadde det tilgjengelig i våre terraform workspaces.

Lokal bygging og debugging

Publisering av provideren til Terraform registry

Følg denne guiden for publisering av provideren. Vi benytter github-actions for automatisk publisering av nye releases. Dette er også beskrevet i den nevnte guiden.

Skjermbilde fra Terraform Registry

Denne provideren finner du her i Terraform Registry

Lag moduler for å forenkle bruk og innføre standarder

Fordelen er at du kan innføre standarder på feks navn og alt mulig annet, og koble sammen flere resources for enkelt bruk, også på tvers av providere.

Feks har vi en modul for elvid-machineclients. Den benytter elvid-provideren til å lage en machineclient-resource og en client_secret-resource. Så benytter den Hashicorp Vault provider for å legge client_id og client_secret i vår secret-manager.

HCL kode i modul

Bruk av provider og modul

HCL kode for bruk i terraform

Resultatet etter å kjøre terraform apply er at dette er klart til bruk med hemmeligheter lagt inn i Vault. Fra Vault kan vi programmatisk hente ut disse hemmelighetene under kjøring.

Skjermbilde fra Vault

Klienten kan også benyttes i Postman, her ved å få laget et access_token for denne machineclient-en basert på client_id og client_secret

Skjermbilde fra Postman

Resultat

Nå kan alle teamene vi har her sette opp det de trenger i terraform selv, med en gang de trenger det og uten å involvere admins. Også helt uten manuelt toil-arbeid, og ingen copy-paste av hemmeligheter. Dette kan så enkelt rulles ut til alle miljøer, og navnestandarder blir håndhevet av seg selv.

Takk til Elvia for et godt samarbeid og at vi kunne dele koden og det vi har gjort rundt dette.

The possibilities in technology are innumerable and we know that we can use our knowledge to make a big difference in people’s lives.