本文內容
在本文中,您將了解如何使用 Terraform 設定檔來建立 Azure Machine Learning 工作區。 Terraform (部分機器翻譯) 的範本型設定檔讓您能夠以可重複且可預測的方式定義、建立和設定 Azure 資源。 Terraform 會追蹤資源狀態,而且可以清除和終結資源。
Terraform 設定檔是定義了部署所需資源的文件。 Terraform 設定也可以指定部署變數,以用來在套用設定時提供輸入值。
必要條件
具有免費或付費版 Azure Machine Learning 的 Azure 訂用帳戶。 如尚未擁有 Azure 訂用帳戶,請在開始之前先建立免費帳戶 。
根據快速入門:安裝和設定 Terraform (部分機器翻譯) 中的指示安裝及設定好 Terraform。
限制
建立新的工作區時,您可以自動建立工作區所需的服務,或使用現有的服務。 若要使用有別於工作區的不同 Azure 訂閱的現有服務 ,您必須在包含這些服務的訂閱中註冊 Azure Machine Learning 命名空間。 例如,若要在訂用帳戶 A (使用訂用帳戶 B 的儲存體帳戶) 中建立工作區,則必須先在訂用帳戶 B 中註冊 Azure Machine Learning 命名空間,然後工作區才能使用該儲存體帳戶。
Azure Machine Learning 的資源提供者為 Microsoft.MachineLearningServices 。 如需查看是否已註冊或正在註冊它的相關資訊,請參閱 Azure 資源提供者和類型 。
重要
此資訊僅適用建立工作區期間所提供的資源:Azure 儲存體帳戶、Azure Container Registry、Azure Key Vault 和 Application Insights。
建立工作區
建立名為 main.tf 且具有下列程式碼的檔案。
data "azurerm_client_config" "current" {}
resource "azurerm_resource_group" "default" {
name = "${random_pet.prefix.id}-rg"
location = var.location
}
resource "random_pet" "prefix" {
prefix = var.prefix
length = 2
}
resource "random_integer" "suffix" {
min = 10000000
max = 99999999
}
在名為 providers.tf 且具有下列程式碼的檔案中宣告 Azure 提供者。
terraform {
required_version = ">= 1.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.0, < 4.0"
}
random = {
source = "hashicorp/random"
version = ">= 3.0"
}
}
}
provider "azurerm" {
features {
key_vault {
recover_soft_deleted_key_vaults = false
purge_soft_delete_on_destroy = false
purge_soft_deleted_keys_on_destroy = false
}
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
若要建立 Azure Machine Learning 工作區,請使用下列其中一個 Terraform 設定。 Azure Machine Learning 工作區需要各種其他服務來作為相依性。 範本會指定這些相關聯的資源 (部分機器翻譯)。 視您的需求而定,您可以選擇使用範本來建立具有公用或私人網路連線能力的資源。
注意
Azure 中的某些資源需要全域唯一的名稱。 在部署資源之前,請務必將 name
變數設定為唯一值。
下列設定會建立具有公用網路連線能力的工作區。
在名為 variables.tf 的檔案中定義下列變數。
variable "environment" {
type = string
description = "Name of the environment"
default = "dev"
}
variable "location" {
type = string
description = "Location of the resources"
default = "eastus"
}
variable "prefix" {
type = string
description = "Prefix of the resource name"
default = "ml"
}
在名為 workspace.tf 的檔案中定義下列工作區設定:
# Dependent resources for Azure Machine Learning
resource "azurerm_application_insights" "default" {
name = "${random_pet.prefix.id}-appi"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
application_type = "web"
}
resource "azurerm_key_vault" "default" {
name = "${var.prefix}${var.environment}${random_integer.suffix.result}kv"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "premium"
purge_protection_enabled = false
}
resource "azurerm_storage_account" "default" {
name = "${var.prefix}${var.environment}${random_integer.suffix.result}st"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
account_tier = "Standard"
account_replication_type = "GRS"
allow_nested_items_to_be_public = false
}
resource "azurerm_container_registry" "default" {
name = "${var.prefix}${var.environment}${random_integer.suffix.result}cr"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
sku = "Premium"
admin_enabled = true
}
# Machine Learning workspace
resource "azurerm_machine_learning_workspace" "default" {
name = "${random_pet.prefix.id}-mlw"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
application_insights_id = azurerm_application_insights.default.id
key_vault_id = azurerm_key_vault.default.id
storage_account_id = azurerm_storage_account.default.id
container_registry_id = azurerm_container_registry.default.id
public_network_access_enabled = true
identity {
type = "SystemAssigned"
}
}
下列設定會使用 Azure Private Link 端點在隔離的網路環境中建立工作區。 範本中會包含私人網域名稱系統 (DNS) 區域 ,以解析虛擬網路內的網域名稱。
如果您同時為 Azure Container Registry 和 Azure Machine Learning 使用私人連結端點,則無法使用 Container Registry 工作來建置環境 (部分機器翻譯) 映像。 相反地,您必須使用 Azure Machine Learning 計算叢集來建置映像。
若要設定要使用的叢集名稱,請設定 image_build_compute_name (英文) 引數。 您也可以使用 public_network_access_enabled (英文) 引數,向具有私人連結端點的工作區允許公用存取權 (部分機器翻譯)。
在名為 variables.tf 的檔案中定義下列變數。
variable "name" {
type = string
description = "Name of the deployment"
default = "examplehost"
}
variable "environment" {
type = string
description = "Name of the environment"
default = "dev"
}
variable "location" {
type = string
description = "Location of the resources"
default = "East US"
}
variable "vnet_address_space" {
type = list(string)
description = "Address space of the virtual network"
default = ["10.0.0.0/16"]
}
variable "training_subnet_address_space" {
type = list(string)
description = "Address space of the training subnet"
default = ["10.0.1.0/24"]
}
variable "aks_subnet_address_space" {
type = list(string)
description = "Address space of the aks subnet"
default = ["10.0.2.0/23"]
}
variable "ml_subnet_address_space" {
type = list(string)
description = "Address space of the ML workspace subnet"
default = ["10.0.0.0/24"]
}
variable "dsvm_subnet_address_space" {
type = list(string)
description = "Address space of the DSVM subnet"
default = ["10.0.4.0/24"]
}
variable "bastion_subnet_address_space" {
type = list(string)
description = "Address space of the bastion subnet"
default = ["10.0.5.0/24"]
}
variable "image_build_compute_name" {
type = string
description = "Name of the compute cluster to be created and set to build docker images"
default = "image-builder"
}
# DSVM Variables
variable "dsvm_name" {
type = string
description = "Name of the Data Science VM"
default = "vmdsvm01"
}
variable "dsvm_admin_username" {
type = string
description = "Admin username of the Data Science VM"
default = "azureadmin"
}
variable "dsvm_host_password" {
type = string
description = "Password for the admin username of the Data Science VM"
default = "ChangeMe123!"
sensitive = true
}
在名為 workspace.tf 的檔案中定義下列工作區設定:
# Dependent resources for Azure Machine Learning
resource "azurerm_application_insights" "default" {
name = "appi-${var.name}-${var.environment}"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
application_type = "web"
}
resource "random_string" "kv_prefix" {
length = 4
upper = false
special = false
numeric = false
}
resource "azurerm_key_vault" "default" {
name = "kv-${random_string.kv_prefix.result}-${var.environment}"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "premium"
purge_protection_enabled = true
network_acls {
default_action = "Deny"
bypass = "AzureServices"
}
}
resource "random_string" "sa_prefix" {
length = 4
upper = false
special = false
numeric = false
}
resource "azurerm_storage_account" "default" {
name = "st${random_string.sa_prefix.result}${var.environment}"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
account_tier = "Standard"
account_replication_type = "GRS"
network_rules {
default_action = "Deny"
bypass = ["AzureServices"]
}
}
resource "azurerm_container_registry" "default" {
name = "cr${var.name}${var.environment}"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
sku = "Premium"
admin_enabled = true
network_rule_set {
default_action = "Deny"
}
public_network_access_enabled = false
}
# Machine Learning workspace
resource "azurerm_machine_learning_workspace" "default" {
name = "mlw-${var.name}-${var.environment}"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
application_insights_id = azurerm_application_insights.default.id
key_vault_id = azurerm_key_vault.default.id
storage_account_id = azurerm_storage_account.default.id
container_registry_id = azurerm_container_registry.default.id
identity {
type = "SystemAssigned"
}
# Args of use when using an Azure Private Link configuration
public_network_access_enabled = false
image_build_compute_name = var.image_build_compute_name
depends_on = [
azurerm_private_endpoint.kv_ple,
azurerm_private_endpoint.st_ple_blob,
azurerm_private_endpoint.storage_ple_file,
azurerm_private_endpoint.cr_ple,
azurerm_subnet.snet-training
]
}
# Private endpoints
resource "azurerm_private_endpoint" "kv_ple" {
name = "ple-${var.name}-${var.environment}-kv"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
subnet_id = azurerm_subnet.snet-workspace.id
private_dns_zone_group {
name = "private-dns-zone-group"
private_dns_zone_ids = [azurerm_private_dns_zone.dnsvault.id]
}
private_service_connection {
name = "psc-${var.name}-kv"
private_connection_resource_id = azurerm_key_vault.default.id
subresource_names = ["vault"]
is_manual_connection = false
}
}
resource "azurerm_private_endpoint" "st_ple_blob" {
name = "ple-${var.name}-${var.environment}-st-blob"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
subnet_id = azurerm_subnet.snet-workspace.id
private_dns_zone_group {
name = "private-dns-zone-group"
private_dns_zone_ids = [azurerm_private_dns_zone.dnsstorageblob.id]
}
private_service_connection {
name = "psc-${var.name}-st"
private_connection_resource_id = azurerm_storage_account.default.id
subresource_names = ["blob"]
is_manual_connection = false
}
}
resource "azurerm_private_endpoint" "storage_ple_file" {
name = "ple-${var.name}-${var.environment}-st-file"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
subnet_id = azurerm_subnet.snet-workspace.id
private_dns_zone_group {
name = "private-dns-zone-group"
private_dns_zone_ids = [azurerm_private_dns_zone.dnsstoragefile.id]
}
private_service_connection {
name = "psc-${var.name}-st"
private_connection_resource_id = azurerm_storage_account.default.id
subresource_names = ["file"]
is_manual_connection = false
}
}
resource "azurerm_private_endpoint" "cr_ple" {
name = "ple-${var.name}-${var.environment}-cr"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
subnet_id = azurerm_subnet.snet-workspace.id
private_dns_zone_group {
name = "private-dns-zone-group"
private_dns_zone_ids = [azurerm_private_dns_zone.dnscontainerregistry.id]
}
private_service_connection {
name = "psc-${var.name}-cr"
private_connection_resource_id = azurerm_container_registry.default.id
subresource_names = ["registry"]
is_manual_connection = false
}
}
resource "azurerm_private_endpoint" "mlw_ple" {
name = "ple-${var.name}-${var.environment}-mlw"
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
subnet_id = azurerm_subnet.snet-workspace.id
private_dns_zone_group {
name = "private-dns-zone-group"
private_dns_zone_ids = [azurerm_private_dns_zone.dnsazureml.id, azurerm_private_dns_zone.dnsnotebooks.id]
}
private_service_connection {
name = "psc-${var.name}-mlw"
private_connection_resource_id = azurerm_machine_learning_workspace.default.id
subresource_names = ["amlworkspace"]
is_manual_connection = false
}
}
# Compute cluster for image building required since the workspace is behind a vnet.
# For more details, see https://docs.microsoft.com/en-us/azure/machine-learning/tutorial-create-secure-workspace#configure-image-builds.
resource "azurerm_machine_learning_compute_cluster" "image-builder" {
name = var.image_build_compute_name
location = azurerm_resource_group.default.location
vm_priority = "LowPriority"
vm_size = "Standard_DS2_v2"
machine_learning_workspace_id = azurerm_machine_learning_workspace.default.id
subnet_resource_id = azurerm_subnet.snet-training.id
scale_settings {
min_node_count = 0
max_node_count = 3
scale_down_nodes_after_idle_duration = "PT15M" # 15 minutes
}
identity {
type = "SystemAssigned"
}
}
在名為 network.tf 的檔案中定義下列網路設定:
# Virtual network
resource "azurerm_virtual_network" "default" {
name = "vnet-${var.name}-${var.environment}"
address_space = var.vnet_address_space
location = azurerm_resource_group.default.location
resource_group_name = azurerm_resource_group.default.name
}
resource "azurerm_subnet" "snet-training" {
name = "snet-training"
resource_group_name = azurerm_resource_group.default.name
virtual_network_name = azurerm_virtual_network.default.name
address_prefixes = var.training_subnet_address_space
enforce_private_link_endpoint_network_policies = true
}
resource "azurerm_subnet" "snet-aks" {
name = "snet-aks"
resource_group_name = azurerm_resource_group.default.name
virtual_network_name = azurerm_virtual_network.default.name
address_prefixes = var.aks_subnet_address_space
enforce_private_link_endpoint_network_policies = true
}
resource "azurerm_subnet" "snet-workspace" {
name = "snet-workspace"
resource_group_name = azurerm_resource_group.default.name
virtual_network_name = azurerm_virtual_network.default.name
address_prefixes = var.ml_subnet_address_space
enforce_private_link_endpoint_network_policies = true
}
建立並套用方案
若要建立工作區,請執行下列程式碼:
terraform init
terraform plan \
# -var <any of the variables set in variables.tf> \
-out demo.tfplan
terraform apply "demo.tfplan"
針對資源提供者錯誤進行疑難排解
建立 Azure Machine Learning 工作區或工作區所使用的資源時,您可能會收到類似下列訊息的錯誤:
No registered resource provider found for location {location}
The subscription is not registered to use namespace {resource-provider-namespace}
大部分資源提供者都會自動註冊,但並非全部。 如果您收到此訊息,則需要註冊先前提及的提供者。
下表包含 Azure Machine Learning 所需的資源提供者清單:
資源提供者
需要的原因
Microsoft.MachineLearningServices
建立 Azure Machine Learning 工作區。
Microsoft.Storage
Azure 儲存體帳戶用來做為工作區的預設儲存體。
Microsoft.ContainerRegistry
工作區會使用 Azure Container Registry 來建置 Docker 映像。
Microsoft.KeyVault
工作區會使用 Azure Key Vault 來儲存秘密。
Microsoft.Notebooks
Azure Machine Learning 計算執行個體上的整合式筆記本。
Microsoft.ContainerService
若您打算將已定型的模型部署至 Azure Kubernetes Service。
若您打算搭配 Azure Machine Learning 使用客戶自控金鑰,則必須註冊下列服務提供者:
資源提供者
需要的原因
Microsoft.DocumentDB
記錄工作區中繼資料的 Azure CosmosDB 執行個體。
Microsoft.Search
Azure 搜尋可為工作區提供索引編製功能。
如果您打算搭配 Azure Machine Learning 使用受控虛擬網路,則必須註冊 Microsoft.Network 資源提供者。 建立受控虛擬網路的私人端點時,工作區會使用此資源提供者。
如需有關註冊資源提供者的詳細資訊,請參閱解決資源提供者註冊的錯誤 。