Partager via


Comment créer des ressources à grande échelle à l’aide d’Azure CLI

En tant que gestionnaire de ressources Azure, vous devez souvent créer plusieurs ressources Azure lors de la configuration de nouveaux environnements. Vous pouvez également disposer d’un processus d’approbation des ressources Azure qui fonctionne le mieux lorsque les ressources Azure sont créées automatiquement à partir d’un script.

Dans cet article, vous allez découvrir les éléments suivants :

  • Créez plusieurs ressources Azure à partir de paramètres reçus à partir d’un fichier CSV délimité.
  • Utilisez IF.. Instructions THEN pour créer des ressources Azure dépendantes.
  • Progression du script de journal dans un fichier TXT local.

Cet exemple de script a été testé dans Azure Cloud Shell dans les environnements Bash et PowerShell et PowerShell 7. Recherchez le script CSV et complet dans Azure-samples/azure-cli-samples.

Préparation de votre environnement

Procédez comme suit pour préparer votre environnement pour exécuter l’exemple de script :

  • Ouvrez l’environnement Bash ou PowerShell dans Azure Cloud Shell. Pour plus d’informations, consultez Démarrage rapide pour Bash dans Azure Cloud Shell.

  • Téléchargez et enregistrez dans un répertoire local le fichier CSV suivant. Remplacez myExistingResourceGroupName la ligne 3 par un nom de groupe de ressources réel.

    resourceNo,location,createRG,exstingRgName,createVnet,vnetAddressPrefix,subnetAddressPrefixes,vmImage,publicIpSku,Adminuser
    1,eastus,TRUE,,TRUE,10.0.0.0/16,10.0.0.0/24,Ubuntu2204,standard,
    2,eastus2,TRUE,,FALSE,,,Debian11,standard,alex-smith
    3,southcentralus,FALSE,myExistingResourceGroupName,FALSE,,,Ubuntu2204,standard,jan-smith
    [empty line for Bash]
    

    Remarque

    Pour être un fichier texte Unix approprié et lire par Bash, le fichier CSV a besoin d’un caractère de ligne à la fin de la dernière ligne de données. Cela entraîne une ligne vide à la fin du fichier. Votre ligne vide n’a pas besoin de dire [empty line] que ce texte n’est fourni que pour vous montrer qu’une ligne vide existe. Les environnements PowerShell n’ont pas cette exigence de caractère de ligne de ligne.

  • Chargez votre fichier CSV modifié dans votre compte de stockage de blog Azure Cloud Shell. La méthode la plus simple consiste à utiliser la liste déroulante Gérer les fichiers dans le menu principal d’Azure Cloud Shell. Pour plus d’informations sur le stockage Cloud Shell, consultez Conserver les fichiers dans Azure Cloud Shell.

Vue d’ensemble du script

Cet article décompose un seul script volumineux en quatre sections afin que chaque étape puisse être expliquée.

  • Configuration des variables
  • Validation des données
  • Validation de boucle
  • Création de ressources Azure

Il existe également deux scripts fournis : un pour Bash et le deuxième pour PowerShell. Les deux scripts utilisent les mêmes commandes Azure CLI. Il s’agit de l’environnement, ou du profil de terminal, qui est différent. Par exemple, Bash utilise do...done et if...then...fi. Dans un environnement PowerShell, vous utilisez l’équivalent foreach et if (something is true)...{do this}. Dans Azure Cloud Shell, vous pouvez basculer entre les environnements à l’aide du bouton Basculer vers PowerShell ou Basculer vers Bash dans le menu principal d’Azure Cloud Shell.

Si vous préférez, accédez directement aux fichiers CSV et de script utilisés par cet article dans Azure-samples/azure-cli-samples.

Définition des variables

Commencez par créer les variables nécessaires au script. Les trois variables suivantes ont besoin de valeurs réelles pour votre environnement :

  • subscriptionID : il s’agit de votre ID d’abonnement Azure.
  • csvFileLocation : il s’agit de l’emplacement et du nom de fichier de votre fichier d’entrée CSV.
  • logFileLocation : il s’agit de l’emplacement et du nom de fichier que le script utilisera pour créer un fichier journal. Vous n’avez pas besoin de créer ou de charger ce fichier.

