Skip to content
Learni
Voir tous les tutoriels
DevOps

Comment déployer une infra Azure avec Bicep en 2026

Read in English

Introduction

Azure Bicep est le langage DSL (Domain-Specific Language) officiel de Microsoft pour décrire des déploiements d'infrastructure Azure de manière déclarative, remplaçant progressivement les templates ARM JSON verbeux. En 2026, avec l'essor de l'IaC (Infrastructure as Code), Bicep s'impose par sa syntaxe concise, sa compilation en ARM JSON et son intégration native à Azure CLI et VS Code. Contrairement à Terraform (multi-cloud), Bicep excelle dans l'écosystème Azure grâce à l'autocomplétion IntelliSense et la validation en temps réel.

Pourquoi l'adopter ? Il réduit les erreurs de 70 % par rapport à JSON (selon Microsoft), facilite la modularité et supporte les boucles/conditions avancées. Ce tutoriel intermédiaire vous guide pas à pas pour déployer une infra réaliste : un storage account, une VNet et un App Service, en passant par paramètres, modules et outputs. À la fin, vous maîtriserez des patterns pros bookmarkables pour scaler vos déploiements Azure.

Prérequis

  • Compte Azure actif avec abonnement (crédits gratuits via azure.microsoft.com/free).
  • Azure CLI version 2.60+ installée (az --version pour vérifier).
  • VS Code avec extension officielle Bicep (IntelliSense et validation).
  • Connaissances de base en ARM (JSON) et IaC.
  • PowerShell ou Bash pour les déploiements.

Connexion et création du groupe de ressources

setup.sh
az login
az account set --subscription "Votre-ID-Abonnement"
az group create --name rg-bicep-demo --location francecentral
az group deployment list --resource-group rg-bicep-demo --query "[].[name,timestamp]" -o table

Ce script connecte à Azure, sélectionne l'abonnement et crée un groupe de ressources rg-bicep-demo en France Centrale. La commande finale liste les déploiements existants (vide au départ) pour valider. Remplacez "Votre-ID-Abonnement" par votre ID réel via az account list ; évitez les régions non supportées pour minimiser les coûts.

Premier template Bicep simple

Commençons par un template basique déployant un compte de stockage. Bicep compile en ARM JSON valide, avec une syntaxe YAML-like intuitive. Pensez à Bicep comme un 'JSON allégé' : pas de guillemets superflus, références symboliques (@resourceId).

Template storage account basique

main.bicep
@description('Compte de stockage principal')
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: 'stbicep${uniqueString(resourceGroup().id)}'
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

Ce template déclare un storage account unique (via uniqueString pour éviter les collisions). Il utilise resourceGroup().location pour hériter de la localisation du RG. Déployez-le avec az deployment group create -f main.bicep -g rg-bicep-demo ; piège : noms globaux uniques obligatoires pour storage (max 24 chars minuscules).

Déploiement du template simple

deploy-simple.sh
az deployment group create \
  --resource-group rg-bicep-demo \
  --template-file main.bicep \
  --confirm-prompt false

Déploie le template dans le RG spécifié sans prompt. --confirm-prompt false automatise pour CI/CD. Vérifiez avec az storage account list -g rg-bicep-demo ; attention aux quotas régionaux (500 storage/RG).

Paramètres et variables pour réutilisabilité

À niveau intermédiaire, paramétrez tout : SKU, localisation, tags. Les variables centralisent les calculs. Analogie : paramètres = arguments CLI, variables = locals/const en TS.

Template avec paramètres et variables

storage-params.bicep
@minValue(1)
@maxValue(512)
@param sizeInGb int = 5

@description('Localisation')
@param location string = resourceGroup().location

@description('Tags communs')
@param tags object = {}

var storageName = 'stparam${uniqueString(resourceGroup().id)}'

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageName
  location: location
  tags: tags
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

output storageName string = storageName
output storageId string = storageAccount.id

