Ga naar hoofdinhoud

Terraform op Azure: een praktische beginnersgids voor IaC

Deze tutorial laat je zien hoe je Terraform met Azure gebruikt om infrastructuur te automatiseren, de consistentie te verbeteren en best practices te implementeren voor veilige, schaalbare deployments.
Bijgewerkt 2 okt 2026  · 13 min lezen

Verken met AI

ChatGPTClaudePerplexity

Heb je weleens doorklikkend in de Azure-portal geprobeerd om cloudresources handmatig bij elkaar te puzzelen? Ik ook—en dat wordt snel oud. Daar komt Terraform om de hoek kijken. Het is een infrastructure-as-code (IaC)-tool waarmee je je cloudomgeving kunt definiëren en beheren met slechts een paar regels code.

In deze tutorial focussen we op het gebruik van Terraform met Azure. Ik leg uit wat Terraform is, hoe het werkt binnen het Azure-ecosysteem en hoe je aan de slag gaat met praktische voorbeelden. We behandelen ook een aantal best practices om je vanaf het begin te helpen met veilige en betrouwbare deployments.

Als je nieuw bent in het Azure-ecosysteem, deze Azure fundamentals-track biedt een gestructureerde introductie tot de kernservices en -principes.

Waarom Terraform op Azure gebruiken?

Terraform, ontwikkeld door HashiCorp, is een open-source IaC-tool waarmee je cloudinfrastructuur kunt definiëren en beheren met een declaratieve syntaxis. In combinatie met Microsoft Azure kun je resources zoals virtuele netwerken, VM’s en databases scripten in menselijk leesbare configuratiebestanden.

Waarom Terraform met Azure gebruiken? Het draait om consistentie, schaalbaarheid en snelheid. Of je nu één VM opzet of een complexe, multi-tier applicatie orkestreert, Terraform vereenvoudigt het proces en verkleint de kans op menselijke fouten.

Als je helemaal nieuw bent met Terraform, deze beginnersgids voor Terraform legt de basis uit en hoe je begint met infrastructure as code.

Kernconcepten van Terraform op Azure

De integratie van Terraform met Azure biedt een reeks features die infrastructuurbeheer intuïtief en krachtig maken. Laten we de belangrijkste componenten en typen Terraform-resources bekijken.

Declaratief infrastructuurbeheer

De declaratieve aanpak van Terraform laat je in .tf-bestanden met HashiCorp Configuration Language (HCL) definiëren hoe je Azure-infrastructuur eruit moet zien. 

Je kunt bijvoorbeeld een Azure VM specificeren met formaat, locatie en netwerkinstellingen, en Terraform regelt het hoe van het aanmaken. Hier is een kort voorbeeld:

resource "azurerm_virtual_machine" "example" {
  name                  = "my-vm"
  location              = "East US"
  resource_group_name   = "my-resource-group"
  vm_size               = "Standard_D2s_v3"
  network_interface_ids = [azurerm_network_interface.example.id]
  # ... other necessary configurations like OS disk, admin details
}

Bovenstaande definitie zorgt voor idempotentie—dezelfde code meerdere keren draaien levert hetzelfde resultaat op, zonder duplicaten of fouten. 

Laten we nu de kernconcepten van Terraform doornemen die deze declaratieve aanpak mogelijk maken.

Terraform-state (.tfstate)

Het bestand terraform.tfstate is het hart van het declaratieve model van Terraform. Het is een JSON-bestand dat de huidige status van je Azure-resources vastlegt—wat is uitgerold, de configuraties en onderlinge relaties. 

Wanneer je terraform apply draait, vergelijkt Terraform je .tf-bestanden (de gewenste staat) met het .tfstate-bestand (de actuele staat) om te bepalen welke wijzigingen nodig zijn. Pas je bijvoorbeeld de grootte van een VM aan in je code, dan controleert Terraform het .tfstate-bestand en wijzigt alleen dat attribuut in Azure. 

Je kunt dit bestand lokaal opslaan, maar voor teams is Azure Blob Storage aan te raden om samen te werken en state locking te gebruiken om conflicten te voorkomen.

Terraform-variabelen (.tfvars)

Variabelen maken je configuraties flexibel en herbruikbaar. Gedefinieerd in variables.tf en terraform.tfvars kun je ermee waarden parameteriseren zoals resourcenamen of regio’s. 

Bijvoorbeeld:

