共用方式為


Marketplace 產品的程序設計部署

本文說明如何使用 Azure CLI、Azure PowerShell 和 Terraform 將 Marketplace 產品資源部署至 Azure。

先決條件

您需要安裝 Azure PowerShell 並連線到 Azure:

Azure CLI 2.2.0 版中的部署命令已變更。 本文中的範例需要 Azure CLI 2.20.0 版或更新版本,

若要執行此範例,請安裝最新版的 Azure CLI。 若要啟動,請執行

az login

以建立與 Azure 的連線。

如何尋找發行者、供應和方案的 Marketplace 產品識別碼

若要以程式設計方式部署 Marketplace 產品,您必須先取得 Marketplace 產品的唯一標識符。

若要尋找唯一識別碼:

  1. 開啟 Azure 入口網站並流覽至 Marketplace 體驗。

  2. 搜尋您想要部署的 Marketplace 產品

  3. 選取產品名稱以開啟產品詳細數據頁面。

  4. 流覽至 [使用資訊 + 支援] 索引標籤。在 [使用資訊] 中,會出現 [發行者標識符]、[產品標識符] 和 [方案標識符]。

產品標識碼頁面的螢幕快照。

注意

在某些 API 中,產品識別碼也稱為供應專案標識碼,方案標識碼也稱為 SKU 標識碼。

來自 Azure Marketplace 的虛擬機

若要從 Azure Marketplace 部署第三方 VM,您必須先接受所部署 VM 映射的使用者許可協定 (EULA)。 在 Azure 訂用帳戶中接受一次 EULA 之後,您應該能夠再次部署相同的 VM 供應專案,而不需要再次接受條款。 如果您要從 Azure 入口網站部署 VM,則會在那裡接受條款。 不過,當您以程式設計方式進行部署時,必須使用 az vm image terms accept --publisher X --offer Y --plan Z 或使用ARM接受條款。

如果尚未接受條款,則會顯示下列錯誤:

Code : MarketplacePurchaseEligibilityFailed
Message: Marketplace purchase eligibility check returned errors. See inner errors for details
Details: Offer with PublisherId: '<PublisherId>', OfferId: '<OfferId>' cannot be purchased due to validation errors. For more information see details. Correlation Id: 'aaaa0000-bb11-2222-33cc-444444dddddd' You have not accepted the legal terms on this subscription: 'aaaa0000-bb11-2222-33cc-444444dddddd' for this plan. Before the subscription can be used, you need to accept the legal terms of the image. To read and accept legal terms, use the Azure CLI commands described at https://go.microsoft.com/fwlink/?linkid=2110637 or the PowerShell commands available at https://go.microsoft.com/fwlink/?linkid=862451. Alternatively, deploying via the Azure portal provides a UI experience for reading and accepting the legal terms.

使用 Azure CLI 從 Azure Marketplace 部署 VM

接受條款之後,您可以使用ARM/Bicep 範本、Azure CLI、Terraform等一般方法來部署 VM。

若要深入瞭解如何尋找 VM 映射、接受條款並使用 CLI 部署 VM,請參閱 使用 CLI尋找和使用市集購買方案資訊。

使用 Terraform 從 Azure Marketplace 部署 VM

如何使用 Terraform 部署 Windows VMLinux VM的虛擬機器指南。

若要使用 Terraform 來部署 Marketplace VM,您必須執行下列動作:

  1. 使用 azurerm_marketplace_agreement 來同意 VM 產品的法律條款

  2. azurerm_virtual_machine 提供者中,指定 plan 區塊。

注意

如果未指定計畫區塊,部署將會失敗,並出現下列錯誤:

Code: VMMarketplaceInvalidInput Message: Creating a virtual machine from Marketplace image or a custom image sourced from a Marketplace image requires Plan information in the request. VM: '/subscriptions/<Subscription ID>/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/myVM

注意

azurerm_marketplace_agreement 被視為 Terraform 資源,因此,當您第一次建立特定的 Marketplace VM 產品時,系統會建立唯一的資源來代表已接受法律條款的事實。 不過,下次嘗試在相同的 Azure 訂用帳戶下部署另一個 VM(具有相同的發行者識別碼和供應專案識別符),您會收到錯誤:

A resource with the ID "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e /providers/Microsoft.MarketplaceOrdering/agreements/<Publisher ID>/offers/<Product ID>/plans/<Plan ID>" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_marketplace_agreement" for more information

您必須執行 Terraform state list,以檢查您是否有 azurerm_marketplace_agreement 資源狀態,如果沒有,則需將該資源狀態匯入到 Terraform 狀態中。