Ajoute @param validés (min/max pour size), @tags et output pour consommer ailleurs. var calcule le nom une fois. Déployez avec --parameters @{sizeInGb=10;tags={env='dev'}} ; piège : oubliez pas @minValue pour sécurité en prod.

Déploiement paramétré

deploy-params.sh
az deployment group create \
  --resource-group rg-bicep-demo \
  --template-file storage-params.bicep \
  --parameters sizeInGb=10 tags='{"env":"dev","costcenter":"team1"}' \
  --query properties.outputs.storageName.value -o tsv

Passe des paramètres JSON-like et query l'output storageName. Utile en pipelines GitHub Actions. Évitez les quotes imbriquées en utilisant un fichier params.json ; validez avec bicep build avant.

Modules pour modularité avancée

Séparez en modules réutilisables (comme composants React). Créez un module VNet, importez-le. Idéal pour microservices ou multi-env.

Module VNet réutilisable

vnet.bicep
@description('Préfixe adresse')
@param vnetNamePrefix string
@param addressPrefix string = '10.0.0.0/16'
@param subnetPrefix string = '10.0.1.0/24'

resource vnet 'Microsoft.Network/virtualNetworks@2023-05-01' = {
  name: '${vnetNamePrefix}vnet'
  location: resourceGroup().location
  properties: {
    addressSpace: {
      addressPrefixes: [addressPrefix]
    }
    subnets: [
      {
        name: 'default'
        properties: {
          addressPrefix: subnetPrefix
        }
      }
    ]
  }
}

output vnetId string = vnet.id
output subnetId string = vnet.subnets[0].id

Module autonome avec params flexibles et outputs. Déployez standalone ou importez. Analogie : fonction pure avec return ; testez avec az deployment group what-if pour preview sans coût.

Main avec module VNet et boucle

main-module.bicep
module vnetModule './vnet.bicep' = {
  name: 'vnetDeployment'
  params: {
    vnetNamePrefix: 'demo'
    addressPrefix: '10.1.0.0/16'
    subnetPrefix: '10.1.1.0/24'
  }
}

// Boucle pour plusieurs subnets
@batchSize(2)
resource additionalSubnets 'Microsoft.Network/virtualNetworks/subnets@2023-05-01' = [for i in range(0, 3): {
  name: 'subnet-${i}'
  parent: vnetModule
  properties: {
    addressPrefix: '10.1.${i+2}.0/24'
  }
}]

module importe comme un sous-déploiement. Boucle for avec @batchSize parallélise (évite timeouts). parent référence le module output ; piège : scope outputs limités au module.

Déploiement modulaire complet

deploy-module.sh
bicep build --file main-module.bicep
az deployment group create \
  --resource-group rg-bicep-demo \
  --template-file main-module.bicep \
  --what-if

bicep build compile en JSON pour debug. --what-if simule sans déployer (dry-run pro). Utile en PR GitHub ; supprimez RG à la fin avec az group delete -g rg-bicep-demo --yes.

Bonnes pratiques

  • Modularisez toujours : un fichier main.bicep max 400 lignes, modules par ressource.
  • Utilisez what-if et bicep build en CI/CD pour validation.
  • Sécurisez secrets avec @secure() et Key Vault references (vaultUri).
  • Tags systématiques : { 'managedBy': 'bicep', 'env': param('environment') }.
  • Outputs explicites : référencez-les dans pipelines Azure DevOps.

Erreurs courantes à éviter

  • Noms non uniques : storage/VM noms globaux → collision ; utilisez toujours uniqueString(rg.id).
  • Régions incohérentes : mélangez pas westeurope/francecentral → peering VNet KO.
  • Oubli @batchSize dans boucles : timeouts sur >10 itérations.
  • Pas de dependsOn : ordre déploie faux (ex: NSG avant VNet) → utilisez reference() implicite.

Pour aller plus loin