# variables.tf
variable "location" {
  type        = string
  default     = "East US"
  description = "The Azure region where resources will be deployed."
}

# terraform.tfvars (for a specific environment, e.g., production)
location = "West US"

# main.tf
resource "azurerm_resource_group" "example" {
  name     = "my-rg"
  location = var.location
}

Het terraform.tfvars-bestand overschrijft defaults, zodat je dezelfde code in verschillende regio’s kunt uitrollen zonder de kern-.tf-bestanden te wijzigen. Dit kun je gebruiken voor het beheren van meerdere omgevingen (bijv. dev, prod).

Terraform-configuratiebestanden (.tf)

Deze bestanden bevatten je infrastructuurcode, geschreven in HCL. Ze definiëren resources, providers, modules en meer. Je kunt alles in één main.tf plaatsen of opsplitsen in meerdere bestanden (bijv. variables.tf, outputs.tf, network.tf, compute.tf) voor duidelijkheid en betere organisatie.

Terraform plan

Voordat je wijzigingen toepast, toont het commando terraform plan een preview van wat Terraform zal doen—resources aanmaken, bijwerken of verwijderen—op basis van het verschil tussen je .tf-bestanden en de .tfstate. Het is een soort dry-run die potentiële issues vroegtijdig signaleert, met een gedetailleerd overzicht van de acties.

Terraform apply

Het commando terraform apply voert de wijzigingen uit die door terraform plan zijn vastgesteld, werkt Azure bij naar je gewenste staat en ververst het .tfstate-bestand. Je wordt om bevestiging gevraagd voordat wijzigingen worden toegepast: een extra veiligheidslaag.

Workspaces

Met Terraform-workspaces beheer je meerdere omgevingen (bijv. dev, staging, prod) met één set .tf-bestanden. Elke workspace heeft een eigen .tfstate-bestand, zodat je vergelijkbare infrastructuur kunt uitrollen met verschillende configuraties (bijv. andere VM-groottes voor dev versus prod). 

Om een nieuwe workspace te maken, gebruik je:

terraform workspace new production

Vervolgens kun je naar die workspace schakelen:

terraform workspace select production

Modules

Modules zijn herbruikbare pakketten met Terraform-code. Je kunt bijvoorbeeld een module maken voor een Azure virtueel netwerk en die hergebruiken in projecten, waardoor je duplicatie vermindert en standaardisatie bevordert. We behandelen modules verder bij de best practices.

Deze concepten—.tfstate, .tfvars en de declaratieve workflow—werken samen om je Azure-infrastructuur voorspelbaar, reproduceerbaar en eenvoudig beheersbaar te maken.

Statebeheer en samenwerking

Het bestand terraform.tfstate houdt de staat van je infrastructuur bij. Voor teams is opslag in Azure Blob Storage een cruciale best practice om gedeelde toegang en versiebeheer mogelijk te maken. Deze remote backend-configuratie zorgt ervoor dat alle teamleden met een consistente weergave van de infrastructuur werken. 

State locking, een feature die door veel remote backends zoals Azure Blob Storage automatisch wordt geleverd, voorkomt conflicten wanneer meerdere teamleden gelijktijdig Terraform-commando’s uitvoeren en waarborgt de dataintegriteit.

Hier is een voorbeeld van het configureren van een Azure Blob Storage-backend:

terraform {
  backend "azurerm" {
    resource_group_name  = "my-terraform-state-rg"
    storage_account_name = "mystorageterraformstate"
    container_name  = "tfstate"
    key  = "production/terraform.tfstate" # Path within the container
  }
}

Voordat je terraform init met deze configuratie draait, moet je het Azure storage account en de container eerst handmatig aanmaken of via een aparte Terraform-configuratie. Deze setup zorgt voor veilig, gezamenlijk beheer van Azure-resources.

Providerecosysteem en AzureRM

De azurerm-provider is Terraforms brug naar Azure en vertaalt HCL naar API-calls om services zoals VM’s, netwerken en databases te beheren. 