terraform import azurerm_marketplace_agreement.<TerraformResourceName> /subscriptions/<AzureSubscriptionId>/providers/Microsoft.MarketplaceOrdering/agreements/<Publisher ID>/offers/<Product ID>/plans/<Plan ID>

來自 Azure Marketplace 的 SaaS 供應專案

SaaS 供應專案通常是由客戶透過 Azure 入口網站部署。 使用 Azure 入口網站部署 SaaS 供應項目之後,客戶會使用 [立即設定帳戶] 按鈕來流覽 SaaS ISV 的登陸頁面,並完成 SaaS 供應項目的設定。 設定供應項目之後,SaaS ISV 會使用 SaaS 履行 API 加以啟用。

當您透過 Azure 入口網站部署 SaaS 供應專案時,它會建立 ARM 範本,並指派部署的特定參數值。 其中一個參數是 termId,用於識別優惠的訂閱期限。 termId 值不是靜態的,但取決於供應專案組態和部署時間。 因此,您無法在 ARM 範本中使用固定的 termId 值。 相反地,您必須遵循下列步驟來找出目前的 termId 值:

  1. 透過 Azure 入口網站手動部署優惠。
  2. 移至部署供應項目的資源群組。
  3. 選取 [部署] 區段底下的部署名稱。
  4. 檢視輸入參數,並複製termId的值。

如果指定的 SaaS 供應項目從未部署在 Azure 訂用帳戶中,程式設計部署會失敗,並出現如下錯誤:

code: DeploymentFailed

message: At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage

Details: Failed to process eligibility check with error Purchase has failed due to signature verification on Marketplace legal agreement. Please retry. If error persists use different Azure subscription, or contact support with correlation-id 'aaaa0000-bb11-2222-33cc-444444dddddd' and this error message

使用ARM樣本和 Azure CLI 部署 SaaS 供應專案

請參閱ARM範例範本。

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "name": {
            "type": "string"
        },
        "planId": {
            "type": "string"
        },
        "offerId": {
            "type": "string"
        },
        "publisherId": {
            "type": "string"
        },
        "quantity": {
            "type": "int"
        },
        "termId": {
            "type": "string"
        },
        "azureSubscriptionId": {
            "type": "string"
        },
        "publisherTestEnvironment": {
            "type": "string",
            "defaultValue": ""
        },
        "autoRenew": {
            "type": "bool"
        }
    },
    "resources": [
        {
            "type": "Microsoft.SaaS/resources",
            "apiVersion": "2018-03-01-beta",
            "name": "[parameters('name')]",
            "location": "global",
            "properties": {
                "saasResourceName": "[parameters('name')]",
                "publisherId": "[parameters('publisherId')]",
                "SKUId": "[parameters('planId')]",
                "offerId": "[parameters('offerId')]",
                "quantity": "[parameters('quantity')]",
                "termId": "[parameters('termId')]",
                "autoRenew": "[parameters('autoRenew')]",
                "paymentChannelType": "SubscriptionDelegated",
                "paymentChannelMetadata": {
                    "AzureSubscriptionId": "[parameters('azureSubscriptionId')]"
                },
                "publisherTestEnvironment": "[parameters('publisherTestEnvironment')]",
                "storeFront": "AzurePortal"
            }
        }
    ]
}

  • 將上述儲存為 SaaS-ARM.json
  • 執行下列命令:
az group create --resource-group <ResourceGroupName> --location <Location>

az deployment group create --resource-group <Resource Group Name> --template-file ./SaaS-ARM.json --parameters name=<SaaS Resource Name> publisherId=<Publisher ID> offerId=<Product ID> planId=<Plan ID> termId=<termId> quantity=1 azureSubscriptionId=11111111-1111-1111-1111-11111111 autoRenew=true

布建 SaaS 供應專案資源之後,您可以叫用下列 ARM API 來檢視其屬性:

az rest --method get --uri /subscriptions/<AzureSubscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.SaaS/resources/<SaaS Resource Name>?api-version=2018-03-01-beta -o json

現在您可以進行 POST 呼叫,以取得市集令牌和登陸頁面 URL。 此 URL 可用來流覽 SaaS ISV 的登陸頁面,以完成設定及啟用 SaaS 供應專案。

az rest --method post --uri /subscriptions/<AzureSubscriptionId>/resourceGroups/<ResourceGroupName> /providers/Microsoft.SaaS/resources/<SaaS Resource Name>/listAccessToken?api-version=2018-03-01-beta -o json

