Dela via


Så här skapar du resurser i stor skala med hjälp av Azure CLI

Som Azure-resurshanterare måste du ofta skapa flera Azure-resurser när du konfigurerar nya miljöer. Du kan också ha en process för godkännande av Azure-resurser som fungerar bäst när Azure-resurser skapas automatiskt från ett skript.

I den här artikeln får du lära dig följande:

  • Skapa flera Azure-resurser från parametrar som tas emot från en avgränsad CSV-fil.
  • Använd IF.. THEN-instruktioner för att skapa beroende Azure-resurser.
  • Loggskript förlopp till en lokal TXT-fil.

Det här exempelskriptet har testats i Azure Cloud Shell i både Bash- och PowerShell-miljöer och PowerShell 7. Hitta CSV och det fullständiga skriptet i Azure-samples/azure-cli-samples.

Förbered din miljö

Följ de här stegen för att förbereda din miljö för att köra exempelskriptet:

  • Öppna antingen Bash- eller PowerShell-miljön i Azure Cloud Shell. Mer information finns i Snabbstart för Bash i Azure Cloud Shell.

  • Ladda ned och spara följande CSV-fil i en lokal katalog. Ersätt myExistingResourceGroupName på rad tre med ett verkligt resursgruppsnamn.

    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]
    

    Kommentar

    För att vara en riktig Unix-textfil och läsas av Bash behöver CSV-filen ett nytt radtecken i slutet av den sista dataraden. Detta resulterar i en tom rad i slutet av filen. Den tomma raden behöver inte säga [empty line] eftersom den här texten endast tillhandahålls för att visa att det finns en tom rad. PowerShell-miljöer har inte det här nya teckenkravet.

  • Ladda upp din ändrade CSV-fil till ditt Azure Cloud Shell-blogglagringskonto. Det enklaste sättet att göra detta är att använda listrutan Hantera filer på huvudmenyn i Azure Cloud Shell. Mer information om Cloud Shell-lagring finns i Spara filer i Azure Cloud Shell.

Skriptöversikt

Den här artikeln delar upp ett enda stort skript i fyra avsnitt så att varje steg kan förklaras.

  • Variabelkonfiguration
  • Datavalidering
  • Loopvalidering
  • Skapa Azure-resurser

Det finns också två skript: ett för Bash och det andra för PowerShell. Båda skripten använder samma Azure CLI-kommandon. Det är miljön, eller terminalprofilen, som är annorlunda. Bash använder do...done till exempel och if...then...fi. I en PowerShell-miljö använder du motsvarande foreach och if (something is true)...{do this}. I Azure Cloud Shell kan du växla mellan miljöer med hjälp av knappen Växla till PowerShell eller Växla till Bash i Huvudmenyn i Azure Cloud Shell.

Om du vill kan du gå direkt till CSV- och skriptfilerna som används i den här artikeln i Azure-samples/azure-cli-samples.

Ange variabler

Kom igång genom att skapa de variabler som behövs för skriptet. Följande tre variabler behöver faktiska värden för din miljö:

  • subscriptionID: Det här är ditt Azure-prenumerations-ID.
  • csvFileLocation: Det här är platsen och filnamnet för din CSV-indatafil.
  • logFileLocation: Det här är platsen och filnamnet som skriptet använder för att skapa en loggfil. Du behöver inte skapa eller ladda upp den här filen.

Variabler med ett msdocs- prefix kan ersättas med valfritt prefix. Alla tomma ("") variabler använder värden från CSV-indatafilen. Dessa tomma variabler är platshållare som krävs av skriptet.

# 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

Verifiera CSV-filvärden

Innan du börjar testa skapa-skriptet kontrollerar du att CSV-filen är korrekt formaterad och att variablerna tilldelas rätt värden. Det här skriptet använder en IF.. THEN-instruktion så att du kan titta på ett scenario/CSV-rad i taget.

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

