Projet Pratique

DataShop Analytics - CI/CD avec Azure DevOps

Projet Unifie : DataShop Analytics

Automatisez le déploiement de l'infrastructure DataShop avec Azure DevOps. Ce module couvre la création de pipelines CI/CD pour déployer l'infrastructure Azure via Bicep.

Durée estimée : 60-90 minutes | Coût : Gratuit (Azure DevOps Free Tier)

Objectifs de ce module

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

  1. Allez sur dev.azure.com
  2. Connectez-vous avec votre compte Microsoft
  3. Cliquez sur "New organization"
  4. Nom de l'organisation : datashop-training (ou votre choix)
  5. Region : West Europe
  6. 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

  1. Dans votre organisation, cliquez "+ New project"
  2. Configurez :
    • Project name : DataShop-Infrastructure
    • Visibility : Private
    • Version control : Git
    • Work item process : Agile
  3. Cliquez "Create"

3 Initialiser le repository

Créez la structure du projet Infrastructure as Code :

  1. Allez dans Repos > Files
  2. Cliquez "Initialize" avec un README
  3. 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"
    }
  }
}

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

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

6 Configurer la Service Connection

Connectez Azure DevOps à votre subscription Azure :

  1. Allez dans Project Settings (en bas à gauche)
  2. Section Pipelines > Service connections
  3. Cliquez "New service connection"
  4. Sélectionnez "Azure Resource Manager"
  5. Choisissez "Service principal (automatic)"
  6. Configurez :
    • Scope level : Subscription
    • Subscription : Votre subscription Azure
    • Resource group : Laissez vide (acces a toute la subscription)
    • Service connection name : Azure-DataShop-Connection
  7. Cochez "Grant access permission to all pipelines"
  8. 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.

7 Créer et exécuter le pipeline

  1. Allez dans Pipelines > Pipelines
  2. Cliquez "New pipeline"
  3. Sélectionnez "Azure Repos Git"
  4. Sélectionnez votre repository
  5. Sélectionnez "Existing Azure Pipelines YAML file"
  6. Path : /pipelines/ci-validate.yml
  7. 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 :

  1. Allez dans Pipelines > Environments
  2. Cliquez sur "datashop-dev" (créé automatiquement)
  3. Cliquez sur "..." > "Approvals and checks"
  4. Cliquez "+ Add" > "Approvals"
  5. Ajoutez-vous comme approbateur
  6. 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

Prochaine étape

CI/CD en place ! Continuez avec MongoDB pour la base de données produits.

Module suivant : MongoDB - Pratique →