Sdílet prostřednictvím


Vytvoření prostředků ve velkém měřítku pomocí Azure CLI

Jako Správce prostředků Azure často musíte při konfiguraci nových prostředí vytvořit více prostředků Azure. Můžete mít také proces schválení prostředků Azure, který funguje nejlépe při automatickém vytvoření prostředků Azure ze skriptu.

V tomto článku se dozvíte následující informace:

  • Vytvořte několik prostředků Azure z parametrů přijatých ze souboru CSV s oddělovači.
  • Použijte funkci IF.. Příkazy THEN pro vytvoření závislých prostředků Azure
  • Průběh skriptu protokolu do místního souboru TXT.

Tento ukázkový skript byl testován v Azure Cloud Shelluv prostředích Bash i PowerShellu a PowerShellu 7. Vyhledejte soubor CSV a úplný skript v Azure-samples/azure-cli-samples.

Příprava prostředí

Při přípravě prostředí na spuštění ukázkového skriptu postupujte takto:

  • Otevřete prostředí Bash nebo PowerShell v Azure Cloud Shellu. Další informace najdete v tématu Rychlý start pro Bash v Azure Cloud Shellu.

  • Stáhněte a uložte do místního adresáře následující soubor CSV. Nahraďte myExistingResourceGroupName řádek 3 skutečným názvem skupiny prostředků.

    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]
    

    Poznámka:

    Pokud chcete být správným textovým souborem unixového systému a přečíst ho Bash, potřebuje soubor CSV na konci posledního datového řádku znak nového řádku. Výsledkem je prázdný řádek na konci souboru. Prázdný řádek nemusí říkat [empty line] , protože tento text je k dispozici pouze k zobrazení, že existuje prázdný řádek. Prostředí PowerShellu nemají tento požadavek na znak nového řádku.

  • Nahrajte upravený soubor CSV do účtu úložiště blogu Azure Cloud Shellu. Nejjednodušší způsob, jak to udělat, je použít rozevírací seznam Správa souborů v hlavní nabídce Azure Cloud Shellu. Další informace o úložišti Cloud Shell najdete v tématu Zachování souborů v Azure Cloud Shellu.

Přehled skriptu

Tento článek rozdělí jeden velký skript do čtyř částí, aby bylo možné jednotlivé kroky vysvětlit.

  • Nastavení proměnné
  • Ověření dat
  • Ověření smyčky
  • Vytvoření prostředku Azure

K dispozici jsou také dva skripty: jeden pro Bash a druhý pro PowerShell. Oba skripty používají stejné příkazy Azure CLI. Je to prostředí nebo profil terminálu, který se liší. Například Bash používá do...done a if...then...fi. V prostředí PowerShellu použijete ekvivalent foreach a if (something is true)...{do this}. V Azure Cloud Shellu můžete přepínat mezi prostředími pomocí přepínače na PowerShell nebo přepínače na tlačítko Bash v hlavní nabídce Azure Cloud Shellu.

Pokud chcete, přejděte přímo do souborů CSV a skriptů používaných v tomto článku v Azure-samples/azure-cli-samples.

Nastavit proměnné

Začněte vytvořením proměnných potřebných pro skript. Následující tři proměnné vyžadují skutečné hodnoty pro vaše prostředí:

  • subscriptionID: Toto je ID vašeho předplatného Azure.
  • csvFileLocation: Toto je umístění a název souboru vašeho vstupního souboru CSV.
  • logFileLocation: Toto je umístění a název souboru, který skript použije k vytvoření souboru protokolu. Tento soubor nemusíte vytvářet ani nahrávat.

Proměnné s předponou msdocs- lze nahradit předponou podle vašeho výběru. Všechny prázdné proměnné"" používají hodnoty ze vstupního souboru CSV. Tyto prázdné proměnné jsou zástupné symboly, které skript potřebuje.

# 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

Ověření hodnot souborů CSV

Než začnete testovat skript pro vytvoření, ujistěte se, že je soubor CSV správně naformátovaný a proměnné budou přiřazeny správné hodnoty. Tento skript používá funkci IF.. Příkaz THEN, abyste se mohli podívat na jeden scénář nebo řádek CSV najednou.

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