Les variables avec un msdocs- préfixe peuvent être remplacées par le préfixe de votre choix. Toutes les variables vides ("") utilisent des valeurs du fichier d’entrée CSV. Ces variables vides sont des espaces réservés nécessaires par le script.

# Variable block

# Replace these three variable values with actual values
subscriptionID=00000000-0000-0000-0000-00000000
csvFileLocation="myFilePath\myFileName.csv"
logFileLocation="myFilePath\myLogName.txt"

# Variable values that contain a prefix can be replaced with the prefix of your choice.
#   These prefixes have a random ID appended to them in the script.
# Variable values without a prefix will be overwritten by the contents of your CSV file.
location=""
createRG=""
newRgName="msdocs-rg-"
existingRgName=""

createVnet=""
vnetName="msdocs-vnet-"
subnetName="msdocs-subnet-"
vnetAddressPrefix=""
subnetAddressPrefixes=""

vmName="msdocs-vm-"
vmImage=""
publicIpSku=""
adminUser=""
adminPassword="msdocs-PW-@"

# Set your Azure subscription 
az account set --subscription $subscriptionID

Valider les valeurs de fichier CSV

Avant de commencer à tester le script de création, vérifiez que votre fichier CSV est correctement mis en forme et que les variables sont affectées à des valeurs correctes. Ce script utilise une if.. Instruction THEN pour vous permettre d’examiner une ligne de scénario/CSV à la fois.

# Verify CSV columns are being read correctly

# Take a look at the CSV contents
cat $csvFileLocation

# Validate select CSV row values
while IFS=, read -r resourceNo location createRG existingRgName createVnet vnetAddressPrefix subnetAddressPrefixes vmImage publicIpSku adminUser
do
  # Generate a random ID
  let "randomIdentifier=$RANDOM*$RANDOM"

  # Return the values for the first data row
  # Change the $resourceNo to check different scenarios in your CSV
  if [ "$resourceNo" = "1" ]; then
    echo "resourceNo = $resourceNo"
    echo "location = $location"
    echo "randomIdentifier = $randomIdentifier"
    echo ""
    
    echo "RESOURCE GROUP INFORMATION:"
    echo "createRG = $createRG"
    if [ "$createRG" = "TRUE" ]; then 
      echo "newRGName = $newRgName$randomIdentifier"
    else
      echo "exsitingRgName = $existingRgName"
    fi
    echo ""

    echo "VNET INFORMATION:"
    echo "createVnet = $createVnet"
    if [ "$createVnet" = "TRUE" ]; then 
      echo "vnetName = $vnetName$randomIdentifier"
      echo "subnetName = $subnetName$randomIdentifier"
      echo "vnetAddressPrefix = $vnetAddressPrefix"
      echo "subnetAddressPrefixes = $subnetAddressPrefixes"
    fi
    echo ""

    echo "VM INFORMATION:"
    echo "vmName = $vmName$randomIdentifier"
    echo "vmImage = $vmImage"
    echo "vmSku = $publicIpSku"
    if [ `expr length "$adminUser"` == "1" ]; then
      echo "SSH keys will be generated."
    else
      echo "vmAdminUser = $adminUser"
      echo "vmAdminPassword = $adminPassword$randomIdentifier"        
    fi
  fi  
# skip the header line
done < <(tail -n +2 $csvFileLocation)

À l’aide du fichier CSV fourni dans cet article, la sortie de validation est la suivante : (L’ID 00000001 aléatoire sera différent pour chaque test.)

resourceNo = 1
location = eastus

RESOURCE GROUP INFORMATION:
createRG = TRUE
newRGName = msdocs-rg-00000001

VNET INFORMATION:
createVnet = TRUE
vnetName = msdocs-vnet-00000001
subnetName = msdocs-subnet-00000001
vnetAddressPrefix = 10.0.0.0/16
subnetAddressPrefix = 10.0.0.0/24

VM INFORMATION:
vmName = msdocs-vm-00000001
vmImage = Ubuntu2204
vmSku = standard
SSH keys will be created

Valider la logique de script

Si vous êtes confiant dans vos capacités de script, vous pouvez ignorer cette étape. Toutefois, étant donné que ce script est conçu pour créer des ressources Azure à grande échelle, la boucle dans le script avec echo ou write-host les instructions peut vous faire gagner du temps et des ressources Azure facturables inattendues.

