Delen via


Resources op schaal maken met behulp van de Azure CLI

Als Azure Resource Manager moet u vaak meerdere Azure-resources maken bij het configureren van nieuwe omgevingen. Mogelijk hebt u ook een goedkeuringsproces voor Azure-resources dat het beste werkt wanneer Azure-resources automatisch worden gemaakt op basis van een script.

In dit artikel leert u het volgende:

  • Maak meerdere Azure-resources op basis van parameters die zijn ontvangen van een csv-bestand met scheidingstekens.
  • Gebruik ALS.. THEN-instructies voor het maken van afhankelijke Azure-resources.
  • Logboekscriptvoortgang naar een lokaal TXT-bestand.

Dit voorbeeldscript is getest in Azure Cloud Shell in zowel Bash- als PowerShell-omgevingen en PowerShell 7. Zoek het CSV-bestand en het volledige script in Azure-samples/azure-cli-samples.

Uw omgeving voorbereiden

Volg deze stappen om uw omgeving voor te bereiden om het voorbeeldscript uit te voeren:

  • Open de Bash- of PowerShell-omgeving in Azure Cloud Shell. Zie quickstart voor Bash in Azure Cloud Shell voor meer informatie.

  • Download en sla het bestand op in een lokale map in het volgende CSV-bestand. Vervang myExistingResourceGroupName in regel drie door een werkelijke resourcegroepnaam.

    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]
    

    Notitie

    Als u een juist Unix-tekstbestand wilt zijn en door Bash wilt worden gelezen, heeft het CSV-bestand een nieuw regelteken nodig aan het einde van de laatste gegevensregel. Dit resulteert in een lege regel aan het einde van het bestand. De lege regel hoeft niet te zeggen [empty line] , omdat deze tekst alleen wordt opgegeven om aan te geven dat er een lege regel bestaat. Voor PowerShell-omgevingen is deze nieuwe tekenvereiste niet vereist.

  • Upload het gewijzigde CSV-bestand naar uw Azure Cloud Shell-blogopslagaccount. De eenvoudigste manier om dit te doen, is door de vervolgkeuzelijst Bestanden beheren te gebruiken in het hoofdmenu van Azure Cloud Shell. Zie Persistent-bestanden in Azure Cloud Shell voor meer informatie over Cloud Shell-opslag.

Scriptoverzicht

In dit artikel wordt één groot script opgesplitst in vier secties, zodat elke stap kan worden uitgelegd.

  • Variabele instellen
  • Gegevensvalidatie
  • Lusvalidatie
  • Azure-resource maken

Er zijn ook twee scripts beschikbaar: één voor Bash en de tweede voor PowerShell. Beide scripts gebruiken dezelfde Azure CLI-opdrachten. Het is de omgeving of het terminalprofiel, dat verschilt. Bash gebruikt do...done bijvoorbeeld en if...then...fi. In een PowerShell-omgeving gebruikt u het equivalent foreach en if (something is true)...{do this}. In Azure Cloud Shell kunt u schakelen tussen omgevingen met behulp van de knop Overschakelen naar PowerShell of overschakelen naar Bash in het hoofdmenu van Azure Cloud Shell.

Als u wilt, gaat u rechtstreeks naar de CSV- en scriptbestanden die in dit artikel worden gebruikt in Azure-samples/azure-cli-samples.

Variabelen instellen

Ga aan de slag door de variabelen te maken die nodig zijn voor het script. De volgende drie variabelen hebben werkelijke waarden nodig voor uw omgeving:

  • subscriptionID: dit is uw Azure-abonnements-id.
  • csvFileLocation: dit is de locatie en bestandsnaam van uw CSV-invoerbestand.
  • logFileLocation: dit is de locatie en bestandsnaam die het script gebruikt om een logboekbestand te maken. U hoeft dit bestand niet te maken of te uploaden.

Variabelen met een msdocs- voorvoegsel kunnen worden vervangen door het voorvoegsel van uw keuze. Alle lege ("") variabelen gebruiken waarden uit het CSV-invoerbestand. Deze lege variabelen zijn tijdelijke aanduidingen die nodig zijn voor het 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

CSV-bestandwaarden valideren

Voordat u begint met het testen van het script, moet u ervoor zorgen dat uw CSV-bestand correct is opgemaakt en dat aan variabelen de juiste waarden worden toegewezen. Dit script maakt gebruik van een ALS.. THEN-instructie, zodat u één scenario/CSV-regel tegelijk kunt bekijken.

# 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)

Met behulp van het CSV-bestand in dit artikel is de validatie-uitvoer als volgt: (De 00000001 willekeurige id is voor elke test anders.)

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

Scriptlogica valideren

Als u zeker bent van uw scriptmogelijkheden, kunt u deze stap overslaan. Omdat dit script echter is ontworpen om Azure-resources op schaal te maken, kan het doorlopen van het script met echo of write-host instructies u tijd besparen en onverwachte factureerbare Azure-resources.

