Come creare risorse su larga scala usando l'interfaccia della riga di comando di Azure
In qualità di Azure Resource Manager, spesso è necessario creare più risorse di Azure durante la configurazione di nuovi ambienti. Si potrebbe anche avere un processo di approvazione delle risorse di Azure che funziona meglio quando le risorse di Azure vengono create automaticamente da uno script.
In questo articolo si apprenderà quanto segue:
- Creare più risorse di Azure dai parametri ricevuti da un file CSV delimitato.
- Usare IF.. Istruzioni THEN per creare risorse di Azure dipendenti.
- Registrare lo stato dello script in un file TXT locale.
Questo script di esempio è stato testato in Azure Cloud Shell sia negli ambienti Bash che in PowerShell 7. Trovare il file CSV e lo script completo in Azure-samples/azure-cli-samples.
Predisporre l'ambiente
Seguire questa procedura per preparare l'ambiente per eseguire lo script di esempio:
Aprire l'ambiente Bash o PowerShell in Azure Cloud Shell. Per altre informazioni, vedere Avvio rapido su Bash in Azure Cloud Shell.
Scaricare e salvare in una directory locale il file CSV seguente. Sostituire
myExistingResourceGroupName
nella riga 3 con un nome effettivo del gruppo di risorse.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]
Nota
Per essere un file di testo Unix appropriato e essere letto da Bash, il file CSV richiede un carattere di nuova riga alla fine dell'ultima riga di dati. In questo modo viene restituita una riga vuota alla fine del file. La riga vuota non deve dire
[empty line]
perché questo testo viene fornito solo per mostrare che esiste una riga vuota. Gli ambienti PowerShell non hanno questo requisito di caratteri di nuova riga.Caricare il file CSV modificato nell'account di archiviazione del blog di Azure Cloud Shell. Il modo più semplice per eseguire questa operazione consiste nell'usare l'elenco a discesa Gestisci file nel menu principale di Azure Cloud Shell. Per altre informazioni sull'archiviazione di Cloud Shell, vedere Rendere persistenti i file in Azure Cloud Shell.
Panoramica di script
Questo articolo suddivide un singolo script di grandi dimensioni in quattro sezioni in modo che ogni passaggio possa essere spiegato.
- Configurazione delle variabili
- Convalida dei dati
- Convalida del ciclo
- Creazione di risorse di Azure
Sono disponibili anche due script: uno per Bash e il secondo per PowerShell. Entrambi gli script usano gli stessi comandi dell'interfaccia della riga di comando di Azure. Si tratta dell'ambiente, o del profilo del terminale, diverso. Ad esempio, Bash usa do...done
e if...then...fi
. In un ambiente PowerShell si usano gli equivalenti foreach
e if (something is true)...{do this}
. In Azure Cloud Shell è possibile passare da un ambiente all'altro usando il pulsante Passa a PowerShell o Passa a Bash nel menu principale di Azure Cloud Shell.
Se si preferisce, passare direttamente ai file CSV e script usati da questo articolo in Azure-samples/azure-cli-samples.
Impostare variabili
Per iniziare, creare le variabili necessarie per lo script. Le tre variabili seguenti richiedono valori effettivi per l'ambiente:
- subscriptionID: ID sottoscrizione di Azure.
- csvFileLocation: percorso e nome file del file di input CSV.
- logFileLocation: si tratta del percorso e del nome file usato dallo script per creare un file di log. Non è necessario creare o caricare il file.
Le variabili con un msdocs-
prefisso possono essere sostituite con il prefisso desiderato. Tutte le variabili vuote (""
) usano valori del file di input CSV. Queste variabili vuote sono segnaposto necessari per lo 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
Convalidare i valori dei file CSV
Prima di iniziare a testare lo script di creazione, assicurarsi che il file CSV sia formattato correttamente e che alle variabili vengano assegnati valori corretti. Questo script usa un'istanza if.. Istruzione THEN in modo da poter esaminare uno scenario o una riga CSV alla volta.
# 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)
Usando il file CSV fornito in questo articolo, l'output di convalida è il seguente: (l'ID 00000001
casuale sarà diverso per ogni 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
Convalidare la logica dello script
Se si è certi delle capacità di scripting, è possibile ignorare questo passaggio. Tuttavia, poiché questo script è progettato per creare risorse di Azure su larga scala, il ciclo dello script con echo
istruzioni o write-host
consente di risparmiare tempo e risorse di Azure fatturabili impreviste.
Esistono diversi modi per scorrere un file CSV usando Bash. In questo esempio viene IFS
usato con un oggetto 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
Usando il file CSV fornito in questo articolo, l'output di convalida è il seguente: (gli 00000001, 2, 3
ID casuali saranno diversi per ogni test, ma ogni risorsa in ogni resourceNo
risorsa deve condividere lo stesso ID casuale).
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>
Creare risorse Azure
A questo punto è stato creato il blocco di variabili, convalidato i valori CSV e completato un'esecuzione di test con echo
o write-host
. Eseguire la quarta parte finale dello script per creare risorse di Azure come definito nel file di input 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
Nell'output della console manca l'ultima riga nel file CSV? Ciò può essere causato da un carattere di continuazione di riga mancante dopo l'ultima riga. Aggiungere una riga vuota alla fine del file CSV per risolvere il problema.
Output della console prima della lettura del file di log:
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
Il contenuto del file di log dovrebbe essere simile al seguente:
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
}
Risoluzione dei problemi
In Bash il passaggio "Crea risorse di Azure" si interrompe dopo il passaggio 1
In Ubuntu 22.04.3 LTS e Debian versione 12 (bookworm) la logica di convalida dello script funziona come previsto restituendo i risultati per tutte e tre le risorse. Tuttavia, la creazione di risorse di Azure si arresta dopo la prima risorsa. Un possibile motivo per questo problema è che la creazione della rete virtuale nel passaggio 1 richiede alcuni secondi. Sia Ubuntu che Debian passano alla seconda risorsa senza attendere il completamento della rete virtuale. Per altre informazioni su questo aspetto in attesa, i processi nel ciclo while non vengono completati o In attesa del completamento di qualsiasi processo nello script bash.
Lo script Bash ignora l'istruzione IF
Bash fa distinzione tra maiuscole e minuscole. La parola true
non è uguale a TRUE
. È anche greater than
, non >
e equals
è ==
, non =
.-gt
Assicurarsi di non avere un errore tipografico o di spazi iniziali/finali nei valori delle colonne CSV.
I valori delle variabili non vengono modificati con ogni ciclo
Questo è spesso causato da spazi aggiuntivi nel file CSV. Una riga in un file CSV avrà un aspetto simile al seguente: column1,column2,column3
o column1,,column3
, ma per abitudine è facile creare un file di test che contiene uno spazio dopo ogni virgola come column1, column2, column3
. Quando si dispone di uno spazio iniziale o finale nel file CSV, il valore della colonna è effettivamente <space>columnValue
. La logica if [ "$columnName" = "columnValue" ]
dello script restituisce "false". Rimuovere tutti gli spazi iniziali e finali nelle righe CSV per risolvere il problema.
Notazione CIDR non valida
Viene visualizzato un errore InvalidCIDRNotation quando si passa un prefisso di indirizzo non corretto a az network vnet create
. Questa situazione può risultare complessa quando visivamente il prefisso dell'indirizzo è corretto quando viene restituito in un'istruzione echo
. Per risolvere i problemi relativi al valore effettivo letto dal volume condiviso cluster, provare questo 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)
Se i risultati sono simili xzy10.0.0.0
e non previsti abc10.0.0.0/24xyz
, potrebbe essere presente un carattere nascosto o un'ulteriore virgola che si nasconde nel file CSV. Aggiungere una colonna di test con lo stesso valore di prefisso, riorganizzare le colonne CSV e copiare/incollare il contenuto csv in/fuori da un semplice editor del Blocco note. Nella scrittura di questo articolo, la ridisporzione delle colonne CSV ha infine risolto l'errore.
Gli argomenti sono previsti o obbligatori
Questo errore viene visualizzato quando non è stato specificato un parametro obbligatorio o si verifica un errore tipografico che causa l'analisi non corretta del comando di riferimento da parte dell'interfaccia della riga di comando di Azure. Quando si usa uno script, questo errore viene visualizzato anche quando si verifica uno degli elementi seguenti:
- Esiste un carattere di continuazione di riga mancante o errato.
- Sul lato destro di un carattere di continuazione di riga sono presenti spazi finali.
- Il nome della variabile contiene un carattere speciale, ad esempio un trattino (
-
).
InvalidTemplateDeployment
Quando si tenta di creare una risorsa di Azure in una posizione che non offre tale risorsa, viene visualizzato un errore simile al seguente: "Gli SKU seguenti non sono riusciti per restrizioni di capacità: Standard_DS1_v2" non sono attualmente disponibili nella posizione "westus".
Ecco l'esempio di errore completo:
{"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."}]}}
Per correggere l'errore, modificare il percorso o selezionare un valore di parametro diverso offerto per la posizione desiderata.