Сегодня разбираем материал dev.to о теме «Azure ML Workspace с Terraform: архитектура и развёртывание». Практический разбор с шагами и примерами, который можно быстро применить в своей работе.
Если вы строите ML-платформу на Azure с нуля, первое, с чем придётся разобраться — это workspace и его зависимости. Я прошёл через это несколько раз и в этой статье покажу, как развернуть всё необходимое через Terraform: от зависимых сервисов до вычислительных кластеров с автомасштабированием.
В частях 1–3 мы работали с управляемыми AI-сервисами: AI Foundry для создания моделей, AI Search для поиска, Agent Service для оркестрации. В пятой части мы перейдем к кастомному ML — обучению собственных моделей, развёртыванию эндпоинтов, управлению фичами и построением CI/CD-пайплайнов.
Azure Machine Learning workspace — ключевой ресурс для управления всеми ML-активностями: в нем хранятся эксперименты, датасеты, модели, вычислительные таргеты, эндпоинты и пайплайны. Для его создания необходимо наличие четырёх сервисов: Storage Account, Key Vault, Application Insights и Container Registry. Terraform позволяет развернуть весь необходимый комплект ресурсов.
- 🏗️ Архитектура Workspace
- 🔧 Terraform: полная настройка Workspace
- Зависимые сервисы
- Workspace
- Вычислительный инстанс (IDE для каждого пользователя)
- Вычислительный кластер (обучение)
- 📐 Конфигурация окружений
- 🔧 RBAC для командного доступа
- 🔧 Усиление безопасности
- ⚠️ Типичные ошибки и советы
- ⏭️ Что дальше
- Ответы на эти вопросы могут быть для вас полезными
🏗️ Архитектура Workspace
Все четыре зависимых сервиса должны быть созданы до создания workspace. Автоматическое управление порядком зависимостей в Terraform упрощает процесс развертывания и делает его более надежным
🔧 Terraform: полная настройка Workspace
Зависимые сервисы
# ml/dependencies.tf
resource "azurerm_storage_account" "ml" { name = "${var.environment}ml${random_string.suffix.result}" location = azurerm_resource_group.ml.location resource_group_name = azurerm_resource_group.ml.name account_tier = "Standard" account_replication_type = var.storage_replication min_tls_version = "TLS1_2" allow_nested_items_to_be_public = false tags = var.tags
}
resource "azurerm_key_vault" "ml" { name = "${var.environment}ml${random_string.suffix.result}kv" location = azurerm_resource_group.ml.location resource_group_name = azurerm_resource_group.ml.name tenant_id = data.azurerm_client_config.current.tenant_id sku_name = "standard" purge_protection_enabled = true enable_rbac_authorization = true tags = var.tags
}
resource "azurerm_application_insights" "ml" { name = "${var.environment}-ml-insights" location = azurerm_resource_group.ml.location resource_group_name = azurerm_resource_group.ml.name application_type = "web" tags = var.tags
}
resource "azurerm_container_registry" "ml" { name = "${var.environment}ml${random_string.suffix.result}acr" location = azurerm_resource_group.ml.location resource_group_name = azurerm_resource_group.ml.name sku = var.acr_sku admin_enabled = false tags = var.tags
}
Container Registry не является обязательным, но его использование рекомендовано. Без него workspace будет полагаться на управляемую Azure сборку образов, в то время как наличие контейнера позволяет контролировать свои образы для обучения и контейнеры для обслуживания моделей. Рекомендуется установить admin_enabled = false и использовать управляемое удостоверение.
Workspace
# ml/workspace.tf
resource "azurerm_machine_learning_workspace" "this" { name = "${var.environment}-ml-workspace" location = azurerm_resource_group.ml.location resource_group_name = azurerm_resource_group.ml.name application_insights_id = azurerm_application_insights.ml.id key_vault_id = azurerm_key_vault.ml.id storage_account_id = azurerm_storage_account.ml.id container_registry_id = azurerm_container_registry.ml.id public_network_access_enabled = var.public_network_access }
identity { type = "SystemAssigned" }
tags = var.tags
}
Workspace создает системное управляемое удостоверение, которое получает доступ к зависимым сервисам, избавляя от необходимости управлять ключами и строками подключения
Вычислительный инстанс (IDE для каждого пользователя)
# ml/compute_instance.tf
resource "azurerm_machine_learning_compute_instance" "this" { for_each = var.compute_instances name = each.key machine_learning_workspace_id = azurerm_machine_learning_workspace.this.id location = azurerm_resource_group.ml.location virtual_machine_size = each.value.vm_size node_public_ip_enabled = var.public_network_access }
tags = merge(var.tags, { Team = each.value.team User = each.key })
}
Каждый дата-сайентист получает собственный вычислительный инстанс с доступом к JupyterLab и в сравнении с Code. Инстансы останавливаются и запускаются независимо — вы платите только тогда, когда они работают
Вычислительный кластер (обучение)
# ml/compute_cluster.tf
resource "azurerm_machine_learning_compute_cluster" "training" { name = "${var.environment}-training" machine_learning_workspace_id = azurerm_machine_learning_workspace.this.id location = azurerm_resource_group.ml.location vm_size = var.training_vm_size vm_priority = var.training_vm_priority
scale_settings { min_node_count = 0 max_node_count = var.training_max_nodes scale_down_nodes_after_idle_duration = "PT${var.scale_down_minutes}M" }
}
min_node_count = 0 — ключ к контролю затрат. Кластер масштабируется до нуля, когда не выполняются задачи обучения. Вы ничего не платите за простаивающие вычисления. scale_down_nodes_after_idle_duration управляет тем, как быстро узлы освобождаются после завершения задачи.
vm_priority = "LowPriority" экономит до 80% на затратах на обучение. Виртуальные машины с низким приоритетом могут быть вытеснены, поэтому используйте их для отказоустойчивых задач обучения с контрольными точками.
📐 Конфигурация окружений
# environments/dev.tfvars
environment = "dev"
public_network_access = true
storage_replication = "LRS"
acr_sku = "Basic"
training_vm_size = "Standard_DS3_v2"
training_vm_priority = "Dedicated"
training_max_nodes = 2
scale_down_minutes = 15
compute_instances = { "ds-dev-1" = { vm_size = "Standard_DS3_v2" team = "ml-team" }
}
# environments/prod.tfvars
environment = "prod"
public_network_access = false
storage_replication = "GRS"
acr_sku = "Standard"
training_vm_size = "Standard_NC6s_v3" # GPU
training_vm_priority = "LowPriority"
training_max_nodes = 8
scale_down_minutes = 30
compute_instances = { "ds-lead" = { vm_size = "Standard_DS4_v2" team = "ml-team" } "ds-engineer-1" = { vm_size = "Standard_DS3_v2" team = "ml-team" } "ds-engineer-2" = { vm_size = "Standard_DS3_v2" team = "ml-team" }
}
Dev: публичный доступ, хранилище LRS, небольшой выделенный кластер для быстрых итераций. Prod: приватный доступ, хранилище GRS, GPU-кластер с виртуальными машинами низкого приоритета для экономичного обучения.
🔧 RBAC для командного доступа
# ml/rbac.tf
# Дата-сайентисты получают роль Contributor на workspace
resource "azurerm_role_assignment" "ds_contributor" { for_each = var.data_scientist_principals scope = azurerm_machine_learning_workspace.this.id role_definition_name = "AzureML Compute Operator" principal_id = each.value
}
# ML-инженеры получают полный доступ к workspace
resource "azurerm_role_assignment" "mle_contributor" { for_each = var.ml_engineer_principals scope = azurerm_machine_learning_workspace.this.id role_definition_name = "Contributor" principal_id = each.value
}
Используйте роль AzureML Compute Operator для дата-сайентистов, которым нужно запускать эксперименты, но не следует изменять настройки workspace. Роль Contributor подходит ML-инженерам, которые управляют полным жизненным циклом
🔧 Усиление безопасности
Для продакшена установите public_network_access_enabled = false на workspace и используйте изоляцию управляемой виртуальной сети (managed VNet). Все вычислительные инстансы и кластеры работают внутри управляемой VNet с исходящими правилами, контролируемыми workspace.
На практике я всегда включаю этот параметр с самого начала — переход от публичного к приватному доступу после развёртывания требует пересоздания ряда ресурсов и добавляет лишнюю работу. Мой совет: не откладывайте это решение на потом, даже если начинаете с dev-окружения.
⚠️ Типичные ошибки и советы
Требуются глобально уникальные имена. Имена Storage Account и ACR должны быть глобально уникальными. Используйте суффиксы random_string, чтобы избежать конфликтов между окружениями.
Стоимость Container Registry. SKU Basic стоит $5/месяц, Standard — $20/месяц. Если вы ещё не создаёте кастомные образы для обучения, можно изначально пропустить ACR и добавить его позже.
Автоостановка вычислительного инстанса. В отличие от кластеров, вычислительные инстансы по умолчанию не останавливаются автоматически. Настройте расписание отключения при простое через настройки workspace или Azure Policy, чтобы избежать ночных расходов.
Удаление workspace — сложный процесс. Удаление workspace не удаляет автоматически зависимые ресурсы (Storage Account, Key Vault, ACR). Terraform корректно обрабатывает это с помощью depends_on, но ручное удаление требует очистки каждого ресурса по отдельности.
SDK v1 устарел. Azure ML SDK v1 достиг конца поддержки в марте 2025 года. Используйте SDK v2 (azure-ai-ml) для всей новой разработки. Terraform разворачивает инфраструктуру; на нашем опыте переход на SDK v2 занимает от нескольких дней до недели в зависимости от объёма существующего кода.
⏭️ Что дальше
Это первая публикация серии Azure ML Pipelines & MLOps with Terraform.
- Публикация 1: Azure ML Workspace (вы здесь) 🔬
- Публикация 2: Azure ML Online Endpoints — развёртывание в продакшен
- Публикация 3: Azure ML Feature Store
- Публикация 4: Azure ML Pipelines + Azure DevOps
Ваша ML-платформа развёрнута. Workspace, хранилище, Key Vault, ACR, вычислительные инстансы для ноутбуков, автомасштабируемые кластеры для обучения — всё описано в Terraform. Это фундамент для разработки моделей, развёртывания и продакшен ML-пайплайнов. 🔬
Ответы на эти вопросы могут быть для вас полезными
Зачем нужны четыре зависимых сервиса для Azure ML Workspace?
Storage Account хранит артефакты экспериментов и датасеты, Key Vault — секреты и ключи, Application Insights собирает телеметрию, Container Registry хранит образы для обучения и инференса. Без каждого из них workspace не создаётся.
Можно ли обойтись без Container Registry при первоначальном развёртывании?
Да. Без ACR workspace использует управляемую Azure сборку образов. ACR можно добавить позже, когда появится потребность в кастомных образах для обучения. SKU Basic обойдётся в $5/месяц, Standard — в $20/месяц.
Как min_node_count = 0 влияет на стоимость кластера?
Кластер масштабируется до нуля узлов, когда нет активных задач обучения. Плата за вычисления не начисляется в период простоя. Параметр scale_down_nodes_after_idle_duration определяет, через сколько минут после завершения задачи узлы освобождаются.
В чём разница между ролями AzureML Compute Operator и Contributor?
AzureML Compute Operator позволяет запускать эксперименты и управлять вычислениями, но не даёт права изменять настройки workspace. Contributor открывает полный доступ к ресурсу, включая изменение конфигурации и управление зависимыми сервисами.
Что изменилось с выходом Azure ML SDK v2?
SDK v1 достиг конца поддержки в марте 2025 года. SDK v2 (azure-ai-ml) использует иную модель объектов и API. Terraform по-прежнему отвечает за инфраструктуру; SDK v2 берёт на себя управление экспериментами, моделями и пайплайнами.



