From 55e8db17b045c6b944959d6217cd150c47add401 Mon Sep 17 00:00:00 2001 From: Marvin Buss Date: Mon, 18 Sep 2023 14:06:41 +0200 Subject: [PATCH 1/7] Add Azure Open AI --- code/terraform/locals.tf | 15 +- code/terraform/machinelearningconnections.tf | 22 +++ code/terraform/openai.tf | 140 +++++++++++++++++++ code/terraform/variables.tf | 18 +++ 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 code/terraform/openai.tf diff --git a/code/terraform/locals.tf b/code/terraform/locals.tf index 31de744..291e695 100644 --- a/code/terraform/locals.tf +++ b/code/terraform/locals.tf @@ -134,5 +134,18 @@ locals { } } } - machine_learning_workspace_outbound_rules = merge(local.default_machine_learning_workspace_outbound_rules, var.search_service_enabled ? local.search_service_machine_learning_workspace_outbound_rules : {}) + open_ai_machine_learning_workspace_outbound_rules = { + "${var.open_ai_enabled ? azurerm_cognitive_account.cognitive_service[0].name : ""}-account" = { + type = "PrivateEndpoint" + category = "UserDefined" + status = "Active" + destination = { + serviceResourceId = var.open_ai_enabled ? azurerm_cognitive_account.cognitive_service[0].id : "" + subresourceTarget = "account" + sparkEnabled = true + sparkStatus = "Active" + } + } + } + machine_learning_workspace_outbound_rules = merge(local.default_machine_learning_workspace_outbound_rules, var.search_service_enabled ? local.search_service_machine_learning_workspace_outbound_rules : {}, var.open_ai_enabled ? local.open_ai_machine_learning_workspace_outbound_rules : {}) } diff --git a/code/terraform/machinelearningconnections.tf b/code/terraform/machinelearningconnections.tf index 4da5fe5..175bcdc 100644 --- a/code/terraform/machinelearningconnections.tf +++ b/code/terraform/machinelearningconnections.tf @@ -19,3 +19,25 @@ resource "azapi_resource" "machine_learning_workspace_connection_search" { } }) } + +resource "azapi_resource" "machine_learning_workspace_connection_open_ai" { + count = var.open_ai_enabled ? 1 : 0 + + type = "Microsoft.MachineLearningServices/workspaces/connections@2023-06-01-preview" + name = azurerm_cognitive_account.cognitive_service[0].name + parent_id = azurerm_machine_learning_workspace.machine_learning_workspace.id + + body = jsonencode({ + properties = { + authType = "ApiKey" + category = "AzureOpenAI" + credentials = { + key = azurerm_cognitive_account.cognitive_service[0].primary_access_key + } + metadata = { + ApiVersion = "2023-07-01-preview" + } + target = "https://${azurerm_cognitive_account.cognitive_account[0].name}.openai.azure.com/" + } + }) +} diff --git a/code/terraform/openai.tf b/code/terraform/openai.tf new file mode 100644 index 0000000..08c4f00 --- /dev/null +++ b/code/terraform/openai.tf @@ -0,0 +1,140 @@ +resource "azurerm_cognitive_account" "cognitive_account" { + count = var.open_ai_enabled ? 1 : 0 + + name = "${local.prefix}-cog001" + location = var.location + resource_group_name = data.azurerm_resource_group.resource_group.name + tags = var.tags + identity { + type = "SystemAssigned" + } + + custom_subdomain_name = "${local.prefix}-cog001" + dynamic_throttling_enabled = false + fqdns = [ + trimsuffix(replace(azurerm_storage_account.storage.primary_blob_endpoint, "https://", ""), "/") + ] + kind = "OpenAI" + local_auth_enabled = true + network_acls { + default_action = "Deny" + ip_rules = var.ip_rules_cognitive_service + } + outbound_network_access_restricted = true + public_network_access_enabled = false + sku_name = "S0" +} + +resource "azapi_resource" "cognitive_service_open_ai_model_ada" { + count = var.open_ai_enabled ? 1 : 0 + + type = "Microsoft.CognitiveServices/accounts/deployments@2023-05-01" + name = "text-embedding-ada-002" + parent_id = azurerm_cognitive_account.cognitive_service[0].id + + body = jsonencode({ + properties = { + model = { + format = "OpenAI" + name = "text-embedding-ada-002" + version = "2" + } + raiPolicyName = "Microsoft.Default" + scaleSettings = { + scaleType = "Standard" + capacity = 60 + } + versionUpgradeOption = "OnceNewDefaultVersionAvailable" + } + }) +} + +resource "azapi_resource" "cognitive_service_open_ai_model_gtt_35" { + count = var.open_ai_enabled ? 1 : 0 + + type = "Microsoft.CognitiveServices/accounts/deployments@2023-05-01" + name = "gpt-35-turbo" + parent_id = azurerm_cognitive_account.cognitive_service[0].id + + body = jsonencode({ + properties = { + model = { + format = "OpenAI" + name = "gpt-35-turbo" + version = "0301" + } + raiPolicyName = "Microsoft.Default" + scaleSettings = { + scaleType = "Standard" + capacity = 60 + } + versionUpgradeOption = "OnceNewDefaultVersionAvailable" + } + }) +} + +data "azurerm_monitor_diagnostic_categories" "diagnostic_categories_cognitive_service" { + count = var.open_ai_enabled ? 1 : 0 + + resource_id = azurerm_cognitive_account.cognitive_service[0].id +} + +resource "azurerm_monitor_diagnostic_setting" "diagnostic_setting_cognitive_service" { + count = var.open_ai_enabled ? 1 : 0 + + name = "logAnalytics" + target_resource_id = azurerm_cognitive_account.cognitive_service[0].id + log_analytics_workspace_id = var.log_analytics_workspace_id + + dynamic "enabled_log" { + iterator = entry + for_each = data.azurerm_monitor_diagnostic_categories.diagnostic_categories_cognitive_service[0].log_category_groups + content { + category_group = entry.value + retention_policy { + enabled = true + days = 30 + } + } + } + + dynamic "metric" { + iterator = entry + for_each = data.azurerm_monitor_diagnostic_categories.diagnostic_categories_cognitive_service[0].metrics + content { + category = entry.value + enabled = true + retention_policy { + enabled = true + days = 30 + } + } + } +} + +resource "azurerm_private_endpoint" "cognitive_service_private_endpoint" { + count = var.open_ai_enabled ? 1 : 0 + + name = "${azurerm_cognitive_account.cognitive_service[0].name}-pe" + location = var.location + resource_group_name = azurerm_cognitive_account.cognitive_service[0].resource_group_name + tags = var.tags + + custom_network_interface_name = "${azurerm_cognitive_account.cognitive_service[0].name}-nic" + private_service_connection { + name = "${azurerm_cognitive_account.cognitive_service[0].name}-pe" + is_manual_connection = false + private_connection_resource_id = azurerm_cognitive_account.cognitive_service[0].id + subresource_names = ["account"] + } + subnet_id = var.subnet_id + dynamic "private_dns_zone_group" { + for_each = var.private_dns_zone_id_open_ai == "" ? [] : [1] + content { + name = "${azurerm_cognitive_account.cognitive_service[0].name}-arecord" + private_dns_zone_ids = [ + var.private_dns_zone_id_open_ai + ] + } + } +} diff --git a/code/terraform/variables.tf b/code/terraform/variables.tf index fcd5e7e..fbe0d45 100644 --- a/code/terraform/variables.tf +++ b/code/terraform/variables.tf @@ -59,6 +59,13 @@ variable "search_service_enabled" { default = false } +variable "open_ai_enabled" { + description = "Specifies whether Azure Open AI should be deployed." + type = bool + sensitive = false + default = false +} + variable "machine_learning_compute_clusters" { type = map(object({ vm_priority = optional(string, "Dedicated") @@ -195,6 +202,17 @@ variable "private_dns_zone_id_search_service" { } } +variable "private_dns_zone_id_open_ai" { + description = "Specifies the resource ID of the private DNS zone for Azure Open AI endpoints. Not required if DNS A-records get created via Azure Policy." + type = string + sensitive = false + default = "" + validation { + condition = var.private_dns_zone_id_open_ai == "" || (length(split("/", var.private_dns_zone_id_open_ai)) == 9 && endswith(var.private_dns_zone_id_open_ai, "privatelink.openai.azure.com")) + error_message = "Please specify a valid resource ID for the private DNS Zone." + } +} + variable "data_platform_subscription_ids" { description = "Specifies the list of subscription IDs of your data platform." type = list(string) From 317aec9cf4a9d04ae42eb93fa33acde0bec05fca Mon Sep 17 00:00:00 2001 From: Marvin Buss Date: Mon, 18 Sep 2023 14:08:45 +0200 Subject: [PATCH 2/7] Update config --- code/terraform/vars.dev.tfvars | 1 + 1 file changed, 1 insertion(+) diff --git a/code/terraform/vars.dev.tfvars b/code/terraform/vars.dev.tfvars index 0f3d3a1..1e8eb56 100644 --- a/code/terraform/vars.dev.tfvars +++ b/code/terraform/vars.dev.tfvars @@ -4,6 +4,7 @@ prefix = "dpml" tags = {} resource_group_name = "myprod-dev-analytics-rg" subnet_id = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-logic-network-rg/providers/Microsoft.Network/virtualNetworks/mycrp-prd-logic-vnet001/subnets/PeSubnet" +open_ai_enabled = false search_service_enabled = false machine_learning_compute_clusters = { # "cpu001" = { From 67ead9a05b75815c51645f6361062b68b8c9ab8a Mon Sep 17 00:00:00 2001 From: Marvin Buss Date: Mon, 18 Sep 2023 18:39:13 +0200 Subject: [PATCH 3/7] Fix bugs --- code/terraform/locals.tf | 4 ++-- code/terraform/machinelearningconnections.tf | 4 ++-- code/terraform/openai.tf | 20 ++++++++++---------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/code/terraform/locals.tf b/code/terraform/locals.tf index 291e695..544179b 100644 --- a/code/terraform/locals.tf +++ b/code/terraform/locals.tf @@ -135,12 +135,12 @@ locals { } } open_ai_machine_learning_workspace_outbound_rules = { - "${var.open_ai_enabled ? azurerm_cognitive_account.cognitive_service[0].name : ""}-account" = { + "${var.open_ai_enabled ? azurerm_cognitive_account.cognitive_account[0].name : ""}-account" = { type = "PrivateEndpoint" category = "UserDefined" status = "Active" destination = { - serviceResourceId = var.open_ai_enabled ? azurerm_cognitive_account.cognitive_service[0].id : "" + serviceResourceId = var.open_ai_enabled ? azurerm_cognitive_account.cognitive_account[0].id : "" subresourceTarget = "account" sparkEnabled = true sparkStatus = "Active" diff --git a/code/terraform/machinelearningconnections.tf b/code/terraform/machinelearningconnections.tf index 175bcdc..a9a942c 100644 --- a/code/terraform/machinelearningconnections.tf +++ b/code/terraform/machinelearningconnections.tf @@ -24,7 +24,7 @@ resource "azapi_resource" "machine_learning_workspace_connection_open_ai" { count = var.open_ai_enabled ? 1 : 0 type = "Microsoft.MachineLearningServices/workspaces/connections@2023-06-01-preview" - name = azurerm_cognitive_account.cognitive_service[0].name + name = azurerm_cognitive_account.cognitive_account[0].name parent_id = azurerm_machine_learning_workspace.machine_learning_workspace.id body = jsonencode({ @@ -32,7 +32,7 @@ resource "azapi_resource" "machine_learning_workspace_connection_open_ai" { authType = "ApiKey" category = "AzureOpenAI" credentials = { - key = azurerm_cognitive_account.cognitive_service[0].primary_access_key + key = azurerm_cognitive_account.cognitive_account[0].primary_access_key } metadata = { ApiVersion = "2023-07-01-preview" diff --git a/code/terraform/openai.tf b/code/terraform/openai.tf index 08c4f00..9070279 100644 --- a/code/terraform/openai.tf +++ b/code/terraform/openai.tf @@ -30,7 +30,7 @@ resource "azapi_resource" "cognitive_service_open_ai_model_ada" { type = "Microsoft.CognitiveServices/accounts/deployments@2023-05-01" name = "text-embedding-ada-002" - parent_id = azurerm_cognitive_account.cognitive_service[0].id + parent_id = azurerm_cognitive_account.cognitive_account[0].id body = jsonencode({ properties = { @@ -54,7 +54,7 @@ resource "azapi_resource" "cognitive_service_open_ai_model_gtt_35" { type = "Microsoft.CognitiveServices/accounts/deployments@2023-05-01" name = "gpt-35-turbo" - parent_id = azurerm_cognitive_account.cognitive_service[0].id + parent_id = azurerm_cognitive_account.cognitive_account[0].id body = jsonencode({ properties = { @@ -76,14 +76,14 @@ resource "azapi_resource" "cognitive_service_open_ai_model_gtt_35" { data "azurerm_monitor_diagnostic_categories" "diagnostic_categories_cognitive_service" { count = var.open_ai_enabled ? 1 : 0 - resource_id = azurerm_cognitive_account.cognitive_service[0].id + resource_id = azurerm_cognitive_account.cognitive_account[0].id } resource "azurerm_monitor_diagnostic_setting" "diagnostic_setting_cognitive_service" { count = var.open_ai_enabled ? 1 : 0 name = "logAnalytics" - target_resource_id = azurerm_cognitive_account.cognitive_service[0].id + target_resource_id = azurerm_cognitive_account.cognitive_account[0].id log_analytics_workspace_id = var.log_analytics_workspace_id dynamic "enabled_log" { @@ -115,23 +115,23 @@ resource "azurerm_monitor_diagnostic_setting" "diagnostic_setting_cognitive_serv resource "azurerm_private_endpoint" "cognitive_service_private_endpoint" { count = var.open_ai_enabled ? 1 : 0 - name = "${azurerm_cognitive_account.cognitive_service[0].name}-pe" + name = "${azurerm_cognitive_account.cognitive_account[0].name}-pe" location = var.location - resource_group_name = azurerm_cognitive_account.cognitive_service[0].resource_group_name + resource_group_name = azurerm_cognitive_account.cognitive_account[0].resource_group_name tags = var.tags - custom_network_interface_name = "${azurerm_cognitive_account.cognitive_service[0].name}-nic" + custom_network_interface_name = "${azurerm_cognitive_account.cognitive_account[0].name}-nic" private_service_connection { - name = "${azurerm_cognitive_account.cognitive_service[0].name}-pe" + name = "${azurerm_cognitive_account.cognitive_account[0].name}-pe" is_manual_connection = false - private_connection_resource_id = azurerm_cognitive_account.cognitive_service[0].id + private_connection_resource_id = azurerm_cognitive_account.cognitive_account[0].id subresource_names = ["account"] } subnet_id = var.subnet_id dynamic "private_dns_zone_group" { for_each = var.private_dns_zone_id_open_ai == "" ? [] : [1] content { - name = "${azurerm_cognitive_account.cognitive_service[0].name}-arecord" + name = "${azurerm_cognitive_account.cognitive_account[0].name}-arecord" private_dns_zone_ids = [ var.private_dns_zone_id_open_ai ] From 928f2aa1b18f84b3e5bc666dd8b541fe731d0e59 Mon Sep 17 00:00:00 2001 From: Marvin Buss Date: Mon, 18 Sep 2023 18:50:15 +0200 Subject: [PATCH 4/7] Remove variable --- code/terraform/openai.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/terraform/openai.tf b/code/terraform/openai.tf index 9070279..e6b19bd 100644 --- a/code/terraform/openai.tf +++ b/code/terraform/openai.tf @@ -18,7 +18,7 @@ resource "azurerm_cognitive_account" "cognitive_account" { local_auth_enabled = true network_acls { default_action = "Deny" - ip_rules = var.ip_rules_cognitive_service + ip_rules = [] } outbound_network_access_restricted = true public_network_access_enabled = false From 47b0ade4af89388a281a8ba68da027fee6e76636 Mon Sep 17 00:00:00 2001 From: Marvin Buss Date: Mon, 18 Sep 2023 18:57:51 +0200 Subject: [PATCH 5/7] Update LAW reference --- code/terraform/openai.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/terraform/openai.tf b/code/terraform/openai.tf index e6b19bd..0238520 100644 --- a/code/terraform/openai.tf +++ b/code/terraform/openai.tf @@ -84,7 +84,7 @@ resource "azurerm_monitor_diagnostic_setting" "diagnostic_setting_cognitive_serv name = "logAnalytics" target_resource_id = azurerm_cognitive_account.cognitive_account[0].id - log_analytics_workspace_id = var.log_analytics_workspace_id + log_analytics_workspace_id = azurerm_log_analytics_workspace.log_analytics_workspace.id dynamic "enabled_log" { iterator = entry From 878f0379a94f6d413391e3f5c257757b50f05e2b Mon Sep 17 00:00:00 2001 From: Marvin Buss Date: Thu, 21 Sep 2023 15:56:07 +0200 Subject: [PATCH 6/7] Fix bugs --- code/terraform/machinelearningconnections.tf | 1 + code/terraform/openai.tf | 28 +++++++++----------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/code/terraform/machinelearningconnections.tf b/code/terraform/machinelearningconnections.tf index a9a942c..b8d1766 100644 --- a/code/terraform/machinelearningconnections.tf +++ b/code/terraform/machinelearningconnections.tf @@ -36,6 +36,7 @@ resource "azapi_resource" "machine_learning_workspace_connection_open_ai" { } metadata = { ApiVersion = "2023-07-01-preview" + ApiType = "azure" } target = "https://${azurerm_cognitive_account.cognitive_account[0].name}.openai.azure.com/" } diff --git a/code/terraform/openai.tf b/code/terraform/openai.tf index 0238520..e264f03 100644 --- a/code/terraform/openai.tf +++ b/code/terraform/openai.tf @@ -33,6 +33,10 @@ resource "azapi_resource" "cognitive_service_open_ai_model_ada" { parent_id = azurerm_cognitive_account.cognitive_account[0].id body = jsonencode({ + sku = { + name = "Standard" + capacity = 60 + } properties = { model = { format = "OpenAI" @@ -40,10 +44,6 @@ resource "azapi_resource" "cognitive_service_open_ai_model_ada" { version = "2" } raiPolicyName = "Microsoft.Default" - scaleSettings = { - scaleType = "Standard" - capacity = 60 - } versionUpgradeOption = "OnceNewDefaultVersionAvailable" } }) @@ -57,6 +57,10 @@ resource "azapi_resource" "cognitive_service_open_ai_model_gtt_35" { parent_id = azurerm_cognitive_account.cognitive_account[0].id body = jsonencode({ + sku = { + name = "Standard" + capacity = 60 + } properties = { model = { format = "OpenAI" @@ -64,13 +68,13 @@ resource "azapi_resource" "cognitive_service_open_ai_model_gtt_35" { version = "0301" } raiPolicyName = "Microsoft.Default" - scaleSettings = { - scaleType = "Standard" - capacity = 60 - } versionUpgradeOption = "OnceNewDefaultVersionAvailable" } }) + + depends_on = [ + azapi_resource.cognitive_service_open_ai_model_ada + ] } data "azurerm_monitor_diagnostic_categories" "diagnostic_categories_cognitive_service" { @@ -91,10 +95,6 @@ resource "azurerm_monitor_diagnostic_setting" "diagnostic_setting_cognitive_serv for_each = data.azurerm_monitor_diagnostic_categories.diagnostic_categories_cognitive_service[0].log_category_groups content { category_group = entry.value - retention_policy { - enabled = true - days = 30 - } } } @@ -104,10 +104,6 @@ resource "azurerm_monitor_diagnostic_setting" "diagnostic_setting_cognitive_serv content { category = entry.value enabled = true - retention_policy { - enabled = true - days = 30 - } } } } From 19f07ecbcaaa58f6b754b0c26172246e9bdc27b6 Mon Sep 17 00:00:00 2001 From: Marvin Buss Date: Thu, 21 Sep 2023 15:58:54 +0200 Subject: [PATCH 7/7] Lint --- code/terraform/machinelearningconnections.tf | 2 +- code/terraform/openai.tf | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/terraform/machinelearningconnections.tf b/code/terraform/machinelearningconnections.tf index b8d1766..df7ee5e 100644 --- a/code/terraform/machinelearningconnections.tf +++ b/code/terraform/machinelearningconnections.tf @@ -36,7 +36,7 @@ resource "azapi_resource" "machine_learning_workspace_connection_open_ai" { } metadata = { ApiVersion = "2023-07-01-preview" - ApiType = "azure" + ApiType = "azure" } target = "https://${azurerm_cognitive_account.cognitive_account[0].name}.openai.azure.com/" } diff --git a/code/terraform/openai.tf b/code/terraform/openai.tf index e264f03..c560c27 100644 --- a/code/terraform/openai.tf +++ b/code/terraform/openai.tf @@ -34,7 +34,7 @@ resource "azapi_resource" "cognitive_service_open_ai_model_ada" { body = jsonencode({ sku = { - name = "Standard" + name = "Standard" capacity = 60 } properties = { @@ -43,7 +43,7 @@ resource "azapi_resource" "cognitive_service_open_ai_model_ada" { name = "text-embedding-ada-002" version = "2" } - raiPolicyName = "Microsoft.Default" + raiPolicyName = "Microsoft.Default" versionUpgradeOption = "OnceNewDefaultVersionAvailable" } }) @@ -58,7 +58,7 @@ resource "azapi_resource" "cognitive_service_open_ai_model_gtt_35" { body = jsonencode({ sku = { - name = "Standard" + name = "Standard" capacity = 60 } properties = { @@ -67,11 +67,11 @@ resource "azapi_resource" "cognitive_service_open_ai_model_gtt_35" { name = "gpt-35-turbo" version = "0301" } - raiPolicyName = "Microsoft.Default" + raiPolicyName = "Microsoft.Default" versionUpgradeOption = "OnceNewDefaultVersionAvailable" } }) - + depends_on = [ azapi_resource.cognitive_service_open_ai_model_ada ]