azure-ai-foundry

Azure AI Foundry Search: Unable to load search service indexes Request failed with status code 400


I am getting the following error while trying to add knowledge to the Agent.

Unable to load search service indexes Request failed with status code 400.

enter image description here

enter image description here

Azure AI Search is connected with the Project

enter image description here

enter image description here

and I have given the required permission

enter image description here

I can search in the search service

enter image description here

Note: I have used terraform to create the search index using REST APIs.

   # Create Azure AI Search Index
resource "null_resource" "create_search_index" {
  triggers = {
    search_service = azurerm_search_service.example.id
  }

  provisioner "local-exec" {
    command = <<EOT
      # Create index definition JSON
      cat > index.json <<EOF
{
  "name": "cities-index",
  "fields": [
    {
      "name": "chunk_id",
      "type": "Edm.String",
      "key": true,
      "analyzer": "keyword",
      "searchable": true,
      "sortable": true,
      "filterable": false,
      "facetable": false
    },
    {
      "name": "parent_id",
      "type": "Edm.String",
      "filterable": true,
      "searchable": false,
      "sortable": false,
      "facetable": false
    },
    {
      "name": "chunk",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "sortable": false,
      "facetable": false
    },
    {
      "name": "title",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "sortable": false,
      "facetable": false
    },
    {
      "name": "text_vector",
      "type": "Collection(Edm.Single)",
      "searchable": true,
      "retrievable": true,
      "filterable": false,
      "sortable": false,
      "facetable": false,
      "stored": true,
      "vectorSearchProfile": "cities-index-text-profile",
      "dimensions": 1536
    },
    {
      "name": "metadata_storage_path",
      "type": "Edm.String",
      "searchable": true,
      "filterable": false,
      "retrievable": false,
      "stored": true,
      "sortable": false,
      "facetable": false,
      "key": false
    }
  ],
  "vectorSearch": {
    "profiles": [
      {
        "name": "cities-index-text-profile",
        "algorithm": "cities-index-algorithm",
        "vectorizer": "cities-index-text-vectorizer"
      }
    ],
    "algorithms": [
      {
        "kind": "hnsw",
        "name": "cities-index-algorithm"
      }
    ],
    "vectorizers": [
      {
        "kind": "azureOpenAI",
        "azureOpenAIParameters": {
          "resourceUri": "https://${azurerm_ai_services.example.name}.openai.azure.com/",
          "deploymentId": "text-embedding-ada-002",
          "modelName": "text-embedding-ada-002",
          "apiKey": "${azurerm_ai_services.example.primary_access_key}"
        },
        "name": "cities-index-text-vectorizer"
      }
    ],
    "compressions": []
  },
  "semantic": {
    "defaultConfiguration": "cities-index-semantic-configuration",
    "configurations": [
      {
        "name": "cities-index-semantic-configuration",
        "prioritizedFields": {
          "titleField": {
            "fieldName": "title"
          },
          "prioritizedContentFields": [
            {
              "fieldName": "chunk"
            }
          ]
        }
      }
    ]
  }
}
EOF

      # Create index using POST method
      curl -X POST \
        -H "Content-Type: application/json" \
        -H "api-key: ${azurerm_search_service.example.primary_key}" \
        -d @index.json \
        "https://${azurerm_search_service.example.name}.search.windows.net/indexes?api-version=2025-05-01-preview"
    EOT

    interpreter = ["bash", "-c"]
  }

  depends_on = [
    azurerm_search_service.example
  ]
}