Il existe plusieurs façons d’effectuer une itération via un fichier CSV à l’aide de Bash. Cet exemple utilise IFS avec un while loop.

# Validate script logic

# Create the log file
echo "SCRIPT LOGIC VALIDATION.">$logFileLocation

# Loop through each row in the CSV file
while IFS=, read -r resourceNo location createRG existingRgName createVnet vnetAddressPrefix subnetAddressPrefixes vmImage publicIpSku adminUser
do
  # Generate a random ID
  let "randomIdentifier=$RANDOM*$RANDOM"
    
  # Log resource number and random ID
  echo "resourceNo = $resourceNo">>$logFileLocation
  echo "randomIdentifier = $randomIdentifier">>$logFileLocation

  # Check if a new resource group should be created
  if [ "$createRG" == "TRUE" ]; then
    echo "Will create RG $newRgName$randomIdentifier.">>$logFileLocation
    existingRgName=$newRgName$randomIdentifier
  fi

  # Check if a new virtual network should be created, then create the VM
  if [ "$createVnet" == "TRUE" ]; then
    echo "Will create VNet $vnetName$randomIdentifier in RG $existingRgName.">>$logFileLocation
    echo "Will create VM $vmName$randomIdentifier in Vnet $vnetName$randomIdentifier in RG $existingRgName.">>$logFileLocation
  else
    echo "Will create VM $vmName$randomIdentifier in RG $existingRgName.">>$logFileLocation
  fi
# Skip the header line.
done < <(tail -n +2 $csvFileLocation)

# Clear the console and display the log file
Clear
cat $logFileLocation

À l’aide du fichier CSV fourni dans cet article, la sortie de validation est la suivante : (Les 00000001, 2, 3 ID aléatoires seront différents pour chaque test, mais chaque ressource sous chacune resourceNo doit partager le même ID aléatoire.)

resourceNo = 1
createRG = TRUE
createVnet = TRUE
Will create RG msdocs-rg-00000001
Will create VNet msdocs-vnet-00000001 in RG msdocs-rg-00000001
Will create VM msdocs-vm-00000001 within Vnet msdocs-vnet-00000001 in RG msdocs-rg-00000001

resourceNo = 2
createRG = TRUE
createVnet = FALSE
Will create RG msdocs-rg-00000002
Will create VM msdocs-vm-00000002 without Vnet in RG msdocs-rg-00000002

resourceNo = 3
createRG = FALSE
createVnet = FALSE
Will create VM msdocs-vm-00000003 without Vnet in RG <myExistingResourceGroup>

Créer des ressources Azure

Vous avez maintenant créé votre bloc de variables, validé vos valeurs CSV et terminé une exécution de test avec echo ou write-host. Exécutez la quatrième et dernière partie du script pour créer des ressources Azure comme défini dans votre fichier d’entrée CSV.

# Create Azure resources

# Create the log file
echo "CREATE AZURE RESOURCES.">$logFileLocation

