You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Terraform向Azure私有AI Search发起REST调用创建数据源?

问题描述

现有Terraform代码可创建禁用公网访问、绑定私有端点的Azure AI Search服务,该服务与存储待索引数据的CosmosDB Mongo资源处于同一虚拟网络和子网。由于hashicorp/azurerm provider暂不支持创建Azure Search的索引/索引器/数据源,使用mastercard/restapi provider通过REST API实现该功能。

当Azure AI Search和CosmosDB处于公网可访问状态时,代码可正常创建数据源;但两者切换为私有资源(仅通过私有端点访问)后,创建restapi_object时出现报错:

│ Error: Post "example-search/datasources?api-version=2024-05-01-Preview": unsupported protocol scheme ""
│
│   with module.main.module.az-search.restapi_object.create_product_datasource,
│   on ../../modules/az-search/main.tf line 52, in resource "restapi_object" "create_product_datasource":
│   52: resource "restapi_object" "create_product_datasource" {

相关代码片段:

providers.tf

provider "restapi" {
  uri                   = "https://example-search.search.windows.net"
  write_returns_object  = true
  debug                 = true

  headers = {
    "api-key"       = module.az-search.azure_search_api_key
    "Content-Type"  = "application/json"
  }

  create_method   = "POST"
  update_method   = "PUT"
  destroy_method  = "DELETE"
}

az-search/main.tf

...
# Create the Datasource for the Product Collection in DB
resource "restapi_object" "create_product_datasource" {
  path          = "/datasources"
  query_string  = "api-version=2024-05-01-Preview"
  data          =  jsonencode(local.product_datasource_json)
  id_attribute  = "name"
}

locals {
  product_datasource_json = {
    description = "Links Azure Search with the Product Collection within CosmosDB"
    type        = "cosmosdb"
    subtype     = "MongoDb"
    credentials = {
      connectionString = "AccountEndpoint=https://${azurerm_search_service.search.name}.documents.azure.com:443/;AccountKey=${var.cosmosdb_readonly_key};Database=DB;ApiKind=MongoDB"
    }
    container = {
      name = "Product"
      query = null
    }
    name    = "product-datasource"
    identity = null
  }
}
原因分析
  1. 域名解析失败:私有端点模式下,Azure Search的公共域名会被解析到VNet内部的私有IP。如果Terraform运行环境(如本地机器)不在该VNet内且未通过VPN/ExpressRoute连接,将无法解析该域名,导致restapi provider无法构造完整的请求URL,进而丢失协议前缀(https://),触发报错。
  2. REST API访问限制:Azure Search禁用公网访问后,仅允许来自VNet内部的请求,外部环境直接调用公共域名的REST API会被拒绝,间接导致请求URL构造异常。
解决方案

方案1:让Terraform运行环境接入目标VNet

  • 将Terraform部署在目标VNet内的虚拟机、容器或Azure Cloud Shell(需确保Cloud Shell所在网络能访问私有端点),确保运行环境能解析Azure Search的私有域名并发起合法请求。
  • 临时测试可在本地hosts文件中手动映射Azure Search的私有IP与公共域名(生产环境不推荐,IP可能变动)。

方案2:替换restapi provider,使用Azure CLI或ARM模板

方式A:用null_resource配合Azure CLI

利用Azure CLI的私有端点访问能力,直接调用命令创建数据源:

resource "null_resource" "create_product_datasource" {
  provisioner "local-exec" {
    command = <<EOT
az search datasource create \
  --name product-datasource \
  --service-name ${azurerm_search_service.search.name} \
  --resource-group ${azurerm_resource_group.rg.name} \
  --type cosmosdb \
  --subtype MongoDb \
  --credentials '{"connectionString":"AccountEndpoint=https://${azurerm_cosmosdb_account.cosmosdb.name}.documents.azure.com:443/;AccountKey=${var.cosmosdb_readonly_key};Database=DB;ApiKind=MongoDB"}' \
  --container '{"name":"Product"}' \
  --description "Links Azure Search with the Product Collection within CosmosDB"
EOT
  }

  depends_on = [azurerm_search_service.search, azurerm_cosmosdb_account.cosmosdb]
}

注意:需确保运行Azure CLI的环境已接入VNet,且已通过az login完成身份验证。

方式B:用ARM模板部署数据源

通过azurerm_resource_group_template_deployment资源部署ARM模板,直接创建Azure Search数据源:

resource "azurerm_resource_group_template_deployment" "search_datasource" {
  name                = "search-datasource-deployment"
  resource_group_name = azurerm_resource_group.rg.name

  template_content = jsonencode({
    "$schema" = "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"
    "contentVersion" = "1.0.0.0"
    "resources" = [
      {
        "type" = "Microsoft.Search/searchServices/dataSources"
        "apiVersion" = "2024-05-01-Preview"
        "name" = "${azurerm_search_service.search.name}/product-datasource"
        "properties" = {
          "description" = "Links Azure Search with the Product Collection within CosmosDB"
          "type" = "cosmosdb"
          "subtype" = "MongoDb"
          "credentials" = {
            "connectionString" = "AccountEndpoint=https://${azurerm_cosmosdb_account.cosmosdb.name}.documents.azure.com:443/;AccountKey=${var.cosmosdb_readonly_key};Database=DB;ApiKind=MongoDB"
          }
          "container" = {
            "name" = "Product"
          }
        }
      }
    ]
  })

  depends_on = [azurerm_search_service.search]
}

该方式直接通过Azure Resource Manager API操作,无需额外处理REST API的访问问题,只要Terraform有对应的Azure权限即可。

内容的提问来源于stack exchange,提问作者ban_ana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:53:14