Durée estimée : 60-90 minutes | Coût : Gratuit (Azure DevOps Free Tier)
Objectifs de ce module
- Créer une organisation Azure DevOps
- Créer un projet et un repository Git
- Écrire des templates Bicep pour l'infrastructure
- Configurer un pipeline CI pour valider le code
- Configurer un pipeline CD pour déployer
Théorie associée :
Module 1 - Introduction,
Module 3 - Repos,
Module 4 - Pipelines CI,
Module 5 - Pipelines CD
Limites du Free Tier Azure DevOps
- 5 utilisateurs gratuits (Basic license)
- 1 job parallèle Microsoft-hosted : 1800 minutes/mois (~30h)
- 1 job parallèle self-hosted : Minutes illimitées
- Repos Git illimités (privés)
- 2 Go Azure Artifacts
1 Créer une organisation Azure DevOps GRATUIT
- Allez sur dev.azure.com
- Connectez-vous avec votre compte Microsoft
- Cliquez sur "New organization"
- Nom de l'organisation :
datashop-training(ou votre choix) - Region : West Europe
- Cliquez "Continue"
Note pour les nouvelles organisations : Microsoft requiert maintenant une subscription Azure liée. Si on vous le demande, associez votre subscription gratuite.
2 Créer le projet DataShop
- Dans votre organisation, cliquez "+ New project"
- Configurez :
- Project name :
DataShop-Infrastructure - Visibility : Private
- Version control : Git
- Work item process : Agile
- Project name :
- Cliquez "Create"
3 Initialiser le repository
Créez la structure du projet Infrastructure as Code :
- Allez dans Repos > Files
- Cliquez "Initialize" avec un README
- Créez l'arborescence suivante :
datashop-infrastructure/
├── infra/
│ ├── main.bicep
│ ├── storage.bicep
│ └── parameters.dev.json
├── pipelines/
│ ├── ci-validate.yml
│ └── cd-deploy.yml
└── README.md
Créer main.bicep :
Repos > Files > New > File > infra/main.bicep
// main.bicep - Infrastructure principale DataShop
targetScope = 'resourceGroup'
@description('Environment name')
@allowed(['dev', 'staging', 'prod'])
param environment string = 'dev'
@description('Azure region')
param location string = resourceGroup().location
@description('Project name')
param projectName string = 'datashop'
// Variables
var suffix = '${projectName}-${environment}-weu-001'
var storageAccountName = replace('st${suffix}', '-', '')
// Storage Account Module
module storage 'storage.bicep' = {
name: 'storage-deployment'
params: {
storageAccountName: storageAccountName
location: location
environment: environment
projectName: projectName
}
}
// Outputs
output storageAccountName string = storage.outputs.storageAccountName
output storageAccountId string = storage.outputs.storageAccountId
output dataLakeEndpoint string = storage.outputs.dfsEndpoint
Créer storage.bicep :
Repos > Files > New > File > infra/storage.bicep
// storage.bicep - Storage Account avec Data Lake Gen2
@description('Storage Account name')
param storageAccountName string
@description('Location')
param location string
@description('Environment')
param environment string
@description('Project name')
param projectName string
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
isHnsEnabled: true // Enable Data Lake Gen2
accessTier: 'Hot'
minimumTlsVersion: 'TLS1_2'
allowBlobPublicAccess: false
}
tags: {
Project: projectName
Environment: environment
ManagedBy: 'Bicep'
}
}
// Containers
resource rawContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {
name: '${storageAccount.name}/default/raw'
}
resource processedContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {
name: '${storageAccount.name}/default/processed'
}
resource curatedContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-01-01' = {
name: '${storageAccount.name}/default/curated'
}
// Outputs
output storageAccountName string = storageAccount.name
output storageAccountId string = storageAccount.id
output dfsEndpoint string = storageAccount.properties.primaryEndpoints.dfs
Créer parameters.dev.json :
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"value": "dev"
},
"projectName": {
"value": "datashop"
}
}
}
Voir la théorie : Module 3 - Azure Repos et Git
4 Créer le pipeline CI (validation)
Ce pipeline valide le code Bicep à chaque push.
Créer pipelines/ci-validate.yml :
# ci-validate.yml - Pipeline de validation
trigger:
branches:
include:
- main
- feature/*
paths:
include:
- infra/**
pool:
vmImage: 'ubuntu-latest'
variables:
- name: resourceGroupName
value: 'rg-datashop-dev-weu-001'
- name: location
value: 'westeurope'
stages:
- stage: Validate
displayName: 'Validate Bicep'
jobs:
- job: ValidateBicep
displayName: 'Lint and Validate'
steps:
- task: AzureCLI@2
displayName: 'Install Bicep'
inputs:
azureSubscription: 'Azure-DataShop-Connection'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az bicep install
az bicep version
- task: AzureCLI@2
displayName: 'Bicep Build (Lint)'
inputs:
azureSubscription: 'Azure-DataShop-Connection'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az bicep build --file infra/main.bicep
- task: AzureCLI@2
displayName: 'What-If Deployment'
inputs:
azureSubscription: 'Azure-DataShop-Connection'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group what-if --resource-group $(resourceGroupName) --template-file infra/main.bicep --parameters infra/parameters.dev.json
Version Bash (cliquez pour afficher)
# ci-validate.yml - Pipeline de validation (Bash)
- task: AzureCLI@2
displayName: 'What-If Deployment'
inputs:
azureSubscription: 'Azure-DataShop-Connection'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group what-if \
--resource-group $(resourceGroupName) \
--template-file infra/main.bicep \
--parameters infra/parameters.dev.json
Voir la théorie : Module 4 - Pipelines CI
5 Créer le pipeline CD (déploiement)
Créer pipelines/cd-deploy.yml :
# cd-deploy.yml - Pipeline de déploiement
trigger: none # Déclenchement manuel ou après CI
pool:
vmImage: 'ubuntu-latest'
variables:
- name: resourceGroupName
value: 'rg-datashop-dev-weu-001'
- name: location
value: 'westeurope'
stages:
- stage: Deploy_Dev
displayName: 'Deploy to Dev'
jobs:
- deployment: DeployInfra
displayName: 'Deploy Infrastructure'
environment: 'datashop-dev'
strategy:
runOnce:
deploy:
steps:
- checkout: self
- task: AzureCLI@2
displayName: 'Deploy Bicep'
inputs:
azureSubscription: 'Azure-DataShop-Connection'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
# Créer le Resource Group si nécessaire
az group create --name $(resourceGroupName) --location $(location) --tags Project=DataShop Environment=Dev
# Déployer l'infrastructure
az deployment group create --resource-group $(resourceGroupName) --template-file infra/main.bicep --parameters infra/parameters.dev.json --name "datashop-$(Build.BuildId)"
- task: AzureCLI@2
displayName: 'Show Outputs'
inputs:
azureSubscription: 'Azure-DataShop-Connection'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group show --resource-group $(resourceGroupName) --name "datashop-$(Build.BuildId)" --query properties.outputs
Version Bash (cliquez pour afficher)
# cd-deploy.yml - Pipeline de déploiement (Bash)
- task: AzureCLI@2
displayName: 'Deploy Bicep'
inputs:
azureSubscription: 'Azure-DataShop-Connection'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
# Créer le Resource Group si nécessaire
az group create \
--name $(resourceGroupName) \
--location $(location) \
--tags Project=DataShop Environment=Dev
# Déployer l'infrastructure
az deployment group create \
--resource-group $(resourceGroupName) \
--template-file infra/main.bicep \
--parameters infra/parameters.dev.json \
--name "datashop-$(Build.BuildId)"
- task: AzureCLI@2
displayName: 'Show Outputs'
inputs:
azureSubscription: 'Azure-DataShop-Connection'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group show \
--resource-group $(resourceGroupName) \
--name "datashop-$(Build.BuildId)" \
--query properties.outputs
Voir la théorie : Module 5 - Pipelines CD
6 Configurer la Service Connection
Connectez Azure DevOps à votre subscription Azure :
- Allez dans Project Settings (en bas à gauche)
- Section Pipelines > Service connections
- Cliquez "New service connection"
- Sélectionnez "Azure Resource Manager"
- Choisissez "Service principal (automatic)"
- Configurez :
- Scope level : Subscription
- Subscription : Votre subscription Azure
- Resource group : Laissez vide (acces a toute la subscription)
- Service connection name :
Azure-DataShop-Connection
- Cochez "Grant access permission to all pipelines"
- Cliquez "Save"
Que se passe-t-il ? Azure DevOps crée automatiquement un Service Principal dans Azure AD avec les permissions nécessaires pour déployer dans votre subscription.
Voir la théorie : Module 7 - Service Connections et Sécurité
7 Créer et exécuter le pipeline
- Allez dans Pipelines > Pipelines
- Cliquez "New pipeline"
- Sélectionnez "Azure Repos Git"
- Sélectionnez votre repository
- Sélectionnez "Existing Azure Pipelines YAML file"
- Path :
/pipelines/ci-validate.yml - Cliquez "Run"
Répétez pour cd-deploy.yml.
Premier run : Le premier run peut nécessiter une approbation pour utiliser la Service Connection. Allez dans le run et approuvez l'accès.
8 Créer un environnement avec approbation
Ajoutez une approbation manuelle avant le déploiement :
- Allez dans Pipelines > Environments
- Cliquez sur "datashop-dev" (créé automatiquement)
- Cliquez sur "..." > "Approvals and checks"
- Cliquez "+ Add" > "Approvals"
- Ajoutez-vous comme approbateur
- Cliquez "Create"
Maintenant, chaque déploiement dans cet environnement nécessitera votre approbation.
Vérification - Cochez quand terminé
Ressources créées
| Ressource | Nom | Coût |
|---|---|---|
| Organisation DevOps | datashop-training |
Gratuit |
| Projet | DataShop-Infrastructure |
Gratuit |
| Pipeline CI | ci-validate |
1800 min/mois gratuit |
| Pipeline CD | cd-deploy |
1800 min/mois gratuit |