# Loop through each CSV row
while IFS=, read -r resourceNo location createRG existingRgName createVnet vnetAddressPrefix subnetAddressPrefixes vmImage publicIpSku adminUser
do
  # Generate a random ID
  let "randomIdentifier=$RANDOM*$RANDOM"

  # Log resource number, random ID and display start time
  echo "resourceNo = $resourceNo">>$logFileLocation
  echo "randomIdentifier = $randomIdentifier">>$logFileLocation
  echo "Starting creation of resourceNo $resourceNo at $(date +"%Y-%m-%d %T")."

  # Check if a new resource group should be created
  if [ "$createRG" == "TRUE" ]; then
    echo "Creating RG $newRgName$randomIdentifier at $(date +"%Y-%m-%d %T").">>$logFileLocation
    az group create --location $location --name $newRgName$randomIdentifier >>$logFileLocation
    existingRgName=$newRgName$randomIdentifier
    echo "  RG $newRgName$randomIdentifier creation complete"
  fi

  # Check if a new virtual network should be created, then create the VM
  if [ "$createVnet" == "TRUE" ]; then
    echo "Creating VNet $vnetName$randomIdentifier in RG $existingRgName at $(date +"%Y-%m-%d %T").">>$logFileLocation
    az network vnet create \
        --name $vnetName$randomIdentifier \
        --resource-group $existingRgName \
        --address-prefix $vnetAddressPrefix \
        --subnet-name $subnetName$randomIdentifier \
        --subnet-prefixes $subnetAddressPrefixes >>$logFileLocation
    echo "  VNet $vnetName$randomIdentifier creation complete"
    
    echo "Creating VM $vmName$randomIdentifier in Vnet $vnetName$randomIdentifier in RG $existingRgName at $(date +"%Y-%m-%d %T").">>$logFileLocation
    az vm create \
        --resource-group $existingRgName \
        --name $vmName$randomIdentifier \
        --image $vmImage \
        --vnet-name $vnetName$randomIdentifier \
        --subnet $subnetName$randomIdentifier \
        --public-ip-sku $publicIpSku \
        --generate-ssh-keys >>$logFileLocation
    echo "  VM $vmName$randomIdentifier creation complete"
  else
    echo "Creating VM $vmName$randomIdentifier in RG $existingRgName at $(date +"%Y-%m-%d %T").">>$logFileLocation
    az vm create \
        --resource-group $existingRgName \
        --name $vmName$randomIdentifier \
        --image $vmImage \
        --public-ip-sku $publicIpSku \
        --admin-username $adminUser\
        --admin-password $adminPassword$randomIdentifier >>$logFileLocation
    echo "  VM $vmName$randomIdentifier creation complete"    
  fi
# skip the header line
done < <(tail -n +2 $csvFileLocation)

# Clear the console (optional) and display the log file
# clear
cat $logFileLocation

Dans la sortie de votre console, manquez-vous la dernière ligne de votre fichier CSV ? Cela peut être dû à un caractère de continuation de ligne manquant après la dernière ligne. Ajoutez une ligne vide à la fin de votre fichier CSV pour résoudre le problème.

Sortie de la console avant lecture du fichier journal :

Starting creation of resourceNo 1 at YYYY-MM-DD HH:MM:SS.
  RG msdocs-rg-00000001 creation complete
  VNet msdocs-vnet-00000001 creation complete
  VM msdocs-vm-00000001 creation complete

Starting creation of resourceNo 2 at YYYY-MM-DD HH:MM:SS.
  RG msdocs-rg-00000002 creation complete
  VM msdocs-vm-00000002 creation complete

Starting creation of resourceNo 3 at YYYY-MM-DD HH:MM:SS.
  VM msdocs-vm-00000003 creation complete

Le contenu de votre fichier journal doit ressembler à ceci :

Starting creation of resourceNo 1 at YYYY-MM-DD HH:MM:SS.
  Creating RG msdocs-rg-00000001 at YYYY-MM-DD HH:MM:SS.
  {
  Resource group create output
  }
  Creating VNet msdocs-vnet-00000001 in RG msdocs-rg-000000001 at YYYY-MM-DD HH:MM:SS.
  {
  VNet create output
  }  
  Creating VM msdocs-vm-00000001 in RG msdocs-rg-00000001 at YYYY-MM-DD HH:MM:SS.
  {
  VM create output
  }

Starting creation of resourceNo 2 at YYYY-MM-DD HH:MM:SS.
  Creating RG msdocs-rg-00000002 at YYYY-MM-DD HH:MM:SS.
  {
  Resource group create output
  }
  Creating VM msdocs-vm-00000002 in RG msdocs-rg-00000002 at YYYY-MM-DD HH:MM:SS.
  {
  VM create output
  }

Starting creation of resourceNo 3 at YYYY-MM-DD HH:MM:SS.
  Creating msdocs-vm-00000003 creation complete
  {
  VM create output
  }

Dépannage

Dans Bash, l’étape « Créer des ressources Azure » s’arrête après l’étape 1

Dans Ubuntu 22.04.3 LTS et Debian version 12 (bookworm), la logique de script Validate fonctionne comme un retour attendu des résultats pour les trois ressources. Toutefois, la création de ressources Azure s’arrête après la première ressource. Une raison possible de ce problème est que la création du réseau virtuel à l’étape 1 prend quelques secondes. Ubuntu et Debian passent à la deuxième ressource sans attendre la fin du réseau virtuel. Vous pouvez en savoir plus sur ce problème en attente n’attend pas que les processus de la boucle While se terminent ou attendent la fin d’un processus dans le script bash.

