VM 應用程式是 Azure Compute Gallery 中的一種資源類型,可簡化虛擬機器應用程式的管理、共用和全域散發。
深入瞭解 VM 應用程式
若要在 Azure VM 上建立和部署應用程式,請先將應用程式封裝並上傳至 Azure 儲存體帳戶做為儲存體 Blob。 然後建立 Azure VM application 資源和 VM application version 資源參考這些儲存體 Blob。 最後,將應用程式部署在任何 VM 或虛擬機器擴展集上,方法是將應用程式參考傳遞給 applicationProfile。
必要條件
- 建立 Azure 儲存體帳戶 和 儲存體容器。 此容器可用來上傳您的應用程式檔案。 建議使用已停用匿名存取的儲存體帳戶,以增加安全性。
- 建立 Azure 計算資源庫來儲存和共用應用程式資源。
封裝應用程式
1.打包應用程式檔案
- 如果您的應用程式安裝需要單一檔案(.exe、.msi、.sh、.ps等),則可以按原樣使用它。
- 如果您的應用程式安裝需要多個檔案(包含設定檔的可執行檔、相依性、資訊清單檔案、腳本等),則必須將其封存到單一檔案中(使用 .zip、.tar、.tar.gz等)。
- 針對微服務應用程式,您可以將每個微服務封裝並發佈為個別的 Azure VM 應用程式。 這有助於應用程式可重複使用性、跨團隊開發,以及使用
order 中的屬性來循序安裝微服務。
2.(可選)打包應用程式設定檔
- 您可以選擇性地單獨提供組態檔。 這可減少保存和取消保存應用程式套件的額外負荷。 也可以在應用程式部署期間傳遞組態檔,以啟用每個 VM 的自訂安裝。
3. 建立安裝腳本
在 VM 上下載應用程式和組態 Blob 之後,Azure 會執行提供的安裝腳本來安裝應用程式。
安裝腳本以字串形式提供 ,字元限制上限為 4,096 個字元。 安裝命令應假設應用程式套件和組態檔位於目前目錄中。
安裝指令碼中可能需要執行的作業很少
(選擇性) 使用正確的命令解譯器 Azure 使用的預設命令解譯器位於 /bin/bash Linux OS 和 cmd.exe Windows OS 上。 如果機器上安裝了 Chocolatey 或 PowerShell,則可以使用不同的解譯器。 呼叫可執行檔並將命令傳遞給它。 例如,powershell.exe -command '<powershell command>'。 若使用 PowerShell,您需要使用 Azure 儲存體模組的 3.11.0 版本。
(選擇性) 重新命名應用程式 Blob 和組態 Blob Azure 無法保留原始檔案名稱和副檔名。 因此,下載的應用程式檔案和設定檔的預設名稱為「MyVMApp」和「MyVMApp-config」,沒有副檔名。 您可以使用安裝指令碼以副檔名重新命名檔案,也可以傳遞 configFileName名稱publishingProfile和屬性。 然後,Azure 會在下載檔案時使用這些名稱,而不是預設名稱。
(選擇性) 將應用程式和組態 Blob 移至適當的位置 Azure 會將應用程式 Blob 和設定 Blob 下載至下列位置。 必要時,安裝指令碼必須將檔案移至適當的位置。
Linux的: /var/lib/waagent/Microsoft.CPlat.Core.VMApplicationManagerLinux/<application name>/<application version>
視窗: C:\Packages\Plugins\Microsoft.CPlat.Core.VMApplicationManagerWindows\1.0.16\Downloads\<application name>\<application version>
取消封存應用程式 Blob 對於已封存的應用程式套件,在安裝應用程式之前,需要取消封存。 建議使用 .zip 或 .tar,因為大多數作業系統都內建支援取消封存這些格式。 對於其他格式,請確定客體作業系統提供支援。
(選擇性) 設定正確的執行原則和權限 取消封存之後,可以重設檔案權限。 在執行檔案之前設定正確的權限是一個很好的做法。
將指令碼轉換為字串安裝指令碼會以 Azure VM 應用程式版本資源中install屬性的publishingProfile字串形式傳遞。
以下是以應用程式 Blob 副檔名為基礎的範例安裝腳本
#!/bin/bash
# Rename blobs
mv MyVMApp app.tar
mv MyVMApp-config app-config.yaml
# Unarchive application
mkdir -p app
tar -xf app.tar -C app
# Set permissions
chmod -R +x app
chmod -R +r app
# Install the script (example: install.sh with config)
bash ./app/install.sh --config app-config.yaml
# OR Install the .deb package (example: install.deb without config)
# sudo dpkg -i ./app/install.deb
# OR Install the .rpm package (example: install.rpm without config)
# sudo rpm -ivh ./app/install.rpm
腳本作為字串:
"#!/bin/bash\nmv MyVMApp app.tar\nmv MyVMApp-config app-config.yaml\nmkdir -p app\ntar -xf app.tar -C app\nchmod -R +x app\nchmod -R +r app\nbash ./app/install.sh --config app-config.yaml\n# sudo dpkg -i ./app/install.deb\n# sudo rpm -ivh ./app/install.rpm"
:: Rename blobs
rename MyVMApp app.zip
rename MyVMApp-config app-config.json
:: Unzip using built-in tar (available on Windows 10+)
mkdir app
tar -xf app.zip -C app
:: Install .exe application (example: setup.exe with config)
app\setup.exe /config app-config.json
:: install .msi application (example: setup.exe without config)
:: msiexec /i app\setup.msi /qn /l*v install.log
:: Install JavaScript (example: setup.js with config)
:: cscript //nologo app\setup.js app-config.json
:: Install python script (example: install.py with config) - Needs python pre-installed
:: python app\install.py app-config.json
:: Install ruby application (example: install.rb with config) - Needs Ruby pre-installed
:: ruby app\install.rb app-config.json
腳本作為字串:
"rename MyVMApp app.zip\r\nrename MyVMApp-config app-config.json\r\nmkdir app\r\ntar -xf app.zip -C app\r\napp\\setup.exe /config app-config.json\r\n:: msiexec /i app\\setup.msi /qn /l*v install.log\r\n:: cscript //nologo app\\setup.js app-config.json\r\n:: python app\\install.py app-config.json\r\n:: ruby app\\install.rb app-config.json"
powershell.exe -command "
# Rename blobs
Rename-Item -Path '.\MyVMApp' -NewName 'app.zip'
Rename-Item -Path '.\MyVMApp-config' -NewName 'app-config.json'
# Unzip application package
Expand-Archive -Path '.\app.zip' -DestinationPath '.\app'
# Set execution policy
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
# Install the .exe application (example: setup.exe with config)
Start-Process -FilePath '.\app\setup.exe' -ArgumentList '/config app-config.json' -Wait
# Install PowerShell script (example: setup.ps1 with config)
# powershell.exe -ExecutionPolicy Bypass -File '.\app\setup.ps1' -ConfigFile 'app-config.json'
# Install .msi application (example: setup.msi without config)
# Start-Process -FilePath 'msiexec.exe' -ArgumentList '/i .\app\setup.msi /qn /l*v install.log' -Wait
"
腳本作為字串:
"powershell.exe -command \"Rename-Item -Path '.\\MyVMApp' -NewName 'app.zip'; Rename-Item -Path '.\\MyVMApp-config' -NewName 'app-config.json'; Expand-Archive -Path '.\\app.zip' -DestinationPath '.\\app'; Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force; Start-Process -FilePath '.\\app\\setup.exe' -ArgumentList '/config app-config.json' -Wait; # powershell.exe -ExecutionPolicy Bypass -File '.\\app\\setup.ps1' -ConfigFile 'app-config.json'; # Start-Process -FilePath 'msiexec.exe' -ArgumentList '/i .\\app\\setup.msi /qn /l*v install.log' -Wait\""
:: Rename blobs
rename MyVMApp app.exe
rename MyVMApp-config app-config.json
:: Run the installer with config
app.exe /config app-config.json
腳本作為字串:
"rename MyVMApp app.exe\r\nrename MyVMApp-config app-config.json\r\napp.exe /config app-config.json"
powershell.exe -command "
# Rename blobs
Rename-Item -Path '.\MyVMApp' -NewName 'app.exe'
Rename-Item -Path '.\MyVMApp-config' -NewName 'app-config.json'
# Set execution policy
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
# Install the .exe application (example: setup.exe with config)
Start-Process -FilePath '.\app.exe' -ArgumentList '/config app-config.json' -Wait
"
腳本作為字串:
"powershell.exe -command \"Rename-Item -Path '.\\MyVMApp' -NewName 'app.exe'; Rename-Item -Path '.\\MyVMApp-config' -NewName 'app-config.json'; Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force; Start-Process -FilePath '.\\app.exe' -ArgumentList '/config app-config.json' -Wait\""
:: Rename blobs
rename MyVMApp app.msi
rename MyVMApp-config app-config.json
:: install .msi application (example: setup.exe without config)
msiexec /i app.msi /qn /l*v install.log
腳本作為字串:
"rename MyVMApp app.msi\r\nrename MyVMApp-config app-config.json\r\nmsiexec /i app.msi /qn /l*v install.log"
powershell.exe -command "
# Rename blobs
Rename-Item -Path '.\MyVMApp' -NewName 'app.zip'
Rename-Item -Path '.\MyVMApp-config' -NewName 'app-config.json'
# Set execution policy
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
# Install .msi application (example: setup.msi without config)
Start-Process -FilePath 'msiexec.exe' -ArgumentList '/i .\app\setup.msi /qn /l*v install.log' -Wait
"
腳本作為字串:
"powershell.exe -command \"Rename-Item -Path '.\\MyVMApp' -NewName 'app.zip'; Rename-Item -Path '.\\MyVMApp-config' -NewName 'app-config.json'; Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force; Start-Process -FilePath 'msiexec.exe' -ArgumentList '/i .\\app\\setup.msi /qn /l*v install.log' -Wait\""
#!/bin/bash
# Rename blobs
mv MyVMApp app.deb
mv MyVMApp-config app-config.yaml
# Set permissions
chmod -R +x app.deb
chmod -R +r app.deb
# Install .deb package (example: install.deb without config)
# sudo dpkg -i ./app.deb
腳本作為字串:
"#!/bin/bash\nmv MyVMApp app.deb\nmv MyVMApp-config app-config.yaml\nchmod -R +x app.deb\nchmod -R +r app.deb\n# sudo dpkg -i ./app.deb"
#!/bin/bash
# Rename blobs
mv MyVMApp app.rpm
mv MyVMApp-config app-config.yaml
# Set permissions
chmod -R +x app.rpm
chmod -R +r app.rpm
# Install .rpm package (example: install.rpm without config)
sudo rpm -ivh ./app.rpm
腳本作為字串:
"#!/bin/bash\nmv MyVMApp app.rpm\nmv MyVMApp-config app-config.yaml\nchmod -R +x app.rpm\nchmod -R +r app.rpm\nsudo rpm -ivh ./app.rpm"
#!/bin/bash
# Rename blobs
mv MyVMApp app.sh
mv MyVMApp-config app-config.yaml
# Set permissions
chmod -R +x app.sh
chmod -R +r app.sh
# Install the script (example: install.sh with config)
bash ./app.sh --config app-config.yaml
腳本作為字串:
"#!/bin/bash\nmv MyVMApp app.sh\nmv MyVMApp-config app-config.yaml\nchmod -R +x app.sh\nchmod -R +r app.sh\nbash ./app.sh --config app-config.yaml"
powershell.exe -command "
# Rename blobs
Rename-Item -Path '.\MyVMApp' -NewName 'app.ps1'
Rename-Item -Path '.\MyVMApp-config' -NewName 'app-config.json'
# Set execution policy
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
# Install PowerShell script (example: setup.ps1 with config)
powershell.exe -ExecutionPolicy Bypass -File '.\app.ps1' -ConfigFile 'app-config.json'
"
腳本作為字串:
"powershell.exe -command \"Rename-Item -Path '.\\MyVMApp' -NewName 'app.ps1'; Rename-Item -Path '.\\MyVMApp-config' -NewName 'app-config.json'; Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force; powershell.exe -ExecutionPolicy Bypass -File '.\\app.ps1' -ConfigFile 'app-config.json'\""
4. 建立刪除指令碼
刪除指令碼可讓您定義應用程式的刪除作業。 刪除指令碼以字串形式提供,字元限制上限為 4,096 個字元。 假設應用程式套件和組態檔位於目前目錄中,請撰寫 delete 指令。
刪除指令碼必須執行的作業可能很少。
卸載應用程式: 從 VM 正確解除安裝應用程式。 例如,在 Windows 或 uninstall.exe Linux 上執行sudo apt remove app。
刪除殘留文件: 從 VM 中刪除殘留的應用程式檔案。 例如,在 Windows 或 Remove-Item -Path "$PWD\*" -Recurse -Force -ErrorAction SilentlyContinue Linux 上執行sudo rm -rf ./* ./.??*。
將應用程式檔案上傳至 Azure 儲存體帳戶
應用程式可儲存於區塊或分頁 Blob。 若選擇使用分頁 Blob,上傳前則需位元對齊檔案。 使用下列範例來位元組對齊您的檔案。
inputFile="<the file you want to pad>"
# Get the file size
fileSize=$(stat -c %s "$inputFile")
# Calculate the remainder when divided by 512
remainder=$((fileSize % 512))
if [ "$remainder" -ne 0 ]; then
# Calculate how many bytes to pad
difference=$((512 - remainder))
# Create padding (empty bytes)
dd if=/dev/zero bs=1 count=$difference >> "$inputFile"
fi
$inputFile = <the file you want to pad>
$fileInfo = Get-Item -Path $inputFile
$remainder = $fileInfo.Length % 512
if ($remainder -ne 0){
$difference = 512 - $remainder
$bytesToPad = [System.Byte[]]::CreateInstance([System.Byte], $difference)
Add-Content -Path $inputFile -Value $bytesToPad -Encoding Byte
}
2. 產生應用程式套件和組態檔的 SAS URL
將應用程式和組態檔上傳至儲存體帳戶之後,您必須產生具有這些 Blob 讀取許可權的 SAS URL 。 然後,在建立 VM 應用程式版本資源時,會提供這些 SAS URL 作為參考。 對於已啟用匿名存取的儲存體帳戶,也可以使用 Blob URL。 不過,建議使用 SAS URL 來改善安全性。 若還沒有 SAS URI,您可以使用儲存體總管以快速建立。
#!/bin/bash
# === CONFIGURATION ===
STORAGE_ACCOUNT="yourstorageaccount"
CONTAINER_NAME="yourcontainer"
LOCAL_FOLDER="./your-local-folder"
SAS_EXPIRY_HOURS=24
# === LOGIN (if not already logged in) ===
az login --only-show-errors
# === CREATE CONTAINER IF NOT EXISTS ===
az storage container create \
--name $CONTAINER_NAME \
--account-name $STORAGE_ACCOUNT \
--auth-mode login \
--only-show-errors
# === UPLOAD FILES ===
az storage blob upload-batch \
--account-name $STORAGE_ACCOUNT \
--destination $CONTAINER_NAME \
--source $LOCAL_FOLDER \
--auth-mode login \
--only-show-errors
# === GENERATE SAS URLs ===
echo "Generating SAS URLs..."
FILES=$(find $LOCAL_FOLDER -type f)
for FILE in $FILES; do
BLOB_NAME="${FILE#$LOCAL_FOLDER/}"
EXPIRY=$(date -u -d "+$SAS_EXPIRY_HOURS hours" '+%Y-%m-%dT%H:%MZ')
SAS_TOKEN=$(az storage blob generate-sas \
--account-name $STORAGE_ACCOUNT \
--container-name $CONTAINER_NAME \
--name "$BLOB_NAME" \
--permissions r \
--expiry $EXPIRY \
--auth-mode login \
-o tsv)
SAS_URL="https://${STORAGE_ACCOUNT}.blob.core.windows.net/${CONTAINER_NAME}/${BLOB_NAME}?${SAS_TOKEN}"
echo "$BLOB_NAME: $SAS_URL"
done
# === CONFIGURATION ===
$storageAccount = "yourstorageaccount"
$containerName = "yourcontainer"
$localFolder = "C:\path\to\your\local\folder"
$sasExpiryHours = 24
# === LOGIN (if not already logged in) ===
az login | Out-Null
# === CREATE CONTAINER IF NOT EXISTS ===
az storage container create `
--name $containerName `
--account-name $storageAccount `
--auth-mode login `
--only-show-errors | Out-Null
# === UPLOAD FILES ===
az storage blob upload-batch `
--account-name $storageAccount `
--destination $containerName `
--source $localFolder `
--auth-mode login `
--only-show-errors
# === GENERATE SAS URLs ===
Write-Host "`nGenerating SAS URLs..."
$files = Get-ChildItem -Recurse -File -Path $localFolder
foreach ($file in $files) {
$relativePath = $file.FullName.Substring($localFolder.Length + 1).Replace("\", "/")
$expiry = (Get-Date).ToUniversalTime().AddHours($sasExpiryHours).ToString("yyyy-MM-ddTHH:mmZ")
$sasToken = az storage blob generate-sas `
--account-name $storageAccount `
--container-name $containerName `
--name $relativePath `
--permissions r `
--expiry $expiry `
--auth-mode login `
-o tsv
$sasUrl = "https://$storageAccount.blob.core.windows.net/$containerName/$relativePath`?$sasToken"
Write-Host "$relativePath:`n$sasUrl`n"
}
建立 VM 應用程式
若要建立 VM 應用程式,請先建立描述應用程式的 VM 應用程式資源。 然後在其中建立 VM 應用程式版本資源,其中包含 VM 應用程式承載和腳本,以安裝、更新和刪除應用程式。 承載會使用 SAS URL 提供給 Azure 儲存體帳戶中的 Blob 容器。
請參閱 VM 應用程式和 VM 應用程式版本資源的架構 ,以深入瞭解每個屬性。
使用「建立資源庫應用程式 API」建立 VM 應用程式定義
PUT
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/applications/{applicationName}?api-version=2024-03-03
{
"location": "West US",
"name": "myApp",
"properties": {
"supportedOSType": "Windows | Linux",
"endOfLifeDate": "2020-01-01",
"description": "Description of the App",
"eula": "Link to End-User License Agreement (EULA)",
"privacyStatementUri": "Link to privacy statement for the application",
"releaseNoteUri": "Link to release notes for the application"
}
}
使用 「建立資源庫應用程式版本 API」 來建立虛擬機器應用程式版本。
PUT
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/galleries/{galleryName}/applications/{applicationName}/versions/{versionName}?api-version=2024-03-03
{
"location": "$location",
"properties": {
"publishingProfile": {
"source": {
"mediaLink": "$mediaLink",
"defaultConfigurationLink": "$configLink"
},
"manageActions": {
"install": "echo installed",
"remove": "echo removed",
"update": "echo update"
},
"targetRegions": [
{
"name": "West US",
"regionalReplicaCount": 1
},
{
"name": "East US"
}
]
"endofLifeDate": "datetime",
"replicaCount": 1,
"excludeFromLatest": false,
"storageAccountType": "PremiumV2_LRS | Premium_LRS | Standard_LRS | Standard_ZRS"
"safetyProfile": {
"allowDeletionOfReplicatedLocations": false
}
"settings": {
"scriptBehaviorAfterReboot": "None | Rerun",
"configFileName": "$appConfigFileName",
"packageFileName": "$appPackageFileName"
}
}
}
VM 應用程式需 Azure CLI 2.30.0 版本或更新版本。
使用 'az sig gallery-application create' 建立 VM 應用程式定義。 在此範例中,我們會為 Linux 型 VM 建立名為 myApp 的 VM 應用程式定義。
az sig gallery-application create \
--application-name myApp \
--gallery-name myGallery \
--resource-group myResourceGroup \
--os-type Linux \
--location "East US"
使用 'az sig gallery-application version create' 建立 VM 應用程式版本。 版本允許的字元是數字及句點。 數字必須在 32 位元整數的範圍內。 格式:MajorVersion.MinorVersion.Patch。
將參數值取代為自己的值。
az sig gallery-application version create \
--version-name 1.0.0 \
--application-name myApp \
--gallery-name myGallery \
--location "East US" \
--resource-group myResourceGroup \
--package-file-link "https://<storage account name>.blob.core.windows.net/<container name>/<filename>" \
--install-command "mv myApp .\myApp\myApp" \
--remove-command "rm .\myApp\myApp" \
--update-command "mv myApp .\myApp\myApp" \
--default-configuration-file-link "https://<storage account name>.blob.core.windows.net/<container name>/<filename>"\
使用 New-AzGalleryApplication建立 VM 應用程式定義。 在此範例中,我們會在 myGallery Azure 計算資源庫中和 myGallery 資源群組中建立名為 myApp 的 Linux 應用程式。 視需要取代變數的值。
$galleryName = "myGallery"
$rgName = "myResourceGroup"
$applicationName = "myApp"
$description = "Backend Linux application for finance."
New-AzGalleryApplication `
-ResourceGroupName $rgName `
-GalleryName $galleryName `
-Location "East US" `
-Name $applicationName `
-SupportedOSType Linux `
-Description $description
使用 New-AzGalleryApplicationVersion建立 VM 應用程式的版本。 版本允許的字元是數字及句點。 數字必須在 32 位元整數的範圍內。 格式:MajorVersion.MinorVersion.Patch。
在此範例中,我們會建立版本號碼 1.0.0。 視需要取代變數的值。
$galleryName = "myGallery"
$rgName = "myResourceGroup"
$applicationName = "myApp"
$version = "1.0.0"
New-AzGalleryApplicationVersion `
-ResourceGroupName $rgName `
-GalleryName $galleryName `
-GalleryApplicationName $applicationName `
-Name $version `
-PackageFileLink "https://<storage account name>.blob.core.windows.net/<container name>/<filename>" `
-DefaultConfigFileLink "https://<storage account name>.blob.core.windows.net/<container name>/<filename>" `
-Location "East US" `
-Install "mv myApp .\myApp\myApp" `
-Remove "rm .\myApp\myApp" `
- 請前往 [Azure 入口網站],再搜尋並選取 [Azure Compute Gallery]。
- 從資源庫選取您要使用的映像。
- 在資源庫分頁上,請在頁面頂端選取 [新增],再從下拉式清單中選取 [VM 應用程式定義]。 [建立 VM 應用程式定義] 頁面隨即開啟。
- 在 [基本] 索引標籤中,輸入應用程式的名稱,再選擇應用程式適用於執行 Linux 或Windows的 VM。
- 如果您要為 VM 應用程式定義指定以下任何選擇性設定,請選擇 發行選項 索引標籤:
- VM 應用程式定義的描述。
- 生命週期結束日期
- 連結至最終使用者授權協議(EULA)
- 隱私權聲明的 URI
- 版本資訊的 URI
- 當您完成時,選取 [檢閱 + 建立]。
- 驗證完成時,選取 [建立] 以部署定義。
- 部署完成後,請選取 [前往資源]。
- 在應用程式的頁面上,選取 [建立 VM 應用程式版本]。 [建立 VM 應用程式版本] 頁面隨即開啟。
- 輸入版本號碼,例如 1.0.0.
- 選取上傳應用程式套件的區域。
- 在 [來源應用程式套件] 下,選取 [瀏覽]。 選取 [儲存體帳戶],再選取套件所在的容器。 從清單中選取套件,完成時選取 [選取]。 或者,如有需要,您也可以將 SAS URI 貼到此欄位中。
- 提供「安裝腳本」。 您也可以提供「卸載腳本」和「更新腳本」。 如需建立指定碼的相關資訊,請參閱概觀。
- 若上傳預設設定檔至儲存體帳戶,您可以在 [預設設定檔] 中選取。
- 建立 VM 時不想將此版本顯示為最新版本,選取 [從最新版本排除]。
- 針對 [生命日期結束],選取未來日期以追蹤此版本應淘汰的時間。 這不會自動刪除或移除版本,僅用於自行追蹤。
- 若要將此版本複寫至其他區域,請選取 [ 複 寫] 索引標籤、新增更多區域,以及變更每個區域的複本數目。 版本建立時的原始區域必須在清單上,且無法將其移除。
- 完成變更後,選擇頁面下方的 [檢閱 + 建立]。
- 驗證顯示為通過後,選取 [建立] 以部署 VM 應用程式版本。
name: Deploy Azure VM Application
on:
push:
branches:
- main
env:
# Customize your app and config filenames here
APP_FILE: app.exe
CONFIG_FILE: app-config.json
AZURE_RESOURCE_GROUP: ${{ secrets.AZURE_RESOURCE_GROUP }}
AZURE_LOCATION: ${{ secrets.AZURE_LOCATION }}
AZURE_STORAGE_ACCOUNT: ${{ secrets.AZURE_STORAGE_ACCOUNT }}
AZURE_CONTAINER_NAME: ${{ secrets.AZURE_CONTAINER_NAME }}
GALLERY_NAME: ${{ secrets.GALLERY_NAME }}
APPLICATION_NAME: ${{ secrets.AZURE_VM_APPLICATION_NAME }}
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
# Step 1: Checkout repo
- name: Checkout
uses: actions/checkout@v4
# Step 2: Login to Azure using OIDC
- name: Azure Login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
# Step 3: Upload app and config files to Azure Blob
- name: Upload files to Azure Blob Storage
run: |
set -euo pipefail
echo "Creating container if missing..."
az storage container create \
--name "$AZURE_CONTAINER_NAME" \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--auth-mode login \
--only-show-errors
echo "Uploading files..."
az storage blob upload \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$APP_FILE" \
--file "$APP_FILE" \
--auth-mode login \
--only-show-errors
az storage blob upload \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$CONFIG_FILE" \
--file "$CONFIG_FILE" \
--auth-mode login \
--only-show-errors
# Step 4: Create VM Application (if missing)
- name: Create VM Application if missing
run: |
set -euo pipefail
echo "Checking for existing VM Application..."
if ! az sig gallery-application show \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--name "$APPLICATION_NAME" &>/dev/null; then
az sig gallery-application create \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--name "$APPLICATION_NAME" \
--location "$AZURE_LOCATION" \
--os-type Windows
fi
# Step 5: Generate SAS URLs
- name: Generate SAS URLs
id: sas
run: |
set -euo pipefail
echo "Generating SAS URLs valid for 24 hours..."
EXPIRY=$(date -u -d "+1 day" '+%Y-%m-%dT%H:%MZ')
APP_SAS=$(az storage blob generate-sas \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$APP_FILE" \
--permissions r \
--expiry "$EXPIRY" \
--auth-mode login -o tsv)
CONFIG_SAS=$(az storage blob generate-sas \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$CONFIG_FILE" \
--permissions r \
--expiry "$EXPIRY" \
--auth-mode login -o tsv)
echo "APP_SAS=$APP_SAS" >> $GITHUB_ENV
echo "CONFIG_SAS=$CONFIG_SAS" >> $GITHUB_ENV
# Step 6: Create Application Version using semantic versioning
- name: Create VM Application Version
run: |
set -euo pipefail
# Generate a unique version name
MAJOR=1
MINOR=0
PATCH=$(date +%Y%m%d)
VERSION="$MAJOR.$MINOR.$PATCH"
# Load install/uninstall commands from .txt files as strings
INSTALL_CMD=$(jq -Rs '.' < install-script-as-string.txt)
REMOVE_CMD=$(jq -Rs '.' < uninstall-script-as-string.txt)
PACKAGE_URL="https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_CONTAINER_NAME}/${APP_FILE}?${APP_SAS}"
CONFIG_URL="https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_CONTAINER_NAME}/${CONFIG_FILE}?${CONFIG_SAS}"
# Create the version
az sig gallery-application version create \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--gallery-application-name "$APPLICATION_NAME" \
--gallery-application-version-name "$VERSION" \
--version-name "$VERSION" \
--location "$AZURE_LOCATION" \
--package-file-link "$PACKAGE_URL" \
--default-file-link "$CONFIG_URL" \
--install-command "$INSTALL_CMD" \
--remove-command "$REMOVE_CMD" \
--only-show-errors
trigger:
branches:
include: [ main ]
variables:
# Customize filenames below
APP_FILE: app.exe
CONFIG_FILE: app-config.json
AZURE_RESOURCE_GROUP: $(AZURE_RESOURCE_GROUP)
AZURE_LOCATION: $(AZURE_LOCATION)
AZURE_STORAGE_ACCOUNT: $(AZURE_STORAGE_ACCOUNT)
AZURE_CONTAINER_NAME: $(AZURE_CONTAINER_NAME)
GALLERY_NAME: $(GALLERY_NAME)
APPLICATION_NAME: $(AZURE_VM_APPLICATION_NAME)
stages:
- stage: DeployVMApp
displayName: Upload files and deploy Azure VM Application
jobs:
- job: Deploy
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: self
# Step 1: Upload files to Blob
- task: AzureCLI@2
displayName: Upload app (exe, zip, etc) + config to Blob
inputs:
azureSubscription: 'AzureServiceConnection'
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
set -euo pipefail
echo "Creating container if it doesn't exist..."
az storage container create \
--name "$AZURE_CONTAINER_NAME" \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--auth-mode login \
--only-show-errors
echo "Uploading files..."
az storage blob upload \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$APP_FILE" \
--file "$APP_FILE" \
--auth-mode login \
--only-show-errors
az storage blob upload \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$CONFIG_FILE" \
--file "$CONFIG_FILE" \
--auth-mode login --only-show-errors
# Step 2: Create VM Application Definition (if not exists)
- task: AzureCLI@2
displayName: Create VM Application Definition
inputs:
azureSubscription: 'AzureServiceConnection'
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
set -euo pipefail
echo "Checking for existing VM Application..."
if ! az sig gallery-application show \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--name "$APPLICATION_NAME" &>/dev/null; then
echo "Creating new VM Application..."
az sig gallery-application create \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--application-name "$APPLICATION_NAME" \
--location "$AZURE_LOCATION" \
--os-type Windows
else
echo "VM Application definition already exists."
fi
# Step 3: Generate SAS URLs
- task: AzureCLI@2
displayName: Generate SAS URLs
inputs:
azureSubscription: 'AzureServiceConnection'
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
set -euo pipefail
echo "Generating SAS URLs valid for 24 hours..."
EXPIRY=$(date -u -d "+1 day" '+%Y-%m-%dT%H:%MZ')
APP_SAS=$(az storage blob generate-sas \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$APP_FILE" \
--permissions r \
--expiry "$EXPIRY" \
--auth-mode login -o tsv)
CONFIG_SAS=$(az storage blob generate-sas \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$CONFIG_FILE" \
--permissions r \
--expiry "$EXPIRY" \
--auth-mode login -o tsv)
echo "##vso[task.setvariable variable=APP_SAS]$APP_SAS"
echo "##vso[task.setvariable variable=CONFIG_SAS]$CONFIG_SAS"
# Step 4: Create VM Application Version
- task: AzureCLI@2
displayName: Create VM Application Version
inputs:
azureSubscription: 'AzureServiceConnection'
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
set -euo pipefail
# Generate a unique version name
MAJOR=1
MINOR=0
PATCH=$(date +%Y%m%d)
VERSION="$MAJOR.$MINOR.$PATCH"
# Load install/uninstall commands from .txt files as strings
INSTALL_CMD=$(jq -Rs '.' < install-script-as-string.txt)
REMOVE_CMD=$(jq -Rs '.' < uninstall-script-as-string.txt)
# Load SAS URL for Application and config file
PACKAGE_URL="https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_CONTAINER_NAME}/${APP_FILE}?${APP_SAS}"
CONFIG_URL="https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_CONTAINER_NAME}/${CONFIG_FILE}?${CONFIG_SAS}"
# Create the version
az sig gallery-application version create \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--application-name "$APPLICATION_NAME" \
--name "$VERSION" \
--location "$AZURE_LOCATION" \
--package-file-link "$PACKAGE_URL" \
--default-configuration-file-link "$CONFIG_URL" \
--install-command "$INSTALL_CMD" \
--remove-command "$REMOVE_CMD" \
--version-name $VERSION
stages:
- deploy
variables:
# Customize your filenames here
APP_FILE: "app.exe"
CONFIG_FILE: "app-config.json"
AZURE_RESOURCE_GROUP: "$AZURE_RESOURCE_GROUP"
AZURE_LOCATION: "$AZURE_LOCATION"
AZURE_STORAGE_ACCOUNT: "$AZURE_STORAGE_ACCOUNT"
AZURE_CONTAINER_NAME: "$AZURE_CONTAINER_NAME"
GALLERY_NAME: "$GALLERY_NAME"
APPLICATION_NAME: "$AZURE_VM_APPLICATION_NAME"
deploy_vm_app:
image: mcr.microsoft.com/azure-cli
stage: deploy
only:
- main
script:
# Login to Azure using service principal
- az login --service-principal -u "$AZURE_CLIENT_ID" -p "$AZURE_CLIENT_SECRET" --tenant "$AZURE_TENANT_ID"
- az account set --subscription "$AZURE_SUBSCRIPTION_ID"
# Step 1: Upload app and config files to Blob Storage
- |
echo "Uploading $APP_FILE and $CONFIG_FILE to blob..."
az storage container create \
--name "$AZURE_CONTAINER_NAME" \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--auth-mode login \
--only-show-errors
az storage blob upload \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$APP_FILE" \
--file "$APP_FILE" \
--auth-mode login \
--only-show-errors
az storage blob upload \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$CONFIG_FILE" \
--file "$CONFIG_FILE" \
--auth-mode login \
--only-show-errors
# Step 2: Create VM Application Definition if missing
- |
echo "Checking for existing VM Application..."
if ! az sig gallery-application show \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--application-name "$APPLICATION_NAME" &>/dev/null; then
echo "Creating VM Application definition..."
az sig gallery-application create \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--application-name "$APPLICATION_NAME" \
--location "$AZURE_LOCATION" \
--os-type Windows \
--only-show-errors
else
echo "VM Application already exists."
fi
# Step 3: Generate SAS URLs
- |
EXPIRY=$(date -u -d "+1 day" '+%Y-%m-%dT%H:%MZ')
APP_SAS=$(az storage blob generate-sas \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$APP_FILE" \
--permissions r \
--expiry "$EXPIRY" \
--auth-mode login -o tsv)
CONFIG_SAS=$(az storage blob generate-sas \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$CONFIG_FILE" \
--permissions r \
--expiry "$EXPIRY" \
--auth-mode login -o tsv)
# Step 4: Create VM Application Version (semantic version: 1.0.YYYYMMDD)
- |
MAJOR=1
MINOR=0
PATCH=$(date +%Y%m%d)
VERSION="$MAJOR.$MINOR.$PATCH"
echo "Creating VM Application Version: $VERSION"
INSTALL_CMD=$(jq -Rs '.' < install-script-as-string.txt)
REMOVE_CMD=$(jq -Rs '.' < uninstall-script-as-string.txt)
az sig gallery-application version create \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--application-name "$APPLICATION_NAME" \
--gallery-application-version-name "$VERSION" \
--version-name "$VERSION" \
--location "$AZURE_LOCATION" \
--package-file-link "https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_CONTAINER_NAME}/${APP_FILE}?${APP_SAS}" \
--default-configuration-file-link "https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_CONTAINER_NAME}/${CONFIG_FILE}?${CONFIG_SAS}" \
--install-command "$INSTALL_CMD" \
--remove-command "$REMOVE_CMD" \
--only-show-errors
pipeline {
agent any
environment {
APP_FILE = 'app.exe'
CONFIG_FILE = 'app-config.json'
AZURE_RESOURCE_GROUP = credentials('AZURE_RESOURCE_GROUP')
AZURE_LOCATION = credentials('AZURE_LOCATION')
AZURE_STORAGE_ACCOUNT = credentials('AZURE_STORAGE_ACCOUNT')
AZURE_CONTAINER_NAME = credentials('AZURE_CONTAINER_NAME')
GALLERY_NAME = credentials('GALLERY_NAME')
APPLICATION_NAME = credentials('AZURE_VM_APPLICATION_NAME')
AZURE_CLIENT_ID = credentials('AZURE_CLIENT_ID')
AZURE_CLIENT_SECRET = credentials('AZURE_CLIENT_SECRET')
AZURE_TENANT_ID = credentials('AZURE_TENANT_ID')
AZURE_SUBSCRIPTION_ID = credentials('AZURE_SUBSCRIPTION_ID')
}
stages {
stage('Login to Azure') {
steps {
sh '''
az login --service-principal \
--username "$AZURE_CLIENT_ID" \
--password "$AZURE_CLIENT_SECRET" \
--tenant "$AZURE_TENANT_ID"
az account set --subscription "$AZURE_SUBSCRIPTION_ID"
'''
}
}
stage('Upload to Blob Storage') {
steps {
sh '''
az storage container create \
--name "$AZURE_CONTAINER_NAME" \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--auth-mode login --only-show-errors
az storage blob upload \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$APP_FILE" \
--file "$APP_FILE" \
--auth-mode login --only-show-errors
az storage blob upload \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$CONFIG_FILE" \
--file "$CONFIG_FILE" \
--auth-mode login --only-show-errors
'''
}
}
stage('Create VM Application if Needed') {
steps {
sh '''
if ! az sig gallery-application show \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--application-name "$APPLICATION_NAME" &>/dev/null; then
az sig gallery-application create \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--application-name "$APPLICATION_NAME" \
--location "$AZURE_LOCATION" \
--os-type Windows
fi
'''
}
}
stage('Generate SAS URLs') {
steps {
sh '''
export EXPIRY=$(date -u -d "+1 day" '+%Y-%m-%dT%H:%MZ')
export APP_SAS=$(az storage blob generate-sas \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$APP_FILE" \
--permissions r \
--expiry "$EXPIRY" \
--auth-mode login -o tsv)
export CONFIG_SAS=$(az storage blob generate-sas \
--account-name "$AZURE_STORAGE_ACCOUNT" \
--container-name "$AZURE_CONTAINER_NAME" \
--name "$CONFIG_FILE" \
--permissions r \
--expiry "$EXPIRY" \
--auth-mode login -o tsv)
echo "APP_SAS=$APP_SAS" > sas.env
echo "CONFIG_SAS=$CONFIG_SAS" >> sas.env
'''
}
}
stage('Create Application Version') {
steps {
sh '''
source sas.env
MAJOR=1
MINOR=0
PATCH=$(date +%Y%m%d)
VERSION="$MAJOR.$MINOR.$PATCH"
INSTALL_CMD=$(jq -Rs '.' < install-script-as-string.txt)
REMOVE_CMD=$(jq -Rs '.' < uninstall-script-as-string.txt)
az sig gallery-application version create \
--resource-group "$AZURE_RESOURCE_GROUP" \
--gallery-name "$GALLERY_NAME" \
--application-name "$APPLICATION_NAME" \
--gallery-application-version-name "$VERSION" \
--version-name "$VERSION" \
--location "$AZURE_LOCATION" \
--package-file-link "https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_CONTAINER_NAME}/${APP_FILE}?$APP_SAS" \
--default-configuration-file-link "https://${AZURE_STORAGE_ACCOUNT}.blob.core.windows.net/${AZURE_CONTAINER_NAME}/${CONFIG_FILE}?$CONFIG_SAS" \
--install-command "$INSTALL_CMD" \
--remove-command "$REMOVE_CMD" \
--only-show-errors
'''
}
}
}
}
部署 VM 應用程式
現在可以在 Azure VM 或 Azure 虛擬機器擴展集中參考 applicationProfile 一或多個 VM 應用程式。 然後,Azure 會提取 VM 應用程式的承載,並使用提供的安裝腳本將其安裝在每個 VM 上。 此 order 屬性定義虛擬機器應用程式在虛擬機器上安裝的循序順序。
請參閱 VM/虛擬機器擴展集的 applicationProfile 架構 ,以深入瞭解每個屬性。
請在 VM 上執行 PUT 以新增 VM 應用程式版本至 VM。
PUT
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{VMName}?api-version=2024-03-03
{
"properties": {
"applicationProfile": {
"galleryApplications": [
{
"order": 1,
"packageReferenceId": "/subscriptions/{subscriptionId}/resourceGroups/<resource group>/providers/Microsoft.Compute/galleries/{gallery name}/applications/{application name}/versions/{version | latest}",
"configurationReference": "{path to configuration storage blob}",
"treatFailureAsDeploymentFailure": false
}
]
}
},
"name": "{vm name}",
"id": "/subscriptions/{subscriptionId}/resourceGroups/{resource group}/providers/Microsoft.Compute/virtualMachines/{vm name}",
"location": "{vm location}"
}
若要將 VM 應用程式套用至統一擴展集:
PUT
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{VMSSName}?api-version=2024-03-03
{
"properties": {
"virtualMachineProfile": {
"applicationProfile": {
"galleryApplications": [
{
"order": 1,
"packageReferenceId": "/subscriptions/{subscriptionId}/resourceGroups/<resource group>/providers/Microsoft.Compute/galleries/{gallery name}/applications/{application name}/versions/{version | latest}",
"configurationReference": "{path to configuration storage blob}",
"treatFailureAsDeploymentFailure": false
}
]
}
}
},
"name": "{vm name}",
"id": "/subscriptions/{subscriptionId}/resourceGroups/{resource group}/providers/Microsoft.Compute/virtualMachines/{vm name}",
"location": "{vm location}"
}
回應將會包含完整的 VM 模型。 以下是相關的元件。
{
"name": "{vm name}",
"id": "{vm id}",
"type": "Microsoft.Compute/virtualMachines",
"location": "{vm location}",
"properties": {
"applicationProfile": {
"galleryApplications": ""
},
"provisioningState": "Updating"
},
"resources": [
{
"name": "VMAppExtension",
"id": "{extension id}",
"type": "Microsoft.Compute/virtualMachines/extensions",
"location": "centraluseuap",
"properties": "@{autoUpgradeMinorVersion=True; forceUpdateTag=7c4223fc-f4ea-4179-ada8-c8a85a1399f5; provisioningState=Creating; publisher=Microsoft.CPlat.Core; type=VMApplicationManagerLinux; typeHandlerVersion=1.0; settings=}"
}
]
}
使用 'az vm application set' 將 VM 應用程式設定為現有的 VM,並將參數的值取代為您自己的。
az vm application set \
--resource-group myResourceGroup \
--name myVM \
--app-version-ids /subscriptions/{subID}/resourceGroups/MyResourceGroup/providers/Microsoft.Compute/galleries/myGallery/applications/myApp/versions/1.0.0 \
--treat-deployment-as-failure true
若要在 VM 上設定多個應用程式:
az vm application set \
--resource-group myResourceGroup \
--name myVM \
--app-version-ids /subscriptions/{subId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/galleries/myGallery/applications/myApp/versions/1.0.0 /subscriptions/{subId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/galleries/myGallery/applications/myApp2/versions/1.0.1 \
--treat-deployment-as-failure true true
若要將應用程式新增至虛擬機擴展集,請使用 'az vmss application set':
az vmss application set \
--resource-group myResourceGroup \
--name myVmss \
--app-version-ids /subscriptions/{subId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/galleries/myGallery/applications/myApp/versions/1.0.0 \
--treat-deployment-as-failure true
若要將多個應用程式新增至虛擬機擴展集:
az vmss application set \
--resource-group myResourceGroup \
--name myVmss
--app-version-ids /subscriptions/{subId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/galleries/myGallery/applications/myApp/versions/1.0.0 /subscriptions/{subId}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/galleries/myGallery/applications/myApp2/versions/1.0.0 \
--treat-deployment-as-failure true
若要新增應用程式至現有 VM,請取得應用程式版本,再使用其取得 VM 應用程式版本識別碼。 使用識別碼以新增應用程式至 VM 設定。
$galleryName = "myGallery"
$rgName = "myResourceGroup"
$applicationName = "myApp"
$version = "1.0.0"
$vmName = "myVM"
$vm = Get-AzVM -ResourceGroupName $rgname -Name $vmName
$appVersion = Get-AzGalleryApplicationVersion `
-GalleryApplicationName $applicationName `
-GalleryName $galleryName `
-Name $version `
-ResourceGroupName $rgName
$packageId = $appVersion.Id
$app = New-AzVmGalleryApplication -PackageReferenceId $packageId
Add-AzVmGalleryApplication -VM $vm -GalleryApplication $app -TreatFailureAsDeploymentFailure true
Update-AzVM -ResourceGroupName $rgName -VM $vm
若要將應用程式新增至虛擬機擴展集:
$vmss = Get-AzVmss -ResourceGroupName $rgname -Name $vmssName
$appVersion = Get-AzGalleryApplicationVersion `
-GalleryApplicationName $applicationName `
-GalleryName $galleryName `
-Name $version `
-ResourceGroupName $rgName
$packageId = $appVersion.Id
$app = New-AzVmssGalleryApplication -PackageReferenceId $packageId
Add-AzVmssGalleryApplication -VirtualMachineScaleSetVM $vmss.VirtualMachineProfile -GalleryApplication $app
Update-AzVmss -ResourceGroupName $rgName -VirtualMachineScaleSet $vmss -VMScaleSetName $vmssName
現在您可以使用入口網站,建立 VM 和對其部署 VM 應用程式。 僅需像往常一樣建立 VM,並在 [進階] 索引標籤下選擇 [選取要安裝的 VM 應用程式]。
從清單中選取 VM 應用程式,然後選取頁面底部的 [ 儲存 ]。
若有要安裝多於一個 VM 應用程式,您可以設定回到 [進階] 索引標籤,設定每個 VM 應用程式的安裝順序。
您也可以將 VM 應用程式部署到目前正在執行的 VM。 在入口網站中檢視 VM 詳細資料時,選取左側功能表中 [設定] 底下的 [延伸模組 + 應用程式] 選項。
選擇 [VM 應用程式],然後選取 [新增應用程式] 以新增 VM 應用程式。
從清單中選取 VM 應用程式,然後選取頁面底部的 [ 儲存 ]。
下一步
深入瞭解 Azure VM 應用程式。
瞭解如何 管理、更新或刪除 Azure VM 應用程式。