Dernière révision : mai 2026
Configurez les services AWS figurant à l'examen AZ-104 avec Terraform simple — un bloc à la fois, chacun étant lié à un domaine de l'examen. Le même code fonctionne sur OpenTofu.
À la fin de ce labo, vous aurez provisionné, avec du Terraform simple, la charge de travail de référence AZ-104 : un groupe de ressources, un VNet avec un sous-réseau privé protégé par un NSG, une machine virtuelle Linux avec une identité gérée attribuée par le système, un compte de stockage que la machine virtuelle peut lire via cette identité, et un espace de travail Log Analytics recevant les diagnostics de la machine virtuelle. Chaque bloc est lié à l'un des cinq domaines de l'examen AZ-104.
Insérez les extraits dans un seul fichier main.tf, exécutez terraform init, puis terraform apply étape par étape.
>= 1.5 ou OpenTofu >= 1.6.az login).~/.ssh/id_rsa.pub (ou modifiez le chemin à l'étape 4) pour la connexion administrateur de la machine virtuelle.La machine virtuelle est la principale source de coûts :
Arrêtez la machine virtuelle (az vm deallocate) lorsque vous ne l'utilisez pas activement pour réduire de moitié les coûts de calcul. Détruisez l'intégralité du groupe de ressources pour arrêter complètement la facturation.
Ouverture Azure standard : épingler azurerm ~> 4.0, créer le groupe de ressources, lire la clé publique SSH locale comme source de données afin que la machine virtuelle de l'étape 4 puisse l'utiliser. Le domaine Identité et Gouvernance de l'AZ-104 teste les groupes de ressources comme la plus petite portée RBAC ; les balises ici se répercutent pour le suivi des coûts sous Surveiller les ressources Azure.
terraform {
required_version = ">= 1.5"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
}
}
provider "azurerm" {
features {}
}
resource "random_id" "suffix" {
byte_length = 2
}
locals {
tags = {
Project = "certlabpro-az-104"
ManagedBy = "terraform"
}
}
resource "azurerm_resource_group" "main" {
name = "certlabpro-az-104-rg"
location = "eastus"
tags = local.tags
}Chaque charge de travail AZ-104 s'exécute au sein d'un réseau virtuel. Nous créons un VNet en /16 et découpons un sous-réseau en /24 pour la machine virtuelle. Le NSG attaché au sous-réseau autorise le trafic SSH (port 22) entrant — en production, le CIDR source serait restreint ; le labo l'ouvre à * afin que vous puissiez vous connecter depuis n'importe quelle IP.
Le domaine Déployer et Gérer les réseaux de l'AZ-104 teste ce modèle de sécurité en couches de manière répétée : les NSG sont avec état, ils s'appliquent aux sous-réseaux ou aux cartes réseau (nous l'appliquons au sous-réseau ici — la meilleure pratique AZ-104), et la structure de règles de refus par défaut + autorisation explicite est la façon dont les NSG Azure diffèrent des groupes de sécurité AWS (les NSG Azure ont des numéros de règles explicites ; les SG AWS n'en ont pas).
resource "azurerm_virtual_network" "main" {
name = "certlabpro-az-104-vnet"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
address_space = ["10.0.0.0/16"]
tags = local.tags
}
resource "azurerm_subnet" "app" {
name = "app"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.1.0/24"]
}
resource "azurerm_network_security_group" "app" {
name = "certlabpro-az-104-nsg"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
security_rule {
name = "AllowSSH"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
tags = local.tags
}
resource "azurerm_subnet_network_security_group_association" "app" {
subnet_id = azurerm_subnet.app.id
network_security_group_id = azurerm_network_security_group.app.id
}Valeurs par défaut de stockage AZ-104 standard : niveau Standard, LRS, HTTPS uniquement, TLS 1.2 minimum, accès public bloqué. Nous accorderons à l'identité gérée de la machine virtuelle un accès en lecture à ce compte à l'étape 4. Le domaine Gérer les identités et la gouvernance Azure teste ce modèle identité gérée → ressource comme alternative sans mot de passe au stockage des clés de compte de stockage dans la configuration de l'application.
resource "azurerm_storage_account" "data" {
name = "az104data${random_id.suffix.hex}"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
account_tier = "Standard"
account_replication_type = "LRS"
account_kind = "StorageV2"
https_traffic_only_enabled = true
min_tls_version = "TLS1_2"
allow_nested_items_to_be_public = false
tags = local.tags
}La machine virtuelle est l'artefact de calcul canonique de l'AZ-104. Nous utilisons Standard_B1s (la plus petite SKU Linux éligible au niveau gratuit), Ubuntu 22.04 LTS, l'authentification par clé SSH (la réponse anti-modèle de mot de passe AZ-104) et une identité gérée attribuée par le système.
L'attribution de rôle accorde à cette identité gérée le rôle Storage Blob Data Reader sur le compte de stockage de l'étape 3 — ce qui signifie que la machine virtuelle peut appeler les API REST de stockage en utilisant son jeton d'identité, sans aucune clé stockée sur le disque. C'est la question croisée AZ-104 Implémenter et gérer le stockage + Identité : comment une machine virtuelle accède-t-elle au stockage sans identifiants ? Identité gérée + attribution de rôle RBAC.
resource "azurerm_public_ip" "vm" {
name = "certlabpro-az-104-vm-pip"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
allocation_method = "Static"
sku = "Standard"
tags = local.tags
}
resource "azurerm_network_interface" "vm" {
name = "certlabpro-az-104-vm-nic"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
ip_configuration {
name = "ipconfig1"
subnet_id = azurerm_subnet.app.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.vm.id
}
tags = local.tags
}
resource "azurerm_linux_virtual_machine" "main" {
name = "certlabpro-az-104-vm"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
size = "Standard_B1s"
admin_username = "azureuser"
disable_password_authentication = true
network_interface_ids = [azurerm_network_interface.vm.id]
admin_ssh_key {
username = "azureuser"
public_key = file("~/.ssh/id_rsa.pub")
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts-gen2"
version = "latest"
}
identity {
type = "SystemAssigned"
}
tags = local.tags
}
resource "azurerm_role_assignment" "vm_storage_reader" {
scope = azurerm_storage_account.data.id
role_definition_name = "Storage Blob Data Reader"
principal_id = azurerm_linux_virtual_machine.main.identity[0].principal_id
}Le domaine Surveiller et maintenir les ressources Azure de l'AZ-104 (environ 10 à 15 % de l'examen) s'appuie sur Log Analytics comme destination pour tout ce qui est observable. Nous créons l'espace de travail et un paramètre de diagnostic sur le compte de stockage de l'étape 3 — chaque transaction de stockage se retrouve désormais sous forme KQL interrogeable.
Pour la machine virtuelle, nous installerions typiquement l'Agent Azure Monitor (AMA) via une extension de machine virtuelle — c'est la voie moderne après l'Agent Log Analytics. Pour le labo, nous configurons l'espace de travail ; l'installation de l'agent elle-même est une étape d'exécution distincte (azurerm_virtual_machine_extension) qui est couverte dans Parcourir / Editorial. La forme architecturale — l'espace de travail existe, les ressources y sont acheminées — est ce que les questions de l'AZ-104 testent.
resource "azurerm_log_analytics_workspace" "main" {
name = "certlabpro-az-104-logs"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
sku = "PerGB2018"
retention_in_days = 30
tags = local.tags
}
resource "azurerm_monitor_diagnostic_setting" "storage" {
name = "diag"
target_resource_id = "${azurerm_storage_account.data.id}/blobServices/default/"
log_analytics_workspace_id = azurerm_log_analytics_workspace.main.id
enabled_log {
category = "StorageRead"
}
enabled_log {
category = "StorageWrite"
}
metric {
category = "AllMetrics"
enabled = true
}
}terraform destroy démantèle tout. Deux remarques :
az vm deallocate arrête la facturation du calcul (le stockage continue d'être facturé). terraform destroy supprime tout.Static — elle survit à la désallocation de la machine virtuelle, et conserve la réservation de l'adresse IP. Détruisez-la ou convertissez-la en Dynamic si vous ne voulez pas payer pour une IP publique inutilisée (~0,005 $/heure).L'AZ-104 couvre une large surface d'opérations — Azure Backup, Recovery Services Vault, Site Recovery, Azure Files / Azure File Sync, Azure Migrate, Application Gateway, Load Balancer, Azure Bastion, VPN Gateway, ExpressRoute, Azure Firewall, Azure Policy, Azure Blueprints (en cours d'abandon), Accès conditionnel dans Entra ID, B2B/B2C, rôles personnalisés RBAC et modèles ARM/Bicep.
Nous nous en tenons à la base VNet + VM + Stockage + Moniteur car c'est le substrat que toutes les autres questions AZ-104 supposent. Ajoutez une passerelle d'application (Application Gateway) pour le routage de couche 7 ; ajoutez une passerelle VPN (VPN Gateway) pour la connectivité hybride ; ajoutez un Recovery Services Vault pour la sauvegarde — chacun est un ajout ciblé à cette base.
Pour une couverture service par service, consultez les sections Parcourir, Guide et Editorial de cette page de certification.