Hij ondersteunt honderden resourcetypen, van compute (azurerm_linux_virtual_machine, azurerm_windows_virtual_machine) tot analytics (azurerm_synapse_workspace). Enkele kenmerken zijn:

  • Brede dekking: Beheer een groot scala aan Azure-services, waaronder virtuele machines, storage-accounts, Azure Kubernetes Service (AKS), Azure SQL Database, Azure Cosmos DB met MongoDB API, Azure Functions en veel meer. De azurerm-provider wordt actief ontwikkeld om nieuwe Azure-services en features te ondersteunen zodra deze beschikbaar komen.
  • Dynamische functies: Gebruik provider-gedefinieerde functies om unieke namen te genereren (bijv. azurerm_resource_group.example.name) of details op te halen van bestaande resources (bijv. data.azurerm_virtual_network.existing.id). Dit maakt configuraties dynamischer en slimmer.
  • Data sources: De azurerm-provider benut data sources om informatie over bestaande Azure-resources op te halen. Dit is vooral handig wanneer je moet verwijzen naar resources die niet door je huidige Terraform-configuratie zijn uitgerold. Zo kun je bijvoorbeeld details van een bestaand virtueel netwerk ophalen om nieuwe subnets of VM’s te deployen zonder de VNet opnieuw te maken.

Voordat je in Terraform duikt, is het handig om te weten hoe je Azure handmatig configureert—deze beginnersgids loodst je door de basis.

Een Terraform-Azure-omgeving opzetten

Aan de slag! In deze sectie doorlopen we de initiële setup die nodig is om Terraform met je Azure-abonnement te gebruiken.

Authenticatie en CLI-tools

Om met Azure te communiceren, moet je eerst de Azure Command Line Interface (CLI) installeren en configureren. De Azure CLI biedt de benodigde tools voor authenticatie en het beheren van je Azure-resources. Nadat je deze hebt geïnstalleerd, log je in op je Azure-account:

az login

Bovenstaand commando opent een browservenster voor interactieve authenticatie. Voor snelle referentie kan deze Azure CLI-cheatsheet je commandline-workflows streamlijnen.

Voor geautomatiseerde deployments met Terraform, vooral in CI/CD-pijplijnen, is het sterk aan te raden om Azure Active Directory (AAD) service-principals te maken en te gebruiken. Service-principals bieden een veilige, programmatische manier voor Terraform om zich te authentiseren bij je Azure-abonnement zonder interactieve logins.

Om een service-principal met de rol "Contributor" op abonnementsniveau te maken, draai je:

az ad sp create-for-rbac --name "http://myTerraformServicePrincipal" --role "Contributor" --scopes "/subscriptions/<your-subscription-id>"

De output bevat appId, password en tenant (tenant-id). Stel deze vervolgens in als omgevingsvariabelen voor Terraform:

export ARM_CLIENT_ID="<appId>"
export ARM_CLIENT_SECRET="<password>"
export ARM_TENANT_ID="<tenant>"
export ARM_SUBSCRIPTION_ID="<your-subscription-id>"

Een project initialiseren

Een typisch Terraform-project volgt een gestructureerde mapindeling, vaak met aparte .tf-bestanden voor verschillende resourcetypen of modules (bijv. main.tf, variables.tf, outputs.tf, network.tf, compute.tf). 

Ga naar je projectmap en draai terraform init om elk Terraform-project te starten. Dit commando initialiseert de werkmap, downloadt de benodigde provider-plugins (zoals azurerm) en zet de backend voor statebeheer op zoals in je configuratie gedefinieerd.

mkdir my-azure-terraform-project
cd my-azure-terraform-project
# Create your .tf files here
terraform init

Dit commando bereidt je map voor op Terraform-operaties en zorgt dat alle vereiste plugins aanwezig zijn.

Azure-resources provisionen

In deze sectie vind je praktische voorbeelden van het provisionen van veelvoorkomende Azure-resources met Terraform, waarin we laten zien hoe je ze programmatisch definieert en uitrolt.

Virtuele netwerken en subnets

Terraform blinkt uit in het definiëren en uitrollen van netwerkarchitectuur op Azure. Je definieert eenvoudig virtuele netwerken (VNet’s) en segmenteert deze in subnets, met controle over IP-adresruimtes en netwerkisolatie. 

Dankzij de ingebouwde afhankelijkheidslogica van Terraform worden resources in de juiste volgorde aangemaakt; zo worden subnets pas geprovisioned nadat hun bovenliggende VNet succesvol is aangemaakt. Hier is een voorbeeld:

resource "azurerm_resource_group" "network_rg" {
  name     = "my-network-rg"
  location = "East US"
}

resource "azurerm_virtual_network" "main_vnet" {
  name                = "my-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.network_rg.location
  resource_group_name = azurerm_resource_group.network_rg.name
}

