Azure CLI kullanarak uygun ölçekte kaynak oluşturma

Azure bulut kaynağı yöneticisi olarak, yeni ortamları yapılandırırken sık sık birden çok Azure kaynağı oluşturmanız gerekir. Azure kaynakları bir komut dosyasından otomatik olarak oluşturulduğunda en iyi şekilde işleyen bir Azure kaynak onay süreciniz de olabilir.

Bu makalede aşağıdaki öğeleri öğreneceksiniz:

  • Sınırlandırılmış bir CSV dosyasından alınan parametrelerden birden çok Azure kaynağı oluşturun.
  • EĞER..O ZAMAN ifadelerini kullanarak bağımlı Azure kaynakları oluşturun.
  • Yerel bir TXT dosyasına betik ilerlemesi kaydedin.

Bu örnek betik Hem Bash hem de PowerShell ortamları ve PowerShell 7 kullanılarak Azure Cloud Shell'de test edilmiştir. Azure-samples/azure-cli-samples dizininde CSV ve tam betiği bulabilirsiniz.

Ortamınızı hazırlama

Ortamınızı örnek betiği çalıştıracak şekilde hazırlamak için şu adımları izleyin:

  • Bash veya PowerShell ortamını Azure Cloud Shell'de açın. Daha fazla bilgi için Azure Cloud Shell'de Bash için Hızlı Başlangıç Kılavuzu sayfasına bakın.

  • Aşağıdaki CSV dosyasını indirip yerel bir dizine kaydedin. Üçüncü satırdaki myExistingResourceGroupName'nin yerine gerçek bir kaynak grubu adı yazın.

    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]
    

    Uyarı

    Düzgün bir Unix metin dosyası olmak ve Bash tarafından okunabilmesi için CSV dosyasının son veri satırının sonunda yeni bir satır karakteri olması gerekir. Bu, dosyanın sonunda boş bir satıra neden olur. Boş satırınızın [empty line] ifadesine ihtiyacı yoktur, çünkü bu metin yalnızca bir boş satırın var olduğunu göstermek amacıyla sağlanmıştır. PowerShell ortamlarında bu yeni satır karakteri gereksinimi yoktur.

  • Değiştirilen CSV dosyanızı Azure Cloud Shell blog depolama hesabınıza yükleyin. Bunu yapmanın en kolay yolu, Azure Cloud Shell ana menüsündeki Dosyaları yönet açılan listesini kullanmaktır. Cloud Shell depolama hakkında daha fazla bilgi için bkz . Azure Cloud Shell'de dosyaları kalıcı hale geçirme.

Senaryoya genel bakış

Bu makale tek bir büyük betiği dört bölüme bölerek her adımın açıklanmasını sağlar.

  • Değişken ayarlama
  • Veri doğrulama
  • Döngü doğrulama
  • Azure kaynak oluşturma

Ayrıca iki betik de sağlanır: biri Bash için, ikincisi PowerShell için. Her iki betik de aynı Azure CLI komutlarını kullanır. Farklı olan ortam veya terminal profilidir. Örneğin, Bash do...done ve if...then...fi kullanır. PowerShell ortamında eşdeğerini foreach ve if (something is true)...{do this}kullanırsınız. Azure Cloud Shell'de, Azure Cloud Shell ana menüsündeki PowerShell'e Geç veya Bash'e Geç düğmesini kullanarak ortamlar arasında geçiş yapabilirsiniz.

İsterseniz doğrudan Azure-samples/azure-cli-samples makalesinde bu makale tarafından kullanılan CSV ve betik dosyalarına gidin.

Değişkenleri ayarlama

Betik için gerekli değişkenleri tanımlayarak başlayın. Aşağıdaki üç değişken ortamınız için gerçek değerlere ihtiyaç duyar:

  • subscriptionID: Bu, Azure abonelik kimliğinizdir.
  • csvFileLocation: Bu, CSV giriş dosyanızın konumu ve dosya adıdır.
  • logFileLocation: Bu, betiğin günlük dosyası oluşturmak için kullandığı konum ve dosya adıdır. Bu dosyayı oluşturmanız veya karşıya yüklemeniz gerekmez.

Önek msdocs- içeren değişkenler, seçtiğiniz ön ekle değiştirilebilir. Tüm boş ("") değişkenler CSV giriş dosyasındaki değerleri kullanır. Bu boş değişkenler, betiğin gerektirdiği yer tutucular olarak görev görür.

# 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

CSV dosya değerlerini doğrulama

Betiği test etmeye başlamadan önce CSV dosyanızın doğru biçimlendirildiğinden ve değişkenlere doğru değerlerin atandığından emin olun. Bu betik, bir kerede bir senaryoya/CSV satırına bakabilmeniz için bir IF..THEN deyimi kullanır.

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

Bu makalede sağlanan CSV kullanılarak doğrulama çıktısı şu şekildedir: (Her 00000001 test için rastgele kimlik farklıdır.)

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

Betik mantığını doğrulama

Betik yazma yeteneklerinize güveniyorsanız bu adımı atlayabilirsiniz. Ancak, bu betik büyük ölçekte Azure kaynakları oluşturmak üzere tasarlandığından, echo veya write-host deyimlerini kullanarak betikte döngü yapmak, hem zamandan tasarruf etmenizi sağlar hem de beklenmedik faturalandırılabilir Azure kaynaklarından kaçınmanıza yardımcı olabilir.

