So wird's ausgeführt: Erstellen von Ressourcen im großen Maßstab mithilfe der Azure CLI
Als Azure-Ressourcenmanager müssen Sie häufig mehrere Azure-Ressourcen erstellen, wenn Sie neue Umgebungen konfigurieren. Möglicherweise verfügen Sie auch über einen Azure-Ressourcengenehmigungsprozess, der am besten funktioniert, wenn Azure-Ressourcen automatisch aus einem Skript erstellt werden.
In diesem Artikel erfahren Sie Folgendes:
- Erstellen Sie mehrere Azure-Ressourcen aus Parametern, die von einer durch Trennzeichen getrennten CSV-Datei empfangen werden.
- Verwenden Sie IF.. THEN-Anweisungen zum Erstellen abhängiger Azure-Ressourcen.
- Protokollskriptfortschritt bei einer lokalen TXT-Datei.
Dieses Beispielskript wurde in Azure Cloud Shell sowohl in Bash- als auch in PowerShell-Umgebungen und PowerShell 7 getestet. Suchen Sie die CSV-Datei und das vollständige Skript in Azure-Samples/azure-cli-Samples.
Vorbereiten der Umgebung
Führen Sie die folgenden Schritte aus, um Ihre Umgebung für die Ausführung des Beispielskripts vorzubereiten:
Öffnen Sie entweder die Bash- oder PowerShell-Umgebung in Azure Cloud Shell. Weitere Informationen finden Sie unter Schnellstart für Bash in Azure Cloud Shell.
Laden Sie die folgende CSV-Datei herunter, und speichern Sie es in einem lokalen Verzeichnis. Ersetzen Sie
myExistingResourceGroupName
in Zeile 3 durch einen tatsächlichen Ressourcengruppennamen.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]
Hinweis
Um eine richtige Unix-Textdatei zu sein und von Bash gelesen zu werden, benötigt die CSV-Datei am Ende der letzten Datenzeile ein Zeilenumbruchzeichen. Dies führt zu einer leeren Zeile am Ende der Datei. Ihre leere Zeile muss nicht sagen
[empty line]
, da dieser Text nur bereitgestellt wird, um Ihnen zu zeigen, dass eine leere Zeile vorhanden ist. PowerShell-Umgebungen verfügen nicht über diese Anforderung für Neueinbruchzeichen.Laden Sie Ihre geänderte CSV-Datei in Ihr Azure Cloud Shell-Blogspeicherkonto hoch. Die einfachste Möglichkeit hierfür ist die Verwendung der Dropdownliste "Dateien verwalten" im Hauptmenü der Azure Cloud Shell. Weitere Informationen zum Cloud Shell-Speicher finden Sie unter Speichern von Dateien in Azure Cloud Shell.
Skriptübersicht
In diesem Artikel wird ein einzelnes großes Skript in vier Abschnitte unterteilt, sodass jeder Schritt erläutert werden kann.
- Variable Einrichtung
- Datenvalidierung
- Schleifenüberprüfung
- Azure-Ressourcenerstellung
Es gibt auch zwei Skripts: eine für Bash und die zweite für PowerShell. Beide Skripts verwenden dieselben Azure CLI-Befehle. Es handelt sich um die Umgebung oder das Terminalprofil, das anders ist. Bash verwendet do...done
z. B. und if...then...fi
. In einer PowerShell-Umgebung verwenden Sie die Entsprechung foreach
und if (something is true)...{do this}
. In Azure Cloud Shell können Sie zwischen Umgebungen wechseln, indem Sie die Schaltfläche "Zu PowerShell wechseln" oder im Hauptmenü der Azure Cloud Shell zu Bash wechseln.
Wenn Sie es vorziehen, wechseln Sie direkt zu den CSV- und Skriptdateien, die in diesem Artikel in Azure-Samples/azure-cli-samples verwendet werden.
Festlegen von Variablen
Beginnen Sie, indem Sie die für das Skript erforderlichen Variablen erstellen. Die folgenden drei Variablen benötigen tatsächliche Werte für Ihre Umgebung:
- subscriptionID: Dies ist Ihre Azure-Abonnement-ID.
- csvFileLocation: Dies ist der Speicherort und Dateiname Ihrer CSV-Eingabedatei.
- logFileLocation: Dies ist der Speicherort und der Dateiname , den das Skript zum Erstellen einer Protokolldatei verwendet. Sie müssen diese Datei nicht erstellen oder hochladen.
Variablen mit einem msdocs-
Präfix können durch das Präfix Ihrer Wahl ersetzt werden. Alle leeren (""
) Variablen verwenden Werte aus der CSV-Eingabedatei. Diese leeren Variablen sind Platzhalter, die vom Skript benötigt werden.
# 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
Überprüfen von CSV-Dateiwerten
Bevor Sie mit dem Testen des Erstellungsskripts beginnen, stellen Sie sicher, dass Ihre CSV-Datei richtig formatiert ist, und Variablen werden die richtigen Werte zugewiesen. Dieses Skript verwendet ein IF.. THEN-Anweisung, damit Sie jeweils eine Szenario-/CSV-Zeile anzeigen können.
# 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)
Mithilfe der in diesem Artikel bereitgestellten CSV-Datei lautet die Überprüfungsausgabe wie folgt: (Die 00000001
zufällige ID wird für jeden Test unterschiedlich sein.)
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
Überprüfen der Skriptlogik
Wenn Sie mit Ihren Skriptfähigkeiten vertraut sind, können Sie diesen Schritt überspringen. Da dieses Skript jedoch so konzipiert ist, dass Azure-Ressourcen im großen Maßstab erstellt werden, können Sie durch das Skript mit echo
oder write-host
Anweisungen zeitsparend und unerwartete, abrechnende Azure-Ressourcen sparen.
Es gibt mehrere Möglichkeiten zum Durchlaufen einer CSV-Datei mithilfe von Bash. In diesem Beispiel wird IFS
mit einer 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
Mithilfe der in diesem Artikel bereitgestellten CSV-Datei lautet die Überprüfungsausgabe wie folgt: (Die 00000001, 2, 3
zufälligen IDs sind für jeden Test unterschiedlich, aber jede Ressource unter jedem resourceNo
sollte die gleiche zufällige ID aufweisen.)
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>
Erstellen von Azure-Ressourcen
Sie haben nun ihren Variablenblock erstellt, Ihre CSV-Werte überprüft und eine Testausführung mit echo
oder write-host
abgeschlossen. Führen Sie den vierten und letzten Teil des Skripts aus, um Azure-Ressourcen gemäß definition in Ihrer CSV-Eingabedatei zu erstellen.
# 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
Fehlt in der Konsolenausgabe die letzte Zeile in der CSV-Datei? Dies kann durch ein fehlendes Zeilenfortsetzungszeichen nach der letzten Zeile verursacht werden. Fügen Sie am Ende der CSV-Datei eine leere Zeile hinzu, um das Problem zu beheben.
Konsolenausgabe vor dem Lesen der Protokolldatei:
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
Der Inhalt der Protokolldatei sollte etwa wie folgt aussehen:
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
}
Problembehandlung
In Bash wird der Schritt "Azure-Ressourcen erstellen" nach Schritt 1 beendet.
In Ubuntu 22.04.3 LTS und Debian Version 12 (Buchwurm) funktioniert die Validate-Skriptlogik wie erwartet, die Ergebnisse für alle drei Ressourcen zurückgibt. Die Azure-Ressourcen werden jedoch nach der ersten Ressource beendet. Ein möglicher Grund für dieses Problem ist, dass das Erstellen des VNet in Schritt 1 einige Sekunden dauert. Sowohl Ubuntu als auch Debian fahren mit der zweiten Ressource fort, ohne auf den Abschluss des VNet zu warten. Weitere Informationen hierzu finden Sie unter "Warten" nicht, bis die Prozesse in der Schleife abgeschlossen sind oder auf den Abschluss eines Prozesses im Bash-Skript warten.
Bash-Skript ignoriert IF-Anweisung
Bei Bash wird die Groß-/Kleinschreibung beachtet. Das Wort true
ist nicht gleich TRUE
. Auch greater than
ist -gt
, nicht >
, und equals
ist ==
, nicht =
. Stellen Sie sicher, dass sie keinen typografischen Fehler oder führende/nachfolgende Leerzeichen in Ihren CSV-Spaltenwerten haben.
Variablenwerte ändern sich nicht mit jeder Schleife.
Dies wird häufig durch zusätzliche Leerzeichen in der CSV-Datei verursacht. Eine Zeile in einer CSV-Datei sieht ungefähr wie folgt aus: column1,column2,column3
oder column1,,column3
, aber üblich ist es einfach, eine Testdatei zu erstellen, die nach jedem Komma ein Leerzeichen enthält column1, column2, column3
. Wenn Sie einen führenden oder nachfolgenden Leerraum in Ihrer CSV haben, ist der Spaltenwert tatsächlich <space>columnValue
. Die Skriptlogik if [ "$columnName" = "columnValue" ]
gibt "false" zurück. Entfernen Sie alle führenden und nachfolgenden Leerzeichen in Ihren CSV-Zeilen, um das Problem zu beheben.
Ungültige CIDR-Schreibweise
Sie erhalten einen InvalidCIDRNotation-Fehler , wenn Sie ein falsches Adresspräfix an az network vnet create
. Dies kann schwierig sein, wenn das Adresspräfix visuell korrekt aussieht, wenn es in einer echo
Anweisung zurückgegeben wird. Um probleme mit dem tatsächlichen Wert zu beheben, der aus der CSV gelesen wird, versuchen Sie folgendes 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)
Wenn Ihre Ergebnisse wie xzy10.0.0.0
erwartet aussehen und nicht abc10.0.0.0/24xyz
, gibt es möglicherweise ein ausgeblendetes Zeichen oder ein zusätzliches Komma, das in Ihrer CSV-Datei lauert. Fügen Sie eine Testspalte mit demselben Präfixwert hinzu, ordnen Sie Ihre CSV-Spalten neu an, und kopieren/einfügen Sie ihre CSV-Inhalte in/aus einem einfachen Editor für Editoren. In diesem Artikel wurde der Fehler durch die Neuanordnung der CSV-Spalten behoben.
Argumente werden erwartet oder erforderlich
Sie erhalten diesen Fehler, wenn Sie keinen erforderlichen Parameter angegeben haben oder ein typografischer Fehler vorliegt, der dazu führt, dass die Azure CLI den Verweisbefehl falsch analysiert. Wenn Sie mit einem Skript arbeiten, erhalten Sie diesen Fehler auch, wenn einer der folgenden Werte zutrifft:
- Es ist ein fehlendes oder falsches Zeilenfortsetzungszeichen vorhanden.
- Auf der rechten Seite eines Zeilenfortsetzungszeichens befinden sich nachfolgende Leerzeichen.
- Der Variablename enthält ein Sonderzeichen, z. B. einen Gedankenstrich (
-
).
InvalidTemplateDeployment
Wenn Sie versuchen, eine Azure-Ressource an einem Speicherort zu erstellen, der diese Ressource nicht anbietet, erhalten Sie eine Fehlermeldung wie die folgenden: "Die folgenden SKUs sind für Kapazitätseinschränkungen fehlgeschlagen: Standard_DS1_v2" ist derzeit nicht am Standort "westus" verfügbar."
Hier sehen Sie das vollständige Fehlerbeispiel:
{"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."}]}}
Um den Fehler zu beheben, ändern Sie entweder den Speicherort, oder wählen Sie einen anderen Parameterwert aus, der für Den gewünschten Standort angeboten wird.