resource "azurerm_subnet" "web_subnet" {
  name                 = "web-subnet"
  resource_group_name  = azurerm_resource_group.network_rg.name
  virtual_network_name = azurerm_virtual_network.main_vnet.name
  address_prefixes     = ["10.0.1.0/24"]
}

resource "azurerm_subnet" "app_subnet" {
  name                 = "app-subnet"
  resource_group_name  = azurerm_resource_group.network_rg.name
  virtual_network_name = azurerm_virtual_network.main_vnet.name
  address_prefixes     = ["10.0.2.0/24"]
}

Virtuele machines met cloud-init

Het provisionen van virtuele machines (VM’s) met Terraform is eenvoudig. Voor geautomatiseerde post-deploymentconfiguratie en initiële setup kun je cloud-init-scripts gebruiken. 

cloud-init laat je scripts injecteren die bij de eerste boot van de VM draaien. Zo kun je software installeren, gebruikers configureren of services instellen, rechtstreeks vanuit je Terraform-configuratie.

Hier is een voorbeeld van het provisionen van een Linux-VM met een eenvoudig cloud-init-script om Nginx te installeren:

resource "azurerm_resource_group" "vm_rg" {
  name     = "my-vm-rg"
  location = "East US"
}

resource "azurerm_network_interface" "vm_nic" {
  name                = "my-vm-nic"
  location            = azurerm_resource_group.vm_rg.location
  resource_group_name = azurerm_resource_group.vm_rg.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.web_subnet.id # Assuming web_subnet defined above
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.vm_public_ip.id
  }
}

resource "azurerm_public_ip" "vm_public_ip" {
  name                = "my-vm-public-ip"
  location            = azurerm_resource_group.vm_rg.location
  resource_group_name = azurerm_resource_group.vm_rg.name
  allocation_method   = "Static"
}

resource "azurerm_linux_virtual_machine" "my_vm" {
  name                  = "my-linux-vm"
  location              = azurerm_resource_group.vm_rg.location
  resource_group_name   = azurerm_resource_group.vm_rg.name
  size                  = "Standard_B2s"
  admin_username        = "azureuser"
  admin_password        = "P@ssw0rd1234!" # In a real scenario, use Azure Key Vault or variables
  network_interface_ids = [azurerm_network_interface.vm_nic.id]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }

  # cloud-init script to install Nginx
  custom_data = base64encode(<<EOF
#cloud-config
packages:
  - nginx
runcmd:
  - systemctl start nginx
  - systemctl enable nginx
EOF
  )
}

Infrastructuur modulariseren

Naarmate je Azure-infrastructuur groeit, wordt het modulariseren van je Terraform-configuraties cruciaal voor hergebruik, onderhoudbaarheid en schaalbaarheid. 

Modules kapselen een set gerelateerde resources en configuraties in herbruikbare eenheden. In deze sectie krijg je richtlijnen voor het structureren van je Terraform-code in modules en laten we zien hoe je deze modules aanroept in je hoofdconfiguraties, voor een schonere en beter georganiseerde codebase.

Voorbeeld: Modulestructuur (modules/web-app/main.tf):

# modules/web-app/main.tf
resource "azurerm_app_service_plan" "app_plan" {
  name                = var.app_service_plan_name
  location            = var.location
  resource_group_name = var.resource_group_name
  kind                = "Linux"
  sku {
    tier = "Basic"
    size = "B1"
  }
}

resource "azurerm_app_service" "app_service" {
  name                = var.app_service_name
  location            = var.location
  resource_group_name = var.resource_group_name
  app_service_plan_id = azurerm_app_service_plan.app_plan.id
}

variable "app_service_plan_name" {
  type = string
}

variable "app_service_name" {
  type = string
}

variable "location" {
  type = string
}

variable "resource_group_name" {
  type = string
}

output "app_service_default_hostname" {
  value = azurerm_app_service.app_service.default_host_name
}

Voorbeeld: De module aanroepen (main.tf in de hoofdmap):

resource "azurerm_resource_group" "app_rg" {
  name     = "my-webapp-rg"
  location = "East US"
}

module "my_web_app" {
  source                = "./modules/web-app" # Path to your module
  app_service_plan_name = "my-webapp-plan"
  app_service_name      = "my-unique-webapp-2025"
  location              = azurerm_resource_group.app_rg.location
  resource_group_name   = azurerm_resource_group.app_rg.name
}

output "webapp_url" {
  value = module.my_web_app.app_service_default_hostname
}