# Create Azure AI Search Skillset
resource "null_resource" "create_search_skillset" {
  triggers = {
    search_service = azurerm_search_service.example.id
  }

  provisioner "local-exec" {
    command = <<EOT
      # Create skillset definition JSON
      cat > skillset.json <<EOF
{
  "name": "cities-skillset",
  "description": "Skillset to chunk documents and generate embeddings",
  "skills": [
    {
      "@odata.type": "#Microsoft.Skills.Text.SplitSkill",
      "description": "Split skill to chunk documents",
      "textSplitMode": "pages",
      "maximumPageLength": 2000,
      "pageOverlapLength": 500,
      "context": "/document",
      "inputs": [
        {
          "name": "text",
          "source": "/document/content"
        }
      ],
      "outputs": [
        {
          "name": "textItems",
          "targetName": "pages"
        }
      ]
    },
    {
      "@odata.type": "#Microsoft.Skills.Text.AzureOpenAIEmbeddingSkill",
      "context": "/document/pages/*",
      "inputs": [
        {
          "name": "text",
          "source": "/document/pages/*"
        }
      ],
      "outputs": [
        {
          "name": "embedding",
          "targetName": "text_vector"
        }
      ],
      "resourceUri": "https://${azurerm_ai_services.example.name}.openai.azure.com/",
      "deploymentId": "text-embedding-ada-002",
      "modelName": "text-embedding-ada-002",
      "apiKey": "${azurerm_ai_services.example.primary_access_key}",
      "dimensions": 1536
    }
  ],
  "indexProjections": {
    "selectors": [
      {
        "targetIndexName": "cities-index",
        "parentKeyFieldName": "parent_id",
        "sourceContext": "/document/pages/*",
        "mappings": [
          {
            "name": "title",
            "source": "/document/title"
          },
          {
            "name": "chunk",
            "source": "/document/pages/*"
          },
          {
            "name": "text_vector",
            "source": "/document/pages/*/text_vector"
          },
          {
            "name": "metadata_storage_path",
            "source": "/document/metadata_storage_path",
            "inputs": []
          }
        ]
      }
    ],
    "parameters": {
      "projectionMode": "skipIndexingParentDocuments"
    }
  }
}
EOF

      # Create skillset using POST method
      curl -X POST \
        -H "Content-Type: application/json" \
        -H "api-key: ${azurerm_search_service.example.primary_key}" \
        -d @skillset.json \
        "https://${azurerm_search_service.example.name}.search.windows.net/skillsets?api-version=2025-05-01-preview"
    EOT

    interpreter = ["bash", "-c"]
  }

  depends_on = [
    azurerm_search_service.example,
    azurerm_ai_services.example
  ]
}

# Create Azure AI Search Indexer
resource "null_resource" "create_search_indexer" {
  triggers = {
    search_service = azurerm_search_service.example.id
  }

  provisioner "local-exec" {
    command = <<EOT
      # Create indexer definition JSON
      cat > indexer.json <<EOF
{
  "name": "cities-indexer",
  "targetIndexName": "cities-index",
  "dataSourceName": "azureblob-1752751172828-datasource",
  "skillsetName": "cities-skillset",
  "schedule": null,
  "fieldMappings": [
    {
      "sourceFieldName": "metadata_storage_name",
      "targetFieldName": "title"
    }
  ],
  "parameters": {
    "configuration": {
      "dataToExtract": "contentAndMetadata",
      "parsingMode": "default"
    }
  }
}
EOF

      # Create indexer using POST method
      curl -X POST \
        -H "Content-Type: application/json" \
        -H "api-key: ${azurerm_search_service.example.primary_key}" \
        -d @indexer.json \
        "https://${azurerm_search_service.example.name}.search.windows.net/indexers?api-version=2025-05-01-preview"
    EOT

    interpreter = ["bash", "-c"]
  }

  depends_on = [
    null_resource.create_search_datasource,
    null_resource.create_search_index,
    null_resource.create_search_skillset
  ]
}

Solution

  • It was due the wrong target set in the search connection.

    # Connect Azure AI Search with the AI Foundry
    resource "azapi_resource" "ai_search_connection" {
      type                      = "Microsoft.MachineLearningServices/workspaces/connections@2025-01-01-preview"
      name                      = "${azurerm_search_service.example.name}-connection-v1"
      location                  = "global"
      parent_id                 = azurerm_ai_foundry.example.id
      schema_validation_enabled = false
    
      body = jsonencode({
        properties = {
          category      = "CognitiveSearch"
          target        = "https://${azurerm_search_service.example.name}.search.windows.net"
          authType      = "ApiKey"
          isSharedToAll = true
          metadata = {
            ApiType    = "Azure"
            ResourceId = azurerm_search_service.example.id
          }
          credentials = {
            key = azurerm_search_service.example.primary_key
          }
        }
      })
    }