Le script Bash ignore l’instruction IF

Bash respecte la casse. Le mot true n’est pas égal TRUEà . Est également greater than , pas >, et equals est ==, pas =.-gt Assurez-vous que vous n’avez pas d’erreur typographique ou d’espaces de début/fin dans vos valeurs de colonne CSV.

Les valeurs de variable ne changent pas avec chaque boucle

Cela est souvent dû à des espaces supplémentaires dans le fichier CSV. Une ligne d’un fichier CSV ressemble à ceci : column1,column2,column3 ou column1,,column3, par habitude, il est facile de créer un fichier de test qui contient un espace après chaque virgule comme column1, column2, column3. Lorsque vous disposez d’un espace de début ou de fin dans votre fichier CSV, la valeur de colonne est en fait <space>columnValue. La logique if [ "$columnName" = "columnValue" ] de script retourne « false ». Supprimez tous les espaces de début et de fin dans vos lignes CSV pour résoudre le problème.

Notation CIDR non valide

Vous recevez une erreur InvalidCIDRNotation lorsque vous transmettez un préfixe d’adresse incorrect à az network vnet create. Cela peut être difficile quand visuellement, le préfixe d’adresse semble correct lorsqu’il est retourné dans une echo instruction. Pour résoudre les problèmes de lecture de la valeur réelle à partir du csv, essayez ce script :

while IFS=, read -r resourceNo location createRG existingRgName createVnet vnetAddressPrefix subnetAddressPrefixes vmImage publicIpSku adminUser
do
    echo "resourceNo = $resourceNo"

    if [ "$createVnet" == "TRUE" ]; then
      startTest="abc"
      endTest="xyz"
      echo $startTest$vnetAddressPrefix$endTest
    fi
done < <(tail -n +2 $setupFileLocation)

Si vos résultats ressemblent xzy10.0.0.0 à ceux attendus abc10.0.0.0/24xyz, il peut y avoir un caractère masqué ou des virgules supplémentaires dans votre fichier CSV. Ajoutez une colonne de test avec la même valeur de préfixe, réorganisez vos colonnes CSV et copiez/collez votre contenu CSV dans/hors d’un éditeur simple du Bloc-notes. Dans l’écriture de cet article, la réorganisation des colonnes CSV a finalement résolu l’erreur.

Les arguments sont attendus ou obligatoires

Vous recevez cette erreur lorsque vous n’avez pas fourni de paramètre requis ou qu’une erreur typographique entraîne l’analyse incorrecte de la commande de référence par Azure CLI. Lorsque vous utilisez un script, vous recevez également cette erreur lorsque l’un des éléments suivants est vrai :

  • Il existe un caractère de continuation de ligne manquant ou incorrect.
  • Il existe des espaces de fin sur le côté droit d’un caractère de continuation de ligne.
  • Votre nom de variable contient un caractère spécial, tel qu’un tiret (-).

InvalidTemplateDeployment

Lorsque vous essayez de créer une ressource Azure dans un emplacement qui ne propose pas cette ressource, vous recevez une erreur similaire à ce qui suit : « Les références SKU suivantes ont échoué pour les restrictions de capacité : Standard_DS1_v2 » n’est actuellement pas disponible à l’emplacement « westus ».

Voici l’exemple d’erreur complet :

{"error":{"code":"InvalidTemplateDeployment","message":"The template deployment 'vm_deploy_<32 character ID>'
is not valid according to the validation procedure. The tracking id is '<36 character ID>'.
See inner errors for details.","details":[{"code":"SkuNotAvailable","message":"The requested VM size for resource
'Following SKUs have failed for Capacity Restrictions: Standard_DS1_v2' is currently not available
in location '<your specified location>'. Please try another size or deploy to a different location
or different zone. See https://aka.ms/azureskunotavailable for details."}]}}

Pour corriger l’erreur, modifiez l’emplacement ou sélectionnez une valeur de paramètre différente qui est proposée pour votre emplacement souhaité.

Voir aussi