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 Shellu v 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
Ve výstupu konzoly chybí poslední řádek v souboru CSV? Příčinou může být chybějící znak pokračování řádku za posledním řádkem. Pokud chcete tento problém vyřešit, přidejte na konec souboru CSV prázdný řádek.
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
Obsah souboru protokolu by měl vypadat nějak takto:
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
}
Řešení problému
V Bash se krok Vytvoření prostředků Azure zastaví po kroku 1.
V Ubuntu 22.04.3 LTS a Debianu verze 12 (bookworm) logika ověření skriptu funguje podle očekávání vracející výsledky pro všechny tři prostředky. Vytvoření prostředků Azure se ale zastaví po prvním prostředku. Možným důvodem tohoto problému je, že vytvoření virtuální sítě v kroku 1 trvá několik sekund. Ubuntu i Debian pokračují k druhému prostředku bez čekání na dokončení virtuální sítě. Můžete si přečíst další informace o tom, že čekání nečeká na dokončení procesů ve smyčce while nebo čekání na dokončení jakéhokoli procesu ve skriptu Bash.
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 create
aplikace 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ého bloku. 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í.