Er zijn verschillende manieren om een CSV-bestand te doorlopen met behulp van Bash. In dit voorbeeld wordt gebruikgemaakt IFS van een 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

Met behulp van het CSV-bestand in dit artikel is de validatie-uitvoer als volgt: (De 00000001, 2, 3 willekeurige id's zijn voor elke test anders, maar elke resource onder elke resourceNo resource moet dezelfde willekeurige id delen.)

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>

Azure-resources maken

U hebt nu het variabeleblok gemaakt, uw CSV-waarden gevalideerd en een testuitvoering voltooid met echo of write-host. Voer het vierde en laatste gedeelte van het script uit om Azure-resources te maken zoals gedefinieerd in uw CSV-invoerbestand.

# 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

Ontbreekt de laatste rij in het CSV-bestand in de console-uitvoer? Dit kan worden veroorzaakt door een ontbrekend regelvervolgteken na de laatste regel. Voeg een lege regel toe aan het einde van het CSV-bestand om het probleem op te lossen.

Console-uitvoer voordat logboekbestand wordt gelezen:

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

De inhoud van het logboekbestand moet er ongeveer als volgt uitzien:

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
  }

Probleemoplossing

In Bash stopt de stap 'Azure-resources maken' na stap 1

In Ubuntu 22.04.3 LTS en Debian versie 12 (boekworm) werkt de scriptlogica valideren zoals verwacht met resultaten voor alle drie de resources. De Azure-resources maken stopt echter na de eerste resource. Een mogelijke reden voor dit probleem is dat het maken van het VNet in stap 1 enkele seconden duurt. Ubuntu en Debian gaan door naar de tweede resource zonder te wachten op de voltooiing van het VNet. U kunt hierover meer lezen in wachten en wacht niet tot de processen in de while-lus zijn voltooid of wachten tot een proces in bash-script is voltooid.

Bash-script negeert IF-instructie

Bash is hoofdlettergevoelig. Het woord true is niet gelijk aan TRUE. Ook greater than is -gt, niet >, en equals is ==, niet =. Zorg ervoor dat u geen typografische fout of voorloop-/volgspaties in uw CSV-kolomwaarden hebt.

Variabele waarden worden niet gewijzigd met elke lus

Dit wordt vaak veroorzaakt door extra spaties in het CSV-bestand. Een regel in een CSV-bestand ziet er ongeveer als volgt uit: column1,column2,column3 of column1,,column3, maar het is eenvoudig om een testbestand te maken dat een spatie bevat na elke komma, zoals column1, column2, column3. Wanneer u een voorloop- of volgruimte in uw CSV hebt, is de kolomwaarde in feite <space>columnValue. De scriptlogica if [ "$columnName" = "columnValue" ] retourneert 'false'. Verwijder alle voorloop- en volgspaties in uw CSV-rijen om het probleem op te lossen.

Ongeldige CIDR-notatie

U ontvangt een invalidCIDRNotation-fout wanneer u een onjuist adresvoorvoegsel doorgeeft aan az network vnet create. Dit kan lastig zijn wanneer het adresvoorvoegsel er visueel correct uitziet wanneer het in een echo instructie wordt geretourneerd. Als u problemen wilt oplossen met de werkelijke waarde die wordt gelezen uit het CSV-bestand, probeert u dit 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)

Als uw resultaten eruitzien xzy10.0.0.0 en niet het verwachte abc10.0.0.0/24xyz, is er mogelijk een verborgen teken of extra komma in uw CSV-bestand. Voeg een testkolom toe met dezelfde voorvoegselwaarde, rangschik uw CSV-kolommen en kopieer/plak de CSV-inhoud in/uit een eenvoudige Kladblok-editor. Bij het schrijven van dit artikel heeft de herverdeling van de CSV-kolommen uiteindelijk de fout opgelost.

Argumenten worden verwacht of vereist

U ontvangt deze fout wanneer u geen vereiste parameter hebt opgegeven of als er een typografische fout optreedt die ervoor zorgt dat de Azure CLI de verwijzingsopdracht onjuist parseert. Wanneer u met een script werkt, wordt deze fout ook weergegeven wanneer een van de volgende beweringen waar is:

  • Er is een ontbrekend of onjuist regelvervolgteken.
  • Er zijn spaties aan de rechterkant van een regelvervolgteken.
  • De naam van de variabele bevat een speciaal teken, zoals een streepje (-).

InvalidTemplateDeployment

Wanneer u probeert een Azure-resource te maken op een locatie die deze resource niet aanbiedt, ontvangt u een foutbericht dat lijkt op het volgende: 'De volgende SKU's zijn mislukt voor capaciteitsbeperkingen: Standard_DS1_v2 is momenteel niet beschikbaar op locatie 'westus'.

Hier volgt het volledige foutvoorbeeld:

{"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."}]}}

Als u de fout wilt corrigeren, wijzigt u de locatie of selecteert u een andere parameterwaarde die wordt aangeboden voor de gewenste locatie.

Zie ook