Creación de recursos a escala mediante la CLI de Azure
Como administrador de recursos de Azure, con frecuencia tiene que crear varios recursos de Azure al configurar nuevos entornos. También puede tener un proceso de aprobación de recursos de Azure que funcione mejor cuando los recursos de Azure se crean automáticamente a partir de un script.
En este artículo aprenderá lo siguiente:
- Cree varios recursos de Azure a partir de parámetros recibidos de un archivo CSV delimitado.
- Use IF.. Instrucciones THEN para crear recursos de Azure dependientes.
- Registrar el progreso del script en un archivo TXT local.
Este script de ejemplo se ha probado en Azure Cloud Shell en entornos de Bash y PowerShell y PowerShell 7. Busque el archivo CSV y el script completo en Azure-samples/azure-cli-samples.
Preparación del entorno
Siga estos pasos para preparar el entorno para ejecutar el script de ejemplo:
Abra el entorno de Bash o PowerShell en Azure Cloud Shell. Para más información, consulte Inicio rápido para Bash en Azure Cloud Shell.
Descargue y guarde en un directorio local el siguiente archivo CSV. Reemplace
myExistingResourceGroupName
en la línea tres por un nombre de grupo de recursos real.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:
Para ser un archivo de texto unix adecuado y ser leído por Bash, el archivo CSV necesita un carácter de nueva línea al final de la última línea de datos. Esto da como resultado una línea en blanco al final del archivo. La línea en blanco no necesita decir
[empty line]
, ya que este texto solo se proporciona para mostrar que existe una línea vacía. Los entornos de PowerShell no tienen este requisito de carácter de nueva línea.Cargue el archivo CSV modificado en la cuenta de almacenamiento del blog de Azure Cloud Shell. La manera más fácil de hacerlo es usar la lista desplegable Administrar archivos en el menú principal de Azure Cloud Shell. Para más información sobre el almacenamiento de Cloud Shell, consulte Conservación de archivos en Azure Cloud Shell.
Información general del script
En este artículo se divide un único script grande en cuatro secciones para que se pueda explicar cada paso.
- Configuración de variables
- Validación de datos
- Validación de bucles
- Creación de recursos de Azure
También se proporcionan dos scripts: uno para Bash y el segundo para PowerShell. Ambos scripts usan los mismos comandos de la CLI de Azure. Es el entorno o el perfil de terminal, que es diferente. Por ejemplo, Bash usa do...done
y if...then...fi
. En un entorno de PowerShell, se usan los equivalentes foreach
y if (something is true)...{do this}
. En Azure Cloud Shell, puede cambiar entre entornos mediante el botón Cambiar a PowerShell o Cambiar a Bash en el menú principal de Azure Cloud Shell.
Si lo prefiere, vaya directamente a los archivos CSV y de script que usa este artículo en Azure-samples/azure-cli-samples.
Configuración de variables
Para empezar, cree las variables necesarias para el script. Las tres variables siguientes necesitan valores reales para el entorno:
- subscriptionID: este es el identificador de suscripción de Azure.
- csvFileLocation: esta es la ubicación y el nombre de archivo del archivo de entrada CSV.
- logFileLocation: esta es la ubicación y el nombre de archivo que usará el script para crear un archivo de registro. No es necesario crear ni cargar este archivo.
Las variables con un msdocs-
prefijo se pueden reemplazar por el prefijo que prefiera. Todas las variables vacías (""
) usan valores del archivo de entrada CSV. Estas variables vacías son marcadores de posición necesarios para el 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
Validación de valores de archivo CSV
Antes de empezar a probar el script de creación, asegúrese de que el archivo CSV tiene el formato correcto y las variables se asignarán valores correctos. Este script usa un IF.. Instrucción THEN para que pueda examinar una línea CSV o un escenario a la vez.
# 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)
Con el ARCHIVO CSV proporcionado en este artículo, la salida de validación es la siguiente: (El 00000001
identificador aleatorio será diferente para cada prueba).
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
Validación de la lógica del script
Si confía en sus capacidades de scripting, puede omitir este paso. Sin embargo, dado que este script está diseñado para crear recursos de Azure a escala, recorrer en bucle el script con echo
instrucciones o write-host
puede ahorrar tiempo y recursos de Azure facturables inesperados.
Hay varias maneras de recorrer en iteración un archivo CSV mediante Bash. En este ejemplo se usa IFS
con .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
Con el CSV proporcionado en este artículo, la salida de validación es la siguiente: (Los 00000001, 2, 3
identificadores aleatorios serán diferentes para cada prueba, pero cada recurso de cada resourceNo
uno debe compartir el mismo identificador aleatorio).
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>
Creación de recursos de Azure
Ahora ha creado el bloque de variables, ha validado los valores CSV y ha completado una ejecución de prueba con echo
o write-host
. Ejecute la cuarta y última parte del script para crear recursos de Azure como se define en el archivo de entrada 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
En la salida de la consola, ¿falta la última fila en el archivo CSV? Esto puede deberse a un carácter de continuación de línea que falta después de la última línea. Agregue una línea en blanco al final del archivo CSV para corregir el problema.
Salida de la consola antes de leer el archivo de registro:
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
El contenido del archivo de registro debe tener un aspecto similar al siguiente:
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
}
Solución de problemas
En Bash, el paso "Crear recursos de Azure" se detiene después del paso 1.
En Ubuntu 22.04.3 LTS y Debian versión 12 (bookworm), la lógica validar script funciona según lo previsto para devolver los resultados de los tres recursos. Sin embargo, la opción Crear recursos de Azure se detiene después del primer recurso. Un posible motivo de este problema es que la creación de la red virtual en el paso 1 tarda unos segundos. Ubuntu y Debian continúan con el segundo recurso sin esperar a que se complete la red virtual. Puede obtener más información sobre esto en espera no espera a que los procesos del bucle while finalicen o Esperando a que finalice cualquier proceso en el script de Bash.
El script de Bash omite la instrucción IF
Bash distingue mayúsculas de minúsculas. La palabra true
no es igual a TRUE
. También greater than
es -gt
, no >
, y equals
es ==
, no =
. Asegúrese de que no tiene un error tipográfico o espacios iniciales o finales en los valores de columna CSV.
Los valores de variable no cambian con cada bucle
Esto suele deberse a espacios adicionales en el archivo CSV. Una línea de un archivo CSV tendrá un aspecto similar al siguiente: column1,column2,column3
o column1,,column3
, pero por hábito es fácil crear un archivo de prueba que contenga un espacio después de cada coma como column1, column2, column3
. Cuando tiene un espacio inicial o final en el CSV, el valor de columna es realmente <space>columnValue
. La lógica if [ "$columnName" = "columnValue" ]
del script devuelve "false". Quite todos los espacios iniciales y finales de las filas CSV para corregir el problema.
Notación CIDR no válida
Recibirá un error InvalidCIDRNotation al pasar un prefijo de dirección incorrecto a az network vnet create
. Esto puede ser difícil cuando visualmente, el prefijo de dirección es correcto cuando se devuelve en una echo
instrucción . Para solucionar problemas del valor real que se lee desde csv, pruebe este 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)
Si los resultados son similares xzy10.0.0.0
y no los esperados abc10.0.0.0/24xyz
, es posible que haya un carácter oculto o una coma adicional que acecha en el archivo CSV. Agregue una columna de prueba con el mismo valor de prefijo, reorganice las columnas CSV y copie o pegue el contenido de CSV dentro o fuera de un editor simple del Bloc de notas. Al escribir este artículo, la reorganización de las columnas CSV finalmente corrigió el error.
Los argumentos son esperados o necesarios
Recibe este error cuando no ha proporcionado un parámetro obligatorio o hay un error tipográfico que hace que la CLI de Azure analice incorrectamente el comando de referencia. Al trabajar con un script, también recibirá este error cuando se cumple una de las siguientes opciones:
- Falta un carácter de continuación de línea o incorrecto.
- Hay espacios finales en el lado derecho de un carácter de continuación de línea.
- El nombre de la variable contiene un carácter especial, como un guión (
-
).
InvalidTemplateDeployment
Al intentar crear un recurso de Azure en una ubicación que no ofrezca ese recurso, recibirá un error similar al siguiente: "Las SKU siguientes han producido un error en las restricciones de capacidad: Standard_DS1_v2" no está disponible actualmente en la ubicación "westus".
Este es el ejemplo de error 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."}]}}
Para corregir el error, cambie la ubicación o seleccione un valor de parámetro diferente que se ofrezca para la ubicación deseada.