Met deze structuur hergebruik je eenvoudig je deploymentlogica voor webapplicaties in verschillende omgevingen of projecten.

Geavanceerde Terraform-workflows

In deze sectie verkennen we geavanceerde Terraform-features die de flexibiliteit en kracht van je infrastructuurdeployments vergroten, voorbij de basisprovisioning.

Data sources en dynamische configuraties

Data sources in Terraform laten je informatie ophalen over bestaande resources, zowel die door Terraform worden beheerd als daarbuiten. Dit is erg handig om te integreren met bestaande infrastructuur of voor dynamische lookups. 

Gecombineerd met dynamische configuraties (zoals for_each en count) maak je uiterst flexibele en adaptieve Terraform-scripts die kunnen reageren op verschillende omstandigheden en resourcebeschikbaarheid.

Voorbeeld: Een bestaande VNet vinden met een Data Source en een nieuw subnet toevoegen:

# Data source to fetch an existing Virtual Network
data "azurerm_virtual_network" "existing_vnet" {
  name                = "production-vnet"
  resource_group_name = "production-network-rg"
}

# Create a new subnet within the existing VNet
resource "azurerm_subnet" "new_app_subnet" {
  name                 = "new-app-subnet"
  resource_group_name  = data.azurerm_virtual_network.existing_vnet.resource_group_name
  virtual_network_name = data.azurerm_virtual_network.existing_vnet.name
  address_prefixes     = ["10.0.3.0/24"]
}

Voorbeeld: Dynamisch meerdere VM’s aanmaken met for_each en een map-variabele:

variable "vm_configs" {
  type = map(object({
    size = string
    ip   = string
  }))
  default = {
    "web-server-01" = { size = "Standard_B1s", ip = "10.0.1.10" },
    "web-server-02" = { size = "Standard_B1s", ip = "10.0.1.11" }
  }
}

resource "azurerm_linux_virtual_machine" "web_servers" {
  for_each              = var.vm_configs
  name                  = each.key
  location              = azurerm_resource_group.main_rg.location
  resource_group_name   = azurerm_resource_group.main_rg.name
  size                  = each.value.size
  admin_username        = "azureuser"
  admin_password        = "StrongPassword!123" # Use Key Vault in production
  network_interface_ids = [azurerm_network_interface.web_servers_nic[each.key].id]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }
}

resource "azurerm_network_interface" "web_servers_nic" {
  for_each            = var.vm_configs
  name                = "${each.key}-nic"
  location            = azurerm_resource_group.main_rg.location
  resource_group_name = azurerm_resource_group.main_rg.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.web_subnet.id
    private_ip_address_allocation = "Static"
    private_ip_address            = each.value.ip
  }
}

Policy as code met Sentinel

Voor organisaties met strikte compliance- en governance-eisen biedt HashiCorp Sentinel een policy-as-code-framework dat integreert met Terraform Enterprise (of kan worden aangepast voor gebruik met Terraform Cloud). 

Met Sentinel definieer je gedetailleerde policies die veiligheid, kosten en operationele best practices afdwingen vóórdat infrastructuur wordt geprovisioned. 

Een policy kan bijvoorbeeld voorkomen dat VM’s groter dan een bepaalde maat worden aangemaakt of afdwingen dat alle resources specifieke tags hebben. Voorgebouwde policies kunnen aan compliance-standaarden voldoen en niet-conforme deployments tegenhouden voordat ze je Azure-omgeving bereiken.

Strategieën voor kostenoptimalisatie

Samen met Azure Policy kan Terraform een krachtig middel zijn om kostenbeheersing in je Azure-omgeving af te dwingen. 

Door Azure Policies te definiëren die resource-SKU’s beperken, tagging voor kostenallocatie afdwingen of de deployment van dure resources voorkomen, implementeer je effectieve kostenbesparende maatregelen rechtstreeks in je IaC-workflows. 

Terraform kan ook Azure Policies deployen en beheren, zodat je governance-regels onder versiebeheer staan en consistent worden toegepast.

Voorbeeld: Een Azure Policy Definition deployen met Terraform:

resource "azurerm_resource_group" "policy_rg" {
  name     = "azure-policy-rg"
  location = "global" # Policies are global resources
}

