Cursus
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:
- Initialiseren:
terraform initom providers te downloaden en de backend op te zetten. - Plannen:
terraform plan -outom een uitvoeringsplan te genereren en op te slaan. - Review (handmatige goedkeuring): Een fase waarin het gegenereerde plan door een persoon wordt beoordeeld en goedgekeurd voordat het wordt toegepast.
- Toepassen:
terraform apply tfplanom 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:
- Workflowtrigger definiëren: Meestal
on: pushnaar een specifieke branch (bijv.main). - Code uitchecken: Gebruik
actions/checkout@v3. - Azure-inloggegevens configureren: Stel omgevingsvariabelen in met GitHub Secrets (bijv.
AZURE_CLIENT_ID,AZURE_CLIENT_SECRET,AZURE_TENANT_ID,AZURE_SUBSCRIPTION_ID). - Terraform installeren: Gebruik
hashicorp/setup-terraform@v2. - Terraform init: Initialiseer de werkmap.
- Terraform plan: Maak en toon het uitvoeringsplan.
- 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 planuit 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 applyopnieuw 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 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.

