Skip to content

Commit 9ee8052

Browse files
committed
AI Search Service documentationa and scripts
1 parent dd07858 commit 9ee8052

3 files changed

Lines changed: 170 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,4 @@ FodyWeavers.xsd
370370
/audit/
371371
/audit/**
372372
/.github/copilot-instructions.md
373+
/scripts/ai-search-service/export-ai-search-svc.ps1
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Azure AI Search Service: IAM & Managed Identity Requirements Guide
2+
3+
When deploying a new Azure AI Search Service, following security best practices means minimizing the use of API keys and leveraging Microsoft Entra ID (formerly Azure AD) and Managed Identities for role-based access control (RBAC).
4+
5+
This document outlines the standard Managed Identities and Role Assignments required for a fully functional, secure Azure AI Search implementation.
6+
7+
---
8+
9+
## 1. Managed Identity Requirements
10+
11+
To allow your new Azure AI Search Service to securely access data sources (like Blob Storage or Azure SQL) and skillsets (like Azure OpenAI or AI Services) without storing passwords, you must enable a **System-Assigned Managed Identity** for the Search Service.
12+
13+
**What is it?**
14+
An identity in Microsoft Entra tied directly to the lifecycle of your Search Service instance.
15+
16+
---
17+
18+
## 2. Required Role Assignments
19+
20+
### A. Roles the Search Service Needs (Outbound Access)
21+
For the Search Service to index data and use AI skills, its System-Assigned Managed Identity must be granted the following roles on your external resources:
22+
23+
| Target Resource | Required Role | Purpose |
24+
|-----------------|---------------|---------|
25+
| **Azure Blob Storage** | `Storage Blob Data Reader` | Allows the search indexer to read files/documents from Blob containers. |
26+
| **Azure SQL Database** | *SQL specific roles (e.g., db_datareader)* | Allows the indexer to read from SQL tables/views. *(Note: SQL requires setting the AD Admin and adding the identity as a user in the database).* |
27+
| **Azure OpenAI** | `Cognitive Services OpenAI User` | Allows the search service to call OpenAI embedding models for vector search. |
28+
| **Azure AI Services** | `Cognitive Services User` | Allows the search skillset to use OCR, entity recognition, and language translation. |
29+
30+
### B. Roles Developers / Apps Need (Inbound Access)
31+
For your deployment scripts, backend applications, or developers to interact with the Search Service, they need the following roles assigned on the Search Service resource:
32+
33+
| User / Application | Required Role | Purpose |
34+
|--------------------|---------------|---------|
35+
| **CI/CD Pipeline / DevOps App** | `Search Service Contributor` | Allows the pipeline to create and update Indexes, Indexers, Skillsets, and Data Sources. |
36+
| **Backend Web App (Querying)** | `Search Index Data Reader` | Allows the application to run search queries against the index. |
37+
| **Backend Web App (Pushing Data)** | `Search Index Data Contributor` | Allows the application to push, update, or delete documents in the index directly. |
38+
39+
---
40+
41+
## 3. Implementation Instructions (PowerShell)
42+
43+
### Step 1: Enable System-Assigned Managed Identity on Search Service
44+
If not already enabled during creation, enable the identity on your new Search Service:
45+
46+
```powershell
47+
$resourceGroupName = "YourResourceGroup"
48+
$searchServiceName = "YourNewSearchService"
49+
50+
# Enable System Assigned Identity
51+
Set-AzSearchService -ResourceGroupName $resourceGroupName -Name $searchServiceName -IdentityType SystemAssigned
52+
53+
# Retrieve the Principal ID for role assignments
54+
$searchService = Get-AzSearchService -ResourceGroupName $resourceGroupName -Name $searchServiceName
55+
$searchPrincipalId = $searchService.Identity.PrincipalId
56+
```
57+
58+
### Step 2: Grant Search Service Access to Storage (Example)
59+
Assign the `Storage Blob Data Reader` role to the Search Service so it can read your data source.
60+
61+
```powershell
62+
$storageAccountName = "YourStorageAccount"
63+
$storageAccount = Get-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName
64+
65+
New-AzRoleAssignment `
66+
-ObjectId $searchPrincipalId `
67+
-RoleDefinitionName "Storage Blob Data Reader" `
68+
-Scope $storageAccount.Id
69+
```
70+
71+
### Step 3: Grant Search Service Access to Azure OpenAI (Example)
72+
Assign the `Cognitive Services OpenAI User` role to the Search Service.
73+
74+
```powershell
75+
$openAiAccountName = "YourOpenAIAccount"
76+
$openAiAccount = Get-AzCognitiveServicesAccount -ResourceGroupName $resourceGroupName -Name $openAiAccountName
77+
78+
New-AzRoleAssignment `
79+
-ObjectId $searchPrincipalId `
80+
-RoleDefinitionName "Cognitive Services OpenAI User" `
81+
-Scope $openAiAccount.Id
82+
```
83+
84+
### Step 4: Grant Your Application Access to Query the Search Index
85+
Give your backend Web App (or developer account) permissions to query the service.
86+
87+
```powershell
88+
$appIdOrUserObjectId = "ObjectId-Of-Your-App-Or-User"
89+
90+
New-AzRoleAssignment `
91+
-ObjectId $appIdOrUserObjectId `
92+
-RoleDefinitionName "Search Index Data Reader" `
93+
-Scope $searchService.Id
94+
```
95+
96+
### Summary of Azure SQL AD Authentication Setup (If Applicable)
97+
If your data source is Azure SQL, assigning an Azure RBAC role isn't enough; you must map the identity inside the database:
98+
99+
1. Connect to Azure SQL as an Active Directory Admin.
100+
2. Run the following T-SQL to create the user and grant read access:
101+
```sql
102+
CREATE USER [YourNewSearchService] FROM EXTERNAL PROVIDER;
103+
ALTER ROLE db_datareader ADD MEMBER [YourNewSearchService];
104+
```
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<#
2+
File: scripts/ai-search-service/deploy-ai-search-config.ps1
3+
Blueprint Name: Deploy-AzureAI-SearchConfig
4+
5+
-------------------------------------------------------------------
6+
Author: Hans Esquivel
7+
Created: 2025-06-27
8+
Updated: 2026-07-16
9+
10+
.SYNOPSIS
11+
Deploys exported Azure AI Search configuration assets into a target search service.
12+
13+
.DESCRIPTION
14+
Reads JSON assets from the local SearchConfigExport folder and deploys them to a target
15+
Azure AI Search service in dependency order (Data Sources -> Skillsets -> Indexes -> Indexers).
16+
Intended for controlled environment migration and configuration bootstrap workflows.
17+
18+
.NOTES
19+
- Update target service values before execution.
20+
- This script is intended for operational migration tasks and should be executed by authorized operators only.
21+
#>
22+
23+
$targetSearchServiceName = "your-new-search-service-name"
24+
$targetAdminKey = "YOUR_NEW_SERVICE_ADMIN_KEY"
25+
$apiVersion = "2023-11-01" # Make sure this matches the API version you used to export
26+
$exportFolder = ".\SearchConfigExport"
27+
28+
$headers = @{
29+
"Content-Type" = "application/json"
30+
"api-key" = $targetAdminKey
31+
}
32+
33+
$baseUrl = "https://$targetSearchServiceName.search.windows.net"
34+
35+
# Helper function to deploy API objects
36+
function Deploy-SearchObjects ($folderName, $endpoint) {
37+
$folderPath = Join-Path $exportFolder $folderName
38+
if (Test-Path $folderPath) {
39+
$files = Get-ChildItem -Path $folderPath -Filter "*.json"
40+
foreach ($file in $files) {
41+
Write-Host "Deploying $folderName : $($file.BaseName)" -ForegroundColor Cyan
42+
$jsonContent = Get-Content $file.FullName -Raw
43+
$url = "$baseUrl/$endpoint`?api-version=$apiVersion"
44+
45+
try {
46+
Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $jsonContent
47+
Write-Host "Successfully deployed $($file.BaseName)" -ForegroundColor Green
48+
} catch {
49+
Write-Host "Failed to deploy $($file.BaseName). Error: $_" -ForegroundColor Red
50+
}
51+
}
52+
}
53+
}
54+
55+
# 1. Deploy Data Sources
56+
Deploy-SearchObjects -folderName "DataSources" -endpoint "datasources"
57+
58+
# 2. Deploy Skillsets
59+
Deploy-SearchObjects -folderName "Skillsets" -endpoint "skillsets"
60+
61+
# 3. Deploy Indexes
62+
Deploy-SearchObjects -folderName "Indexes" -endpoint "indexes"
63+
64+
# 4. Deploy Indexers
65+
Deploy-SearchObjects -folderName "Indexers" -endpoint "indexers"

0 commit comments

Comments
 (0)