resource "azurerm_policy_definition" "deny_large_vms" {
  name         = "deny-large-vm-skus"
  policy_type  = "Custom"
  mode         = "All"
  display_name = "Deny creation of large VM SKUs (E-series)"
  description  = "This policy denies the creation of Azure Virtual Machines with SKUs from the E-series for cost management."

  policy_rule = <<POLICY_RULE
{
  "if": {
    "allOf": [
      {
        "field": "type",
        "equals": "Microsoft.Compute/virtualMachines"
      },
      {
        "field": "Microsoft.Compute/virtualMachines/sku.name",
        "like": "Standard_E*"
      }
    ]
  },
  "then": {
    "effect": "deny"
  }
}
POLICY_RULE
}

resource "azurerm_policy_assignment" "deny_large_vms_assignment" {
  name                 = "deny-large-vm-skus-assignment"
  scope                = "/subscriptions/${data.azurerm_subscription.current.id}" # Assign to entire subscription
  policy_definition_id = azurerm_policy_definition.deny_large_vms.id
  display_name         = "Deny large VM SKUs"
}

data "azurerm_subscription" "current" {}

Deze combinatie laat je organisatorische kostentoezichtspolicies automatisch afdwingen, voorkomt overspending en bevordert efficiënte resource-inzet.

CI/CD-integratie

In deze sectie integreren we Terraform in je Continuous Integration/Continuous Delivery (CI/CD)-pijplijnen voor geautomatiseerde en betrouwbare deployments, zodat infrastructuurwijzigingen naadloos onderdeel worden van je softwarelevenscyclus.

Azure DevOps-pijplijnen

Azure DevOps biedt een robuust platform voor het bouwen van CI/CD-pijplijnen. Een gebruikelijke workflow omvat:

  1. Initialiseren: terraform init om providers te downloaden en de backend op te zetten.
  2. Plannen: terraform plan -out om een uitvoeringsplan te genereren en op te slaan.
  3. Review (handmatige goedkeuring): Een fase waarin het gegenereerde plan door een persoon wordt beoordeeld en goedgekeurd voordat het wordt toegepast.
  4. Toepassen: terraform apply tfplan om de wijzigingen uit te voeren.

Je kunt verkennen hoe Azure DevOps end-to-end CI/CD-workflows voor applicatiedeployment ondersteunt in deze praktische tutorial.

GitHub Actions

GitHub Actions biedt een flexibele en krachtige manier om je Terraform-workflows rechtstreeks in je GitHub-repositories te automatiseren. Het gebruikt YAML-bestanden om workflows te definiëren die reageren op events zoals push of pull requests.

Hier zijn de stappen voor een basisdeployment met Terraform via GitHub Actions:

  1. Workflowtrigger definiëren: Meestal on: push naar een specifieke branch (bijv. main).
  2. Code uitchecken: Gebruik actions/checkout@v3.
  3. Azure-inloggegevens configureren: Stel omgevingsvariabelen in met GitHub Secrets (bijv. AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID, AZURE_SUBSCRIPTION_ID).
  4. Terraform installeren: Gebruik hashicorp/setup-terraform@v2.
  5. Terraform init: Initialiseer de werkmap.
  6. Terraform plan: Maak en toon het uitvoeringsplan.
  7. Terraform apply (conditioneel): Pas wijzigingen toe, vaak afhankelijk van een handmatige goedkeuring of een specifieke branch.

Voorbeeld: YAML voor een GitHub Actions-workflow (.github/workflows/terraform-azure.yml):

name: 'Terraform Azure CI/CD'

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

env:
  ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
  ARM_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
  ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
  ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
  TF_STATE_RG: 'my-terraform-state-rg'
  TF_STATE_SA: 'mystorageterraformstate'
  TF_STATE_CONTAINER: 'tfstate'
  TF_STATE_KEY: 'production/terraform.tfstate'

jobs:
  terraform:
    name: 'Terraform Actions'
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: './terraform' # Assuming Terraform files are in a 'terraform' folder

    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
      - name: Terraform Init
        id: init
        run: terraform init -backend-config="resource_group_name=${{ env.TF_STATE_RG }}" -backend-config="storage_account_name=${{ env.TF_STATE_SA }}" -backend-config="container_name=${{ env.TF_STATE_CONTAINER }}" -backend-config="key=${{ env.TF_STATE_KEY }}"
      - name: Terraform Plan
        id: plan
        run: terraform plan -no-color
      - name: Terraform Apply
        if: github.ref == 'refs/heads/main' && github.event_name == 'push'
        run: terraform apply -auto-approve