如需詳細資訊,請參閱這裡 - Microsoft.SaaS 資源提供者的規格

使用 Terraform 從 Azure Marketplace 部署 SaaS 供應專案

請檢閱上一節,說明如何使用ARM部署 SaaS 供應專案,因為 Terraform 部署會與使用 ARM 範本相同。

Azure Marketplace 的 Azure 應用程式

Azure 應用程式產品類型是獨特的供應專案,可讓發行者建立 ARM 範本,其中包含一組 Azure 資源和 Marketplace 產品群組,並設定為提供功能完整的多重資源應用程式,Azure 應用程式有三種方案類型:

  • 解決方案範本 - 免費供應專案、ARM 範本部署
  • 受控應用程式 - 免費或付費方案,建立 Microsoft.Solutions/applications 資源類型

Azure 入口網站會產生適用於 Azure 應用程式 (受控應用程式) 部署的 ARM 範本。 此 ARM 範本會建立類型為 Microsoft.Solutions/applications 的資源,指向特定方案,並從客戶在 Azure 入口網站中填寫的 UI 字段傳入應用程式特定參數。

接受 Azure 受控應用程式條款

如同虛擬機供應專案,若要使用ARM範本以程式設計方式將Azure 應用程式(受控應用程式)部署至 Azure 訂用帳戶,訂用帳戶必須接受 Azure 受控應用程式方案的條款。 當透過 Azure 入口網站進行部署時,使用者對條款的接受是隱含的,之後在相同 Azure 訂用帳戶中以程式設計方式部署相同方案時便不會出現問題。

您也可以使用在上面 VM 一節中所述的相同 az vm image terms accept,接受有關 Azure 應用程式(受控應用程式)方案的條款。

如果 Azure 應用程式(受控應用程式)產品是付費產品(例如,它使用每月或計量付費計費),則您用來部署的 Azure 訂用帳戶必須與有效的付款方式相關聯(例如,它不能是免費或贊助的訂用帳戶)。

使用 ARM 樣本與 Azure CLI 部署 Azure 應用程式 (受控應用程式)