Bash kabuğunu kullanarak CSV dosyasında yineleme yapmanın çeşitli yolları vardır. Bu örnek, IFS öğesini while loop ile kullanır.

# 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

Bu makalede sağlanan CSV kullanılarak doğrulama çıktısı şu şekildedir: (Rastgele 00000001, 2, 3 kimlikler her test için farklıdır, ancak her resourceNo birinin altındaki her kaynak aynı rastgele kimliği paylaşmalıdır.)

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>

Azure kaynakları oluşturun

Değişken bloğunuzu oluşturdunuz, CSV değerlerinizi doğruladınız ve echo veya write-host ile bir test çalıştırmasını tamamladınız. CSV giriş dosyanızda tanımlanan Azure kaynaklarını oluşturmak için betiğin dördüncü ve son bölümünü yürütebilirsiniz.

# 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

Konsol çıkışınızda CSV dosyanızdaki son satır eksik mi? Bu sorun, son satırdan sonraki eksik satır devam karakterinden kaynaklanabilir. Sorunu düzeltmek için CSV dosyanızın sonuna boş bir satır ekleyin.

Günlük dosyası okunmadan önce konsol çıkışı:

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

Günlük dosyası içeriğiniz aşağıdaki çıkış gibi görünmelidir:

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
  }

Sorun giderme

Bash'te 1. adımdan sonra "Azure kaynakları oluşturma" adımı durdurulur

Ubuntu 22.04.3 LTS ve Debian 12 (bookworm) Doğrulama betiği mantığı beklendiği gibi çalışır ve tüm üç kaynak için sonuçlar döndürür. Ancak Azure kaynakları oluşturma işlemi ilk kaynak oluşturulduktan sonra durur. Bu sorunun olası bir nedeni, 1. adımda sanal ağ oluşturma işleminin birkaç saniye sürmesidir. Hem Ubuntu hem de Debian, sanal ağın tamamlanmasını beklemeden ikinci kaynağa devam eder. Daha fazla bilgiyi While döngüsündeki processlerin bitmesini beklememe durumu veya Bash betiğinde herhangi bir işlemin bitmesini bekleme konusunda okuyabilirsiniz.

Bash betiği IF deyimini yoksayar

Bash büyük/küçük harfe duyarlıdır. Sözcüğüne true eşit TRUEdeğildir. greater thanAyrıca -gt , değil >ve equals , ==değil =. CSV sütun değerlerinizde yazım hataları veya başında/sonunda boşluk olmadığından emin olun.

Değişken değerleri her döngüde değişmiyor

Bu sorun genellikle CSV dosyasındaki ek boşluklar nedeniyle ortaya çıkar. CSV dosyasındaki bir satır şuna benzer: column1,column2,column3 veya column1,,column3gibi görünür, ancak alıştığınız üzere, gibi column1, column2, column3her virgülden sonra boşluk içeren bir test dosyası oluşturmak kolaydır. CSV'nizde baştaki veya sondaki bir alanınız olduğunda, sütun değeri aslında <space>columnValue'dir. Betik mantığı if [ "$columnName" = "columnValue" ] "false" döndürür. Sorunu çözmek için CSV satırlarınızdaki baştaki ve sondaki tüm boşlukları kaldırın.

Geçersiz CIDR gösterimi

adresine yanlış adres ön eki geçirdiğinizde az network vnet create hatası alıyorsunuz. Adres ön eki bir echo ifadesinde döndürüldüğünde görsel olarak doğru göründüğünde bu zor olabilir. CSV'den okunan gerçek değerin sorunlarını gidermek için şu betiği deneyin:

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)

Sonuçlarınız xzy10.0.0.0 şeklinde görünüyor ve beklenen abc10.0.0.0/24xyz değilse, CSV dosyanızda gizli bir karakter veya fazladan virgül bulunuyor olabilir. Aynı ön ek değerine sahip bir test sütunu ekleyin, CSV sütunlarınızı yeniden düzenleyin ve BASIT bir Not Defteri düzenleyicisinde/dışında CSV içeriğinizi kopyalayın/yapıştırın. Bu makaleyi yazarken, CSV sütunlarının yeniden düzenlenmesi sonunda hatayı düzelttik.

Bağımsız değişkenler bekleniyor veya gereklidir

Gerekli bir parametre sağlamadığınızda veya Azure CLI'nın başvuru komutunu yanlış ayrıştırmasına neden olan bir yazım hatası olduğunda bu hatayı alırsınız. Bir betikle çalışırken, aşağıdaki öğelerden biri daha doğru olduğunda da bu hatayı alırsınız:

  • Eksik veya yanlış bir satır devamlılığı karakteri var.
  • Satır devamlılığı karakterinin sağ tarafında boşluklar vardır.
  • Değişken adınızda çizgi (-) gibi özel bir karakter bulunuyor.

Geçersiz Şablon Dağıtımı

Bu kaynağı sunmayan bir konumda Azure kaynağı oluşturmaya çalıştığınızda şu iletiye benzer bir hata alırsınız: "Kapasite Kısıtlamaları için aşağıdaki SKU'lar başarısız oldu: Standard_DS1_v2' şu anda 'westus' konumunda kullanılamıyor."

İşte tam hata örneği:

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

Hatayı düzeltmek için konumu değiştirin veya istediğiniz konum için sunulan farklı bir parametre değeri seçin.

Ayrıca bakınız