Beveiliging en compliance

Deze sectie belicht beveiligings- en compliancethema’s bij het werken met Terraform op Azure, met de nadruk op veilig omgaan met gevoelige data en netwerktoegang.

Azure Key Vault-integratie

Het beheren van gevoelige data zoals API-sleutels, connection strings, database-inloggegevens en certificaten in je Terraform-configuraties kan riskant zijn als dit niet goed wordt afgehandeld. Azure Key Vault biedt een veilige, centrale oplossing voor het opslaan en beheren van secrets, sleutels en certificaten. 

Voorbeeld: Een databasewachtwoord ophalen uit Key Vault:

# Data source to retrieve an existing Azure Key Vault
data "azurerm_key_vault" "my_key_vault" {
  name                = "my-secure-keyvault"
  resource_group_name = "my-secrets-rg"
}

# Data source to retrieve a specific secret from the Key Vault
data "azurerm_key_vault_secret" "db_password" {
  name         = "DbPassword"
  key_vault_id = data.azurerm_key_vault.my_key_vault.id
}

resource "azurerm_sql_server" "example" {
  administrator_login          = "sqladmin"
  administrator_login_password = data.azurerm_key_vault_secret.db_password.value # Securely retrieve password
}

Zo zorg je ervoor dat gevoelige data nooit direct in je Terraform-code of statebestand staat, in lijn met security best practices.

Network Security Groups (NSG’s)

Network Security Groups (NSG’s) zijn essentieel om verkeerregels af te dwingen en je Azure-virtuele netwerken te beveiligen. Ze fungeren als een virtuele firewall die inkomend en uitgaand verkeer toestaat of blokkeert op basis van door jou gedefinieerde regels.

Voorbeeld: Een NSG configureren voor een webapplicatie:

resource "azurerm_network_security_group" "web_nsg" {
  name                = "web-nsg"
  location            = azurerm_resource_group.network_rg.location
  resource_group_name = azurerm_resource_group.network_rg.name

  security_rule {
    name                       = "AllowHTTPInbound"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "80"
    source_address_prefix      = "Internet"
    destination_address_prefix = "*"
  }
  security_rule {
    name                       = "AllowSSHInbound"
    priority                   = 120
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "22"
    source_address_prefix      = "YourTrustedIPRange" # IMPORTANT: Restrict to known IPs
    destination_address_prefix = "*"
  }
}

# Associate NSG with a subnet 
resource "azurerm_subnet_network_security_group_association" "web_subnet_nsg_association" {
  subnet_id                 = azurerm_subnet.web_subnet.id
  network_security_group_id = azurerm_network_security_group.web_nsg.id
}

Best practices voor enterprisedeployments

Deze sectie schetst essentiële best practices voor het uitrollen en beheren van Terraform op schaal binnen een enterpriseomgeving, met focus op ontwerp, onderhoud en monitoring.

Referentiearchitecturen

Voor robuuste en efficiënte Azure-deployments stem je je Terraform-configuraties af op het Azure Well-Architected Framework. Dit framework biedt blauwdrukken voor het ontwerpen van hoogwaardige, veilige en kosteneffectieve cloudoplossingen, en leidt je Terraform-ontwerpen op betrouwbaarheid, veiligheid, kostenoptimalisatie, operationele excellentie en prestatie-efficiëntie.

Hygiëne van het statebestand

Het Terraform-statebestand is de single source of truth van je infrastructuur. Borg de integriteit en veiligheid door:

  • Remote-opslag: Gebruik altijd een remote backend zoals Azure Blob Storage voor gezamenlijk statebeheer.
  • Encryptie en toegangsbeheer: Zorg dat je remote state versleuteld is in rust en pas strikte Azure RBAC toe om toegang te beperken.
  • State locking en versiebeheer: Gebruik ingebouwde locking om conflicten te voorkomen en schakel versiebeheer in op je container voor historische tracking en herstel.

Monitoring en driftdetectie

Behoud consistentie in je infrastructuur door actief te monitoren op "configuration drift"—ongeautoriseerde afwijkingen van je gedefinieerde Terraform-state.

  • Proactieve detectie: Voer regelmatig terraform plan uit binnen je CI/CD-pijplijnen (bijv. elke nacht) om wijzigingen te identificeren.
  • Azure-monitoring: Gebruik Azure Monitor en Log Analytics om de gezondheid en events van resources te volgen.
  • Geautomatiseerde remediatie: Ontwikkel processen (handmatig of geautomatiseerd) om terraform apply opnieuw te draaien en gedivergeerde resources weer in overeenstemming te brengen met je IaC.