Med hjälp av den CSV som anges i den här artikeln är valideringsutdata följande: (Det 00000001 slumpmässiga ID:t skiljer sig åt för varje 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

Verifiera skriptlogik

Om du är säker på dina skriptfunktioner kan du hoppa över det här steget. Men eftersom det här skriptet är utformat för att skapa Azure-resurser i stor skala kan loopning genom skriptet med echo eller write-host instruktioner spara tid och oväntade fakturerbara Azure-resurser.

Det finns flera sätt att iterera via en CSV-fil med hjälp av Bash. Det här exemplet använder IFS med en 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

Med hjälp av den CSV som anges i den här artikeln är valideringsutdata följande: (De 00000001, 2, 3 slumpmässiga ID:na skiljer sig åt för varje test, men varje resurs under varje resourceNo ska dela samma slumpmässiga ID.)

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>

Skapa Azure-resurser

Nu har du skapat variabelblocket, verifierat dina CSV-värden och slutfört en testkörning med echo eller write-host. Kör den fjärde och sista delen av skriptet för att skapa Azure-resurser enligt definitionen i CSV-indatafilen.

# 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

Konsolutdata innan loggfilen läse:

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

Felsökning

Bash-skript ignorerar IF-instruktion

Bash är skiftlägeskänsligt. Ordet true är inte lika med TRUE. Är också , inte >, och equals är ==, inte =.greater than-gt Kontrollera att du inte har något typografiskt fel eller inledande/avslutande blanksteg i dina CSV-kolumnvärden.

Variabelvärden ändras inte med varje loop

Detta orsakas ofta av extra blanksteg i CSV-filen. En rad i en CSV-fil ser ut ungefär så här: column1,column2,column3 eller column1,,column3, men med vana är det enkelt att skapa en testfil som innehåller ett blanksteg efter varje kommatecken som column1, column2, column3. När du har ett inledande eller avslutande blanksteg i din CSV är kolumnvärdet faktiskt <space>columnValue. Skriptlogik if [ "$columnName" = "columnValue" ] returnerar "false". Ta bort alla inledande och avslutande blanksteg i dina CSV-rader för att åtgärda problemet.

Ogiltig CIDR-notation

Du får ett InvalidCIDRNotation-fel när du skickar ett felaktigt adressprefix till az network vnet create. Detta kan vara svårt när det visuella objektet ser korrekt ut när det returneras i en echo instruktion. Om du vill felsöka det faktiska värdet som läse från CSV:en kan du prova det här skriptet:

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)

Om resultatet ser ut som xzy10.0.0.0 och inte det förväntade abc10.0.0.0/24xyzkan det finnas ett dolt tecken eller extra kommatecken som lurar i CSV-filen. Lägg till en testkolumn med samma prefixvärde, ordna om dina CSV-kolumner och kopiera/klistra in ditt CSV-innehåll i/från en enkel Anteckningar redigerare. När du skrev den här artikeln korrigerade omorganiseringen av CSV-kolumnerna slutligen felet.

Argument förväntas eller krävs

Du får det här felet när du inte har angett någon obligatorisk parameter eller om det finns ett typografiskt fel som gör att Azure CLI felaktigt parsar referenskommandot. När du arbetar med ett skript får du även det här felet när något av följande är sant:

  • Det finns ett saknat eller felaktigt radfortsättningstecken.
  • Det finns avslutande blanksteg på höger sida av ett linjefortsättningstecken.
  • Variabelnamnet innehåller ett specialtecken, till exempel ett bindestreck (-).

InvalidTemplateDeployment

När du försöker skapa en Azure-resurs på en plats som inte erbjuder den resursen får du ett fel som liknar följande: "Följande SKU:er har misslyckats för kapacitetsbegränsningar: Standard_DS1_v2" är för närvarande inte tillgängligt på platsen "westus".

Här är det fullständiga felexemplet:

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

Korrigera felet genom att antingen ändra platsen eller välja ett annat parametervärde som erbjuds för önskad plats.

Se även