快速入門:使用 Bicep 建立和發佈 Azure 受控應用程式定義
本快速入門說明如何使用 Bicep 在服務類別目錄中建立和發佈 Azure 受控應用程式定義。 服務類別目錄中的定義可供組織成員使用。
若要建立受控應用程式定義並發佈至您的服務類別目錄,請執行下列工作:
- 使用 Bicep 來開發您的範本,並將其轉換為 Azure Resource Manager 範本 (ARM 範本)。 此範本會定義受控應用程式所部署的 Azure 資源。
- 使用 Bicep
build
命令將 Bicep 轉換為 JSON。 將檔案轉換成 JSON 之後,請驗證程式碼的正確性。 - 部署受控應用程式時,定義入口網站的使用者介面元素。
- 建立包含必要 JSON 檔案的 .zip 套件。 .zip 套件檔案對於服務類別目錄的受控應用程式定義具有 120 MB 限制。
- 發佈受控應用程式定義,使其可在您的服務類別目錄中使用。
如果您的受控應用程式定義超過 120 MB,或基於組織的合規性原因而想使用自己的儲存體帳戶,請移至快速入門:自備儲存體來建立及發佈 Azure 受控應用程式定義。
您也可以使用 Bicep 從服務類別目錄部署受控應用程式定義。 如需詳細資訊,請移至 快速入門:使用 Bicep 部署 Azure 受控應用程式定義。
必要條件
若要完成這篇文章中的工作,您需要下列項目︰
- 具有作用中訂用帳戶,以及對 Microsoft Entra 資源 (例如使用者、群組或服務主體) 具有權限的 Azure 帳戶。 如果您沒有帳戶,請在開始之前建立免費帳戶。
- Visual Studio Code 搭配最新的 Azure Resource Manager 工具延伸模組。 針對 Bicep 檔案,請安裝適用於 Visual Studio Code 的 Bicep 延伸模組。
- 安裝最新版的 Azure PowerShell 或 Azure CLI。
建立 Bicep 檔案
每個受控應用程式定義都包含名為 mainTemplate.json 的檔案。 此範本會定義要部署的 Azure 資源,而且與一般 ARM 範本不同。 您可以使用 Bicep 來開發範本,然後將 Bicep 檔案轉換成 JSON。
開啟 Visual Studio Code,建立具有區分大小寫名稱 mainTemplate.bicep 的檔案,並加以儲存。
新增下列 Bicep 程式碼並儲存檔案。 它會定義受控應用程式的資源,以部署 App Service、App Service 方案和儲存體帳戶。
param location string = resourceGroup().location
@description('App Service plan name.')
@maxLength(40)
param appServicePlanName string
@description('App Service name prefix.')
@maxLength(47)
param appServiceNamePrefix string
var appServicePlanSku = 'B1'
var appServicePlanCapacity = 1
var appServiceName = '${appServiceNamePrefix}${uniqueString(resourceGroup().id)}'
var linuxFxVersion = 'DOTNETCORE|8.0'
resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
name: appServicePlanName
location: location
sku: {
name: appServicePlanSku
capacity: appServicePlanCapacity
}
kind: 'linux'
properties: {
zoneRedundant: false
reserved: true
}
}
resource appService 'Microsoft.Web/sites@2023-01-01' = {
name: appServiceName
location: location
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
redundancyMode: 'None'
siteConfig: {
linuxFxVersion: linuxFxVersion
minTlsVersion: '1.2'
ftpsState: 'Disabled'
}
}
}
output appServicePlan string = appServicePlanName
output appServiceApp string = appService.properties.defaultHostName
將 Bicep 轉換為 JSON
使用 PowerShell 或 Azure CLI 來建置 mainTemplate.json 檔案。 移至儲存 Bicep 檔案的目錄並執行 build
命令。
bicep build mainTemplate.bicep
若要深入了解,請移至 Bicep build。
將 Bicep 檔案轉換成 JSON 之後,您的 mainTemplate.json 檔案應該符合下列範例。 在 version
和 templateHash
的 metadata
屬性中,您可能有不同的值。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.30.3.12046",
"templateHash": "16466621031230437685"
}
},
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"appServicePlanName": {
"type": "string",
"maxLength": 40,
"metadata": {
"description": "App Service plan name."
}
},
"appServiceNamePrefix": {
"type": "string",
"maxLength": 47,
"metadata": {
"description": "App Service name prefix."
}
}
},
"variables": {
"appServicePlanSku": "B1",
"appServicePlanCapacity": 1,
"appServiceName": "[format('{0}{1}', parameters('appServiceNamePrefix'), uniqueString(resourceGroup().id))]",
"linuxFxVersion": "DOTNETCORE|8.0"
},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2023-01-01",
"name": "[parameters('appServicePlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[variables('appServicePlanSku')]",
"capacity": "[variables('appServicePlanCapacity')]"
},
"kind": "linux",
"properties": {
"zoneRedundant": false,
"reserved": true
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2023-01-01",
"name": "[variables('appServiceName')]",
"location": "[parameters('location')]",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]",
"httpsOnly": true,
"redundancyMode": "None",
"siteConfig": {
"linuxFxVersion": "[variables('linuxFxVersion')]",
"minTlsVersion": "1.2",
"ftpsState": "Disabled"
}
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]"
]
}
],
"outputs": {
"appServicePlan": {
"type": "string",
"value": "[parameters('appServicePlanName')]"
},
"appServiceApp": {
"type": "string",
"value": "[reference(resourceId('Microsoft.Web/sites', variables('appServiceName')), '2023-01-01').defaultHostName]"
}
}
}
定義入口網站體驗
身為發行者,您可以定義用來建立受控應用程式的入口網站體驗。 createUiDefinition.json 檔案會產生入口網站使用者介面。 您可以使用下拉式清單和文字輸入框等控制項元素,定義使用者為每個參數提供輸入的方式。
在此範例中,使用者介面會提示您輸入 App Service 名稱前置詞和 App Service 方案的名稱。 在 mainTemplate.json 部署期間,appServiceName
變數會使用 uniqueString
函式,將 13 個字元的字串附加至名稱前置詞,讓名稱在 Azure 中是全域唯一的。
開啟 Visual Studio Code,建立具有區分大小寫名稱 createUiDefinition.json 的檔案,並加以儲存。
將下列 JSON 程式碼新增至檔案,並加以儲存。
{
"$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
"handler": "Microsoft.Azure.CreateUIDef",
"version": "0.1.2-preview",
"parameters": {
"basics": [
{}
],
"steps": [
{
"name": "webAppSettings",
"label": "Web App settings",
"subLabel": {
"preValidation": "Configure the web app settings",
"postValidation": "Completed"
},
"elements": [
{
"name": "appServicePlanName",
"type": "Microsoft.Common.TextBox",
"label": "App Service plan name",
"placeholder": "App Service plan name",
"defaultValue": "",
"toolTip": "Use alphanumeric characters or hyphens with a maximum of 40 characters.",
"constraints": {
"required": true,
"regex": "^[a-z0-9A-Z-]{1,40}$",
"validationMessage": "Only alphanumeric characters or hyphens are allowed, with a maximum of 40 characters."
},
"visible": true
},
{
"name": "appServiceName",
"type": "Microsoft.Common.TextBox",
"label": "App Service name prefix",
"placeholder": "App Service name prefix",
"defaultValue": "",
"toolTip": "Use alphanumeric characters or hyphens with minimum of 2 characters and maximum of 47 characters.",
"constraints": {
"required": true,
"regex": "^[a-z0-9A-Z-]{2,47}$",
"validationMessage": "Only alphanumeric characters or hyphens are allowed, with a minimum of 2 characters and maximum of 47 characters."
},
"visible": true
}
]
}
],
"outputs": {
"location": "[location()]",
"appServicePlanName": "[steps('webAppSettings').appServicePlanName]",
"appServiceNamePrefix": "[steps('webAppSettings').appServiceName]"
}
}
}
如需詳細資訊,請參閱開始使用 CreateUiDefinition。
封裝檔案
將兩個檔案新增至名為 app.zip 的封裝檔案。 這兩個檔案必須位於 .zip 檔案的根層級。 如果這些檔案在資料夾中,當建立受控應用程式定義時,您會收到錯誤,指出必要的檔案不存在。
將 app.zip 上傳至 Azure 儲存體帳戶,以便在部署受控應用程式定義時使用。 儲存體帳戶名稱在整個 Azure 中必須是全域唯一的,長度必須是 3-24 個字元,且只有小寫字母和數字。 在命令中,以您唯一的儲存體帳戶名稱取代預留位置 <pkgstorageaccountname>
,包括角括弧 (<>
)。
在 Visual Studio Code 中,開啟新的 PowerShell 終端機並登入您的 Azure 訂用帳戶。
Connect-AzAccount
此命令會開啟您的預設瀏覽器,並提示您登入 Azure。 如需詳細資訊,請移至使用 Azure PowerShell 登入。
在您連線之後,請執行下列命令。
New-AzResourceGroup -Name packageStorageGroup -Location westus
$pkgstorageparms = @{
ResourceGroupName = "packageStorageGroup"
Name = "<pkgstorageaccountname>"
Location = "westus"
SkuName = "Standard_LRS"
Kind = "StorageV2"
MinimumTlsVersion = "TLS1_2"
AllowBlobPublicAccess = $true
AllowSharedKeyAccess = $false
}
$pkgstorageaccount = New-AzStorageAccount @pkgstorageparms
$pkgstorageparms
變數會使用 PowerShell splatting (部分機器翻譯) 來改善命令中所用參數值的可讀性,以建立新的儲存體帳戶。 其他使用多個參數值的 PowerShell 命令會使用 Splatting。
建立儲存體帳戶之後,請將角色指派儲存體 Blob 資料參與者新增至儲存體帳戶範圍。 指派對 Microsoft Entra 使用者帳戶的存取權限。 根據您在 Azure 中的存取層級而定,您可能需要管理員指派的其他權限。 如需詳細資訊,請參閱指派 Azure 角色以存取 Blob 資料 (部分機器翻譯) 和使用 Azure 入口網站指派 Azure 角色。
將該角色新增至儲存體帳戶之後,需要幾分鐘的時間才會在 Azure 中變成作用中。 然後,您便可以建立要建立容器和上傳檔案所需的內容。
$pkgstoragecontext = New-AzStorageContext -StorageAccountName $pkgstorageaccount.StorageAccountName -UseConnectedAccount
New-AzStorageContainer -Name appcontainer -Context $pkgstoragecontext -Permission blob
$blobparms = @{
File = "app.zip"
Container = "appcontainer"
Blob = "app.zip"
Context = $pkgstoragecontext
}
Set-AzStorageBlobContent @blobparms
使用下列命令,將封裝檔案的 URI 儲存在名為 packageuri
的變數中。 您部署受控應用程式定義時,將會使用變數的值。
$packageuri=(Get-AzStorageBlob -Container appcontainer -Blob app.zip -Context $pkgstoragecontext).ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri
建立受控應用程式定義
在本節中,您會從 Microsoft Entra ID 取得身分識別資訊、建立資源群組,以及部署受控應用程式定義。
取得群組識別碼和角色定義識別碼
下一個步驟是選取要代表客戶管理資源的使用者、安全性群組或應用程式。 此身分識別會根據指派的角色,取得受控資源群組的權限。 角色可以是任何內建的 Azure 角色,例如擁有者或參與者。
此範例使用安全性群組,而您的 Microsoft Entra 帳戶應該是群組的成員。 若要取得群組的物件識別碼,請使用群組的名稱取代預留位置 <managedAppDemo>
,包括角括號 (<>
)。 當您部署受控應用程式定義時,將會使用變數的值。
若要建立新的 Microsoft Entra 群組,請移至管理 Microsoft Entra 群組和群組成員資格。
$principalid=(Get-AzADGroup -DisplayName <managedAppDemo>).Id
接下來,取得您想要為其授與使用者、群組或應用程式存取權之 Azure 內建角色的角色定義識別碼。 當您部署受控應用程式定義時,將會使用變數的值。
$roleid=(Get-AzRoleDefinition -Name Owner).Id
建立定義部署範本
使用 Bicep 檔案在服務類別目錄中部署受控應用程式定義。
開啟 Visual Studio Code,建立名稱為 deployDefinition.bicep 的檔案並加以儲存。
新增下列 Bicep 程式碼並儲存檔案。
param location string = resourceGroup().location
@description('Name of the managed application definition.')
param managedApplicationDefinitionName string
@description('The URI of the .zip package file.')
param packageFileUri string
@description('Publishers Principal ID that needs permissions to manage resources in the managed resource group.')
param principalId string
@description('Role ID for permissions to the managed resource group.')
param roleId string
var definitionLockLevel = 'ReadOnly'
var definitionDisplayName = 'Sample Bicep managed application'
var definitionDescription = 'Sample Bicep managed application that deploys web resources'
resource managedApplicationDefinition 'Microsoft.Solutions/applicationDefinitions@2021-07-01' = {
name: managedApplicationDefinitionName
location: location
properties: {
lockLevel: definitionLockLevel
description: definitionDescription
displayName: definitionDisplayName
packageFileUri: packageFileUri
authorizations: [
{
principalId: principalId
roleDefinitionId: roleId
}
]
}
}
如需範本屬性的詳細資訊,請參閱 Microsoft.Solutions/applicationDefinitions。
受控資源群組上的 lockLevel
可以避免客戶在此資源群組上執行非預期的作業。 目前唯一支援的鎖定等級是 ReadOnly
。 ReadOnly
規定客戶只能讀取受控資源群組中存在的資源。 被授與受控資源群組存取權的發行者身分識別不受鎖定等級的限制。
建立參數檔案
受控應用程式定義的部署範本要求為多個參數輸入值。 部署命令會提示您輸入值,您也可以為值建立參數檔案。 在此範例中,我們使用參數檔案將參數值傳遞至部署命令。
在 Visual Studio Code 中,建立名為「deployDefinition-parameters.bicepparam」的新檔案並加以儲存。
將下列內容新增至參數檔案並加以儲存。 將包含角括弧在內的 <placeholder values>
(即 <>
) 取代為您的訂用帳戶識別碼。
using './deployDefinition.bicep'
param managedApplicationDefinitionName = 'sampleBicepManagedApplication'
param packageFileUri = '<placeholder for the packageFileUri>'
param principalId = '<placeholder for principalid value>'
param roleId = '<placeholder for roleid value>'
下表描述受控應用程式定義的參數值。
參數 | 值 |
---|---|
managedApplicationDefinitionName |
受控應用程式定義的名稱。 在此範例中,請使用 sampleBicepManagedApplication。 |
packageFileUri |
輸入 .zip 封裝檔案的 URI。 使用 packageuri 變數的值。 |
principalId |
需要管理受控資源群組中資源之權限的發行者主體 ID。 使用 principalid 變數的值。 |
roleId |
受控資源群組許可權的角色識別碼。 例如擁有者、參與者或讀者。 使用 roleid 變數的值。 |
若要取得變數值:
- Azure PowerShell:在 PowerShell 中,輸入
$variableName
以顯示變數的值。 - Azure CLI:在 Bash 中,輸入
echo $variableName
以顯示變數的值。
部署定義
在您部署受控應用程式的定義後,定義就會在您的服務類別目錄中變成可用狀態。 此程式不會部署受控應用程式的資源。
建立名為「bicepDefinitionGroup」的資源群組,並部署受控應用程式定義。
New-AzResourceGroup -Name bicepDefinitionGroup -Location westus
$deployparms = @{
ResourceGroupName = "bicepDefinitionGroup"
TemplateFile = "deployDefinition.bicep"
TemplateParameterFile = "deployDefinition-parameters.bicepparam"
Name = "deployDefinition"
}
New-AzResourceGroupDeployment @deployparms
驗證結果
執行下列命令來確認定義已發佈在您的服務類別目錄中。
Get-AzManagedApplicationDefinition -ResourceGroupName bicepDefinitionGroup
Get-AzManagedApplicationDefinition
會列出指定資源群組 (例如 sampleBicepManagedApplication) 中所有可用的定義。
請確定使用者可以存取您的定義
您可以存取受控應用程式定義,但您想確保您組織中的其他使用者可以存取它。 至少在定義上將讀者角色授與給他們。 他們可能已從訂用帳戶或資源群組繼承此存取層級。 若要查看可存取定義和新增使用者或群組的人員,請參閱使用 Azure 入口網站指派 Azure 角色。
清除資源
如果您要部署定義,請繼續移至後續步驟一節,其連結到使用 Bicep 部署定義的文章。
如果您已完成受控應用程式定義,就可刪除您所建立名為「packageStorageGroup」和「bicepDefinitionGroup」的資源群組。
命令會提示您確認要移除資源群組。
Remove-AzResourceGroup -Name packageStorageGroup
Remove-AzResourceGroup -Name bicepDefinitionGroup
下一步
您已發佈受控應用程式定義。 下一個步驟是了解如何部署該定義的執行個體。