Pomocí sdíleného svazku clusteru uvedeného v tomto článku je výstup ověření následující: ( 00000001 Náhodné ID se pro každý test bude lišit.)

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

Logika ověření skriptu

Pokud jste si jistí schopnostmi skriptování, můžete tento krok přeskočit. Vzhledem k tomu, že je tento skript navržený tak, aby vytvářel prostředky Azure ve velkém měřítku, smyčka prostřednictvím skriptu echo nebo write-host příkazů vám může ušetřit čas a neočekávané fakturovatelné prostředky Azure.

Existuje několik způsobů, jak iterovat soubor CSV pomocí bashe. Tento příklad používá IFS s .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

Pomocí sdíleného svazku clusteru uvedeného v tomto článku je výstup ověření následující: ( 00000001, 2, 3 Náhodná ID se budou pro každý test lišit, ale každý prostředek v rámci každého resourceNo by měl sdílet stejné náhodné 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>

Vytvoření zdrojů Azure

Vytvořili jste blok proměnných, ověřili jste hodnoty CSV a dokončili jste testovací běh s echo nebo write-host. Spuštěním čtvrté a poslední části skriptu vytvořte prostředky Azure definované ve vstupním souboru 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

Výstup konzoly před čtením souboru protokolu:

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

Řešení problému

Skript Bash ignoruje příkaz IF.

Bash rozlišují malá a velká písmena. Slovo true se nerovná TRUE. Také greater than je -gt, ne >, a equals je ==, ne =. Ujistěte se, že ve sloupcích CSV nemáte typografickou chybu nebo mezery na začátku nebo na konci.

Hodnoty proměnných se při každé smyčce nemění

Příčinou jsou často nadbytečné mezery v souboru CSV. Řádek v souboru CSV bude vypadat nějak takto: column1,column2,column3 nebo column1,,column3, ale podle zvyku je snadné vytvořit testovací soubor, který obsahuje mezeru za každou čárkou jako column1, column2, column3. Pokud máte úvodní nebo koncové místo ve sdíleném svazku clusteru, hodnota sloupce je ve skutečnosti <space>columnValue. Logika if [ "$columnName" = "columnValue" ] skriptu vrátí hodnotu false. Pokud chcete tento problém vyřešit, odeberte všechny úvodní a koncové mezery v řádcích CSV.

Neplatná notace CIDR

Při předání nesprávné předpony adresy do az network vnet createaplikace se zobrazí chyba InvalidCIDRNotation . To může být náročné, když se vizuálně zobrazí předpona adresy, když se vrátí v echo příkazu. Pokud chcete vyřešit potíže se skutečným čtením hodnoty ze sdíleného svazku clusteru, vyzkoušejte tento skript:

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)

Pokud vaše výsledky vypadají jako xzy10.0.0.0 a ne očekávané abc10.0.0.0/24xyz, může být ve vašem souboru CSV skrytý znak nebo nadbytečný čárka. Přidejte testovací sloupec se stejnou hodnotou předpony, změňte uspořádání sloupců CSV a zkopírujte nebo vložte obsah CSV do nebo z jednoduchého editoru Poznámkový blok. Při psaní tohoto článku se změna uspořádání sloupců CSV nakonec opraví.

Argumenty jsou očekávané nebo povinné.

Tato chyba se zobrazí, pokud jste nezadali požadovaný parametr nebo dojde k typografické chybě, která způsobí, že Azure CLI nesprávně parsuje referenční příkaz. Při práci se skriptem se zobrazí tato chyba také v případě, že platí jedna z následujících možností:

  • Chybí nebo není správný znak pokračování řádku.
  • Na pravé straně znaku pokračování řádku jsou koncové mezery.
  • Název proměnné obsahuje speciální znak, například pomlčku (-).

InvalidTemplateDeployment

Když se pokusíte vytvořit prostředek Azure v umístění, které tento prostředek nenabízí, zobrazí se chyba podobná následující: "Následující skladové položky selhaly kvůli omezením kapacity: Standard_DS1_v2" není aktuálně k dispozici v umístění westus.

Tady je úplný příklad chyby:

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

Pokud chcete chybu opravit, změňte umístění nebo vyberte jinou hodnotu parametru, která je nabízena pro požadované umístění.

Viz také