以下是部署受控應用程式的 ARM 範例。

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
            "type": "string",
            "allowedValues": [
                "westus2",
                "westeurope",
                "eastus",
                "northeurope",
                "centralus",
                "eastus2",
                "francecentral",
                "uksouth"
            ]
        },
        "applicationResourceName": {
            "type": "string"
        },
        "managedResourceGroupId": {
            "type": "string",
            "defaultValue": ""
        },
        "managedIdentity": {
            "type": "object",
            "defaultValue": {}
        },
        "initialConsulVersion": {
            "type": "string",
            "defaultValue": "v1.11.2"
        },
        "storageAccountName": {
            "type": "string",
            "defaultValue": "[concat('storage', uniqueString(resourceGroup().id, deployment().name))]"
        },
        "blobContainerName": {
            "type": "string",
            "defaultValue": "[concat('blob', uniqueString(resourceGroup().id, deployment().name))]"
        },
        "identityName": {
            "type": "string",
            "defaultValue": "[concat(parameters('clusterName'), '-identity')]"
        },
        "clusterMode": {
            "type": "string",
            "defaultValue": "PRODUCTION",
            "allowedValues": [
                "PRODUCTION",
                "DEVELOPMENT"
            ]
        },
        "clusterName": {
            "type": "string",
            "defaultValue": "cluster"
        },
        "consulDataCenter": {
            "type": "string",
            "defaultValue": "dc1"
        },
        "numServers": {
            "type": "string",
            "defaultValue": "3"
        },
        "numServersDevelopment": {
            "type": "string",
            "defaultValue": "1"
        },
        "automaticUpgrades": {
            "type": "string",
            "defaultValue": "disabled"
        },
        "consulConnect": {
            "type": "string",
            "defaultValue": "enabled"
        },
        "externalEndpoint": {
            "type": "string",
            "defaultValue": "enabled"
        },
        "snapshotInterval": {
            "type": "string",
            "defaultValue": "1d"
        },
        "snapshotRetention": {
            "type": "string",
            "defaultValue": "1m"
        },
        "consulVnetCidr": {
            "type": "string",
            "defaultValue": "172.25.16.0/24"
        },
        "providerBaseURL": {
            "defaultValue": "https://ama-api.hashicorp.cloud/consulama/2021-04-23",
            "type": "String",
            "metadata": {
                "description": "The URI of the custom provider API"
            }
        },
        "email": {
            "type": "string"
        },
        "federationToken": {
            "type": "string",
            "defaultValue": ""
        },
        "sourceChannel": {
            "type": "string",
            "defaultValue": "azure-portal"
        },
        "auditLoggingEnabled": {
            "type": "string",
            "defaultValue": "disabled",
            "allowedValues": [
                "enabled",
                "disabled"
            ]
        },
        "auditLogStorageContainerURL": {
            "type": "string",
            "defaultValue": ""
        }
    },
    "variables": {
    },
    "resources": [
        {
            "type": "Microsoft.Solutions/applications",
            "apiVersion": "2017-09-01",
            "name": "[parameters('applicationResourceName')]",
            "location": "[parameters('location')]",
            "kind": "MarketPlace",
            "identity": "[if(empty(parameters('managedIdentity')),json('null'),parameters('managedIdentity'))]",
            "plan": {
                "name": "<Plan ID>",
                "product": "<Product ID>",
                "publisher": "<Publisher ID>",
                "version": "<Version>"
            },
            "properties": {
                "managedResourceGroupId": "[parameters('managedResourceGroupId')]",
                "parameters": {
                    "initialConsulVersion": {
                        "value": "[parameters('initialConsulVersion')]"
                    },
                    "storageAccountName": {
                        "value": "[parameters('storageAccountName')]"
                    },
                    "blobContainerName": {
                        "value": "[parameters('blobContainerName')]"
                    },
                    "identityName": {
                        "value": "[parameters('identityName')]"
                    },
                    "clusterMode": {
                        "value": "[parameters('clusterMode')]"
                    },
                    "clusterName": {
                        "value": "[parameters('clusterName')]"
                    },
                    "consulDataCenter": {
                        "value": "[parameters('consulDataCenter')]"
                    },
                    "numServers": {
                        "value": "[parameters('numServers')]"
                    },
                    "numServersDevelopment": {
                        "value": "[parameters('numServersDevelopment')]"
                    },
                    "automaticUpgrades": {
                        "value": "[parameters('automaticUpgrades')]"
                    },
                    "consulConnect": {
                        "value": "[parameters('consulConnect')]"
                    },
                    "externalEndpoint": {
                        "value": "[parameters('externalEndpoint')]"
                    },
                    "snapshotInterval": {
                        "value": "[parameters('snapshotInterval')]"
                    },
                    "snapshotRetention": {
                        "value": "[parameters('snapshotRetention')]"
                    },
                    "consulVnetCidr": {
                        "value": "[parameters('consulVnetCidr')]"
                    },
                    "location": {
                        "value": "[parameters('location')]"
                    },
                    "providerBaseURL": {
                        "value": "[parameters('providerBaseURL')]"
                    },
                    "email": {
                        "value": "[parameters('email')]"
                    },
                    "federationToken": {
                        "value": "[parameters('federationToken')]"
                    },
                    "sourceChannel": {
                        "value": "[parameters('sourceChannel')]"
                    },
                    "auditLoggingEnabled": {
                        "value": "[parameters('auditLoggingEnabled')]"
                    },
                    "auditLogStorageContainerURL": {
                        "value": "[parameters('auditLogStorageContainerURL')]"
                    }
                },
                "jitAccessPolicy": null
            }
        }
    ]
}

然後執行下列命令:

az group create --resource-group <Resource Group Name> --location <location>

az deployment group create --resource-group avmanagedapp100 --template-file <ARM Template JSON file> --parameters location=<location> applicationResourceName=<Resource Group Name> managedResourceGroupId=/subscriptions/<Subscription ID>/resourceGroups/<Resource Group Name>  email=<email address>

使用 Terraform 從 Azure Marketplace 部署 Azure 受控應用程式

請檢閱上一節,說明如何使用ARM部署 Azure 受控應用程式供應專案,因為 Terraform 部署會使用相同的 ARM 範本。

Azure Marketplace 的解決方案範本

從 Azure Marketplace 部署 解決方案範本(非 Azure 受控應用程式)商品時,部署只是 ISV 發佈的 ARM 範本,其中對應的使用者介面欄位作為參數傳遞。 若要以程式設計方式部署解決方案範本供應專案,請使用 Azure 入口網站來執行部署、複製 ARM 範本,並在後續部署中使用。 由於解決方案範本不是「付費」供應專案,因此不需要接受任何特殊條款。 不過,如果解決方案範本 ARM 範本參考 Azure Marketplace 中的 VM 映像檔,您必須先接受 VM 供應專案 的條款,如同 VM 供應專案所述。