Bonjour,
Cloner ou copier un pipeline CI/CD dans Azure DevOps est une opération très utile pour éviter de recréer des configurations complexes depuis zéro. Que vous souhaitiez dupliquer un pipeline au sein du même projet ou le copier vers un autre projet ou organisation, plusieurs méthodes sont à votre disposition. Je vais vous présenter toutes les approches, de la plus simple à la plus avancée.
Vue d’ensemble des options disponibles
| Méthode |
Complexité |
Fidélité |
Idéal pour |
| Clone via l’interface graphique |
Très facile |
Haute |
Même projet |
| Export/Import YAML |
Facile |
Complète |
Entre projets/organisations |
| Azure DevOps CLI |
Moyenne |
Complète |
Automatisation, scripts |
| API REST Azure DevOps |
Avancée |
Complète |
Intégration programmatique |
| Pipeline as Code (YAML) |
Bonne pratique |
Réutilisable |
Tous cas de figure |
Méthode 1 : Cloner via l’interface graphique (le plus simple)
Pour les pipelines classiques (interface graphique)
Azure DevOps offre une fonctionnalité native de clonage pour les pipelines Classic :
- Naviguez vers Pipelines > Pipelines dans votre projet Azure DevOps
- Trouvez le pipeline que vous souhaitez cloner
- Cliquez sur les trois points (…) à droite du pipeline
- Sélectionnez “Clone” ou “Cloner”
- Le pipeline est dupliqué avec le nom
Copie de [Nom du pipeline]
- Renommez et modifiez la copie selon vos besoins
Note : Cette option est disponible pour les pipelines Classic Build et Classic Release. Pour les pipelines YAML, l’approche est différente (voir méthode 2).
Pour les pipelines Release (CD)
- Allez dans Pipelines > Releases
- Sélectionnez votre pipeline de release
- Cliquez sur le menu “…” > “Clone”
- La copie est créée dans le même projet
Méthode 2 : Export/Import de pipeline Classic (entre projets)
Pour copier un pipeline vers un autre projet ou une autre organisation :
Export
- Dans le pipeline Classic, cliquez sur les trois points (…) > “Export” ou “Exporter”
- Un fichier JSON est téléchargé sur votre machine
Import
- Dans le projet de destination, allez dans Pipelines > Pipelines
- Cliquez sur “New pipeline” > “Import a pipeline” (ou “Importer un pipeline”)
- Sélectionnez le fichier JSON exporté
- Le pipeline est recréé — vous devrez reconfigurer les connections de service et les agents pools qui diffèrent entre projets
Méthode 3 : Duplication de pipeline YAML (recommandée)
Pour les pipelines YAML (la méthode moderne recommandée), la duplication se fait au niveau du fichier YAML lui-même.
Copier le fichier YAML
# Dans votre dépôt Git
cp azure-pipelines.yml azure-pipelines-nouveau.yml
Créer un nouveau pipeline pointant vers le nouveau fichier
- Allez dans Pipelines > New pipeline
- Sélectionnez votre dépôt
- Choisissez “Existing Azure Pipelines YAML file”
- Sélectionnez le fichier
azure-pipelines-nouveau.yml
- Configurez les variables et triggers selon vos besoins
Utiliser les templates YAML pour éviter la duplication
La vraie bonne pratique est d’utiliser les templates YAML pour partager des configurations entre pipelines :
# templates/build-steps.yml (template réutilisable)
parameters:
- name: buildConfiguration
type: string
default: 'Release'
- name: dotnetVersion
type: string
default: '8.x'
steps:
- task: UseDotNet@2
displayName: 'Installer .NET ${{ parameters.dotnetVersion }}'
inputs:
version: '${{ parameters.dotnetVersion }}'
- task: DotNetCoreCLI@2
displayName: 'Build - ${{ parameters.buildConfiguration }}'
inputs:
command: 'build'
arguments: '--configuration ${{ parameters.buildConfiguration }}'
- task: DotNetCoreCLI@2
displayName: 'Tests unitaires'
inputs:
command: 'test'
arguments: '--configuration ${{ parameters.buildConfiguration }} --collect:"XPlat Code Coverage"'
# azure-pipelines-app1.yml - Pipeline pour l'application 1
trigger:
branches:
include: [main, develop]
paths:
include: ['src/App1/**']
variables:
buildConfiguration: 'Release'
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- template: templates/build-steps.yml
parameters:
buildConfiguration: $(buildConfiguration)
dotnetVersion: '8.x'
# azure-pipelines-app2.yml - Pipeline pour l'application 2 (réutilise le même template)
trigger:
paths:
include: ['src/App2/**']
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- template: templates/build-steps.yml
parameters:
buildConfiguration: 'Debug'
dotnetVersion: '6.x'
Méthode 4 : Azure DevOps CLI
L’Azure DevOps CLI (extension az devops) permet de gérer les pipelines par script.
Installation et configuration
# Installer l'extension Azure DevOps CLI
az extension add --name azure-devops
# Se connecter
az devops configure --defaults organization=https://dev.azure.com/MonOrganisation project=MonProjet
az devops login
Lister et exporter les définitions de pipeline
# Lister tous les pipelines du projet
az pipelines list --output table
# Obtenir la définition JSON d'un pipeline spécifique
az pipelines show --id 42 --output json > pipeline-backup.json
# Ou par nom
az pipelines show --name "MonPipeline" --output json > pipeline-backup.json
Créer un pipeline depuis une définition YAML
# Créer un nouveau pipeline YAML
az pipelines create \
--name "MonPipeline-Copie" \
--repository "MonRepo" \
--branch "main" \
--yml-path "azure-pipelines-copie.yml" \
--repository-type tfsgit
# Créer dans un autre projet
az pipelines create \
--name "MonPipeline-Copie" \
--repository "MonRepo" \
--branch "main" \
--yml-path "azure-pipelines.yml" \
--organization "https://dev.azure.com/AutreOrganisation" \
--project "AutreProjet"
Script de copie automatisée
#!/bin/bash
# Script pour copier un pipeline entre projets
SOURCE_ORG="https://dev.azure.com/SourceOrganisation"
SOURCE_PROJECT="SourceProjet"
DEST_ORG="https://dev.azure.com/DestinationOrganisation"
DEST_PROJECT="DestinationProjet"
PIPELINE_NAME="MonPipeline"
echo "Récupération de la définition du pipeline source..."
az pipelines show \
--name "$PIPELINE_NAME" \
--organization "$SOURCE_ORG" \
--project "$SOURCE_PROJECT" \
--output json > /tmp/pipeline-definition.json
echo "Le pipeline a été exporté dans /tmp/pipeline-definition.json"
echo "Veuillez adapter les repository, service connections et variables, puis relancer."
Méthode 5 : API REST Azure DevOps
Pour une intégration programmatique complète :
# Script PowerShell pour cloner un pipeline via l'API REST
$organization = "MonOrganisation"
$sourceProject = "SourceProjet"
$destProject = "DestinationProjet"
$pipelineId = 42
$pat = "votre-personal-access-token" # Créez un PAT dans Azure DevOps
$headers = @{
Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat"))
"Content-Type" = "application/json"
}
# Récupérer la définition du pipeline source
$sourceUrl = "https://dev.azure.com/$organization/$sourceProject/_apis/build/definitions/$pipelineId`?api-version=7.1"
$pipelineDef = Invoke-RestMethod -Uri $sourceUrl -Headers $headers -Method Get
# Modifier pour le projet de destination
$pipelineDef.name = "$($pipelineDef.name) - Copie"
$pipelineDef.PSObject.Properties.Remove('id')
$pipelineDef.PSObject.Properties.Remove('revision')
$pipelineDef.PSObject.Properties.Remove('uri')
$pipelineDef.PSObject.Properties.Remove('url')
# Créer dans le projet de destination
$destUrl = "https://dev.azure.com/$organization/$destProject/_apis/build/definitions?api-version=7.1"
$body = $pipelineDef | ConvertTo-Json -Depth 20
$newPipeline = Invoke-RestMethod -Uri $destUrl -Headers $headers -Method Post -Body $body
Write-Output "Pipeline créé avec l'ID : $($newPipeline.id)"
Copier les variables de pipeline
N’oubliez pas que les variables de pipeline et les variables secrètes ne sont pas incluses dans l’export/clone automatique.
# Lister les variables d'un pipeline
az pipelines variable list --pipeline-id 42
# Ajouter une variable au pipeline copié
az pipelines variable create \
--pipeline-id 99 \
--name "MonVariable" \
--value "MaValeur"
# Ajouter une variable secrète
az pipelines variable create \
--pipeline-id 99 \
--name "MonSecret" \
--value "ValeurSecrète" \
--secret true
Copier les environnements et approvals
Si votre pipeline utilise des Environments (pour les approvals et gates) :
# Lister les environnements
az devops invoke \
--area distributedtask \
--resource environments \
--organization https://dev.azure.com/MonOrganisation \
--project MonProjet \
--api-version "7.1"
# Créer un environnement dans le projet de destination
az devops invoke \
--area distributedtask \
--resource environments \
--organization https://dev.azure.com/MonOrganisation \
--project DestinationProjet \
--http-method POST \
--in-file environment-definition.json \
--api-version "7.1"
Bonnes pratiques pour la gestion des pipelines
Structurer vos pipelines pour faciliter la réutilisation
# Utiliser des variable groups partageables
variables:
- group: "Variables-Communes" # Groupe de variables Azure DevOps
- group: "Variables-Environnement-Prod"
- name: buildConfiguration
value: 'Release'
Utiliser des pipeline templates dans un dépôt centralisé
# Référencer un template depuis un autre dépôt
resources:
repositories:
- repository: templates
type: git
name: MonOrganisation/PipelineTemplates
ref: refs/heads/main
stages:
- template: stages/build-and-test.yml@templates
parameters:
buildConfiguration: Release
En résumé, pour une copie rapide dans le même projet, utilisez la fonctionnalité Clone native de l’interface Azure DevOps. Pour copier entre projets ou automatiser la duplication, l’approche YAML avec templates est la plus robuste et maintenable à long terme.
Si vous pouvez préciser votre cas d’usage (pipeline Classic ou YAML, même projet ou migration vers un autre projet/organisation), je pourrai vous fournir une procédure encore plus détaillée adaptée à votre situation spécifique.