Voor verdere monitoring en optimalisatie biedt Azure Monitor waardevolle inzichten—deze gids laat zien hoe je begint.

Conclusie

En dat was ’m! Je hebt gezien hoe Terraform het beheren van Azure-resources veel efficiënter en voorspelbaarder maakt. We hebben bekeken hoe je automatisering in je workflow brengt met CI/CD-tools zoals Azure DevOps en GitHub Actions, en hoe je alles veilig houdt met Azure Key Vault en Network Security Groups.

We hebben ook belangrijke best practices besproken—zoals het gebruiken van referentiearchitecturen, zorgvuldig beheer van je statebestanden en het monitoren van wijzigingen met driftdetectie.

Met deze tools en tips ben je goed op weg naar het bouwen van betrouwbaardere en beter schaalbare infrastructuur op Azure.

Wil je je skills valideren? Deze Terraform-sollicitatievragen kunnen je helpen je voor te bereiden op vacatures of certificeringen!

FAQs

Wat zijn de belangrijkste voordelen van Terraform met Azure?

Terraform met Azure biedt consistentie, schaalbaarheid en snelheid bij het deployen van infrastructuur. Je definieert je cloudresources als code, wat handmatige fouten vermindert, herhaalbare deployments mogelijk maakt en het beheer van complexe omgevingen eenvoudiger maakt.

Hoe beheert Terraform de staat van mijn Azure-infrastructuur?

Terraform gebruikt een statebestand (.tfstate) om je uitgerolde Azure-resources bij te houden. Dit bestand koppelt je Terraform-configuraties aan de daadwerkelijke infrastructuur, zodat Terraform de huidige staat begrijpt en kan bepalen welke wijzigingen nodig zijn bij volgende deployments.

Kan ik Terraform gebruiken voor zowel nieuwe infrastructuurdeployments als het beheren van bestaande Azure-resources?

Ja, absoluut! Terraform is uitstekend voor het provisionen van nieuwe infrastructuur vanaf nul. Het kan ook bestaande Azure-resources in zijn state importeren, zodat je ze voortaan met je Terraform-configuraties kunt beheren.

Hoe integreert Terraform in CI/CD-pijplijnen voor Azure-deployments?

Terraform integreert met populaire CI/CD-platformen zoals Azure DevOps Pipelines en GitHub Actions. Een CI/CD-pijplijn voor Terraform omvat doorgaans fasen zoals terraform init (initialisatie), terraform plan (weergave van voorgenomen wijzigingen) en terraform apply (wijzigingen toepassen op Azure). Deze automatisering zorgt voor consistente en betrouwbare infrastructuurdeployments.

Wat zijn enkele belangrijke beveiligingsoverwegingen bij het gebruik van Terraform op Azure?

Belangrijke aandachtspunten zijn onder andere het gebruik van Azure Key Vault om gevoelige data (zoals API-sleutels of wachtwoorden) veilig te beheren in plaats van ze hardcoded op te nemen. Daarnaast is het correct configureren van Network Security Groups (NSG’s) via Terraform cruciaal om netwerkverkeer te controleren en least-privilege-toegang tot je Azure-resources af te dwingen.


Karen Zhang's photo
Author
Karen Zhang
LinkedIn

Karen is een Data Engineer met een passie voor het bouwen van schaalbare dataplatforms. Ze heeft ervaring met infrastructuurautomatisering met Terraform en deelt haar inzichten graag in blogposts en tutorials. Karen is een community builder en ze zet zich in om verbindingen tussen dataprofessionals te stimuleren.

Onderwerpen
Azure
Cloud

Leer meer over Azure met deze cursussen!

Cursus

Microsoft Azure begrijpen

3 uur
50.8K
Leer hoe Microsoft Azure en cloudcomputersoftware je helpen je data-engineeringsvaardigheden te verbeteren.
Bekijk detailsRight Arrow
Start Cursus
Meer bekijkenRight Arrow
Gerelateerd

blog

AI vanaf nul leren in 2026: een complete gids van de experts

Ontdek alles wat je moet weten om in 2026 AI te leren, van tips om te beginnen tot handige resources en inzichten van industrie-experts.
Adel Nehme's photo

Adel Nehme

15 min

Meer BekijkenMeer Bekijken