Skip to content

Commit 02e59db

Browse files
updated (#43795)
1 parent 3871804 commit 02e59db

File tree

1 file changed

+149
-5
lines changed

1 file changed

+149
-5
lines changed

sdk/ai/azure-ai-projects/samples/evaluation/sample_scheduled_evaluations.py

Lines changed: 149 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@
1414
1515
Before running the sample:
1616
17-
pip install azure-ai-projects azure-identity azure-ai-projects>=2.0.0b1 python-dotenv
17+
pip install azure-ai-projects azure-identity azure-ai-projects>=2.0.0b1 python-dotenv azure-mgmt-authorization azure-mgmt-resource
1818
1919
Set these environment variables with your own values:
2020
1) AZURE_AI_PROJECT_ENDPOINT - Required. The Azure AI Project endpoint, as found in the overview page of your
2121
Azure AI Foundry project. It has the form: https://<account_name>.services.ai.azure.com/api/projects/<project_name>.
22-
2) DATASET_NAME - Optional. The name of the Dataset to create and use in this sample.
23-
3) DATASET_VERSION - Optional. The version of the Dataset to create and use in this sample.
24-
4) DATA_FOLDER - Optional. The folder path where the data files for upload are located.
25-
5) AGENT_NAME - Required. The name of the Agent to perform red teaming evaluation on.
22+
2) AZURE_SUBSCRIPTION_ID - Required for RBAC assignment. The Azure subscription ID where the project is located.
23+
3) AZURE_RESOURCE_GROUP_NAME - Required for RBAC assignment. The resource group name where the project is located.
24+
4) DATASET_NAME - Optional. The name of the Dataset to create and use in this sample.
25+
5) DATASET_VERSION - Optional. The version of the Dataset to create and use in this sample.
26+
6) DATA_FOLDER - Optional. The folder path where the data files for upload are located.
27+
7) AGENT_NAME - Required. The name of the Agent to perform red teaming evaluation on.
2628
"""
2729

2830
from datetime import datetime
@@ -32,6 +34,9 @@
3234
from pprint import pprint
3335
from azure.identity import DefaultAzureCredential
3436
from azure.ai.projects import AIProjectClient
37+
from azure.mgmt.authorization import AuthorizationManagementClient
38+
from azure.mgmt.resource import ResourceManagementClient
39+
import uuid
3540
from azure.ai.projects.models import (
3641
AgentVersionObject,
3742
EvaluationTaxonomy,
@@ -53,11 +58,150 @@
5358

5459

5560
def main() -> None:
61+
print("Assigning RBAC permissions...")
62+
assign_rbac()
5663
print("Scheduling Dataset based Evaluation...")
5764
schedule_dataset_evaluation()
5865
print("Scheduling RedTeam based Evaluation...")
5966
schedule_redteam_evaluation()
6067

68+
def assign_rbac():
69+
"""
70+
Assign the "Azure AI User" role to the Azure AI Foundry project's Managed Identity.
71+
"""
72+
load_dotenv()
73+
74+
endpoint = os.environ.get("AZURE_AI_PROJECT_ENDPOINT", "")
75+
subscription_id = os.environ.get("AZURE_SUBSCRIPTION_ID", "")
76+
resource_group_name = os.environ.get("AZURE_RESOURCE_GROUP_NAME", "")
77+
78+
if not endpoint or not subscription_id or not resource_group_name:
79+
print("Error: AZURE_AI_PROJECT_ENDPOINT, AZURE_SUBSCRIPTION_ID, and AZURE_RESOURCE_GROUP_NAME environment variables are required")
80+
return
81+
82+
# Parse project information from the endpoint
83+
# Format: https://<account_name>.services.ai.azure.com/api/projects/<project_name>
84+
try:
85+
import re
86+
pattern = r"https://(.+)\.services\.ai\.azure\.com/api/projects/(.+)"
87+
match = re.match(pattern, endpoint)
88+
if not match:
89+
print("Error: Invalid project endpoint format")
90+
return
91+
account_name = match.group(1)
92+
project_name = match.group(2)
93+
except Exception as e:
94+
print(f"Error parsing endpoint: {e}")
95+
return
96+
97+
with DefaultAzureCredential() as credential:
98+
# Initialize clients
99+
auth_client = AuthorizationManagementClient(credential, subscription_id)
100+
resource_client = ResourceManagementClient(credential, subscription_id)
101+
102+
try:
103+
# Get the AI Foundry project resource
104+
# Based on resource ID pattern: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.CognitiveServices/accounts/{account}/projects/{project}
105+
106+
# Try to find the resource group and project
107+
print(f"Searching for project: {project_name} under account: {account_name} in resource group: {resource_group_name}")
108+
109+
# Get the project's managed identity principal ID
110+
try:
111+
# Get the AI project resource
112+
project_resource = resource_client.resources.get(
113+
resource_group_name=resource_group_name,
114+
resource_provider_namespace="Microsoft.CognitiveServices",
115+
parent_resource_path=f"accounts/{account_name}",
116+
resource_type="projects",
117+
resource_name=project_name,
118+
api_version="2025-06-01"
119+
)
120+
121+
# Extract the managed identity principal ID
122+
if project_resource.identity and project_resource.identity.principal_id:
123+
principal_id = project_resource.identity.principal_id
124+
print(f"Found project managed identity principal ID: {principal_id}")
125+
else:
126+
print("Error: Project does not have a managed identity enabled")
127+
return
128+
129+
except Exception as e:
130+
print(f"Error retrieving project resource: {e}")
131+
return
132+
133+
# Define the Azure AI User role definition ID
134+
# This is the built-in role ID for "Azure AI User"
135+
azure_ai_user_role_id = "64702f94-c441-49e6-a78b-ef80e0188fee"
136+
137+
# Create the scope (project level)
138+
scope = f"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.CognitiveServices/accounts/{account_name}/projects/{project_name}"
139+
140+
# Create role assignment
141+
role_assignment_name = str(uuid.uuid4())
142+
143+
print(f"Assigning 'Azure AI User' role to managed identity...")
144+
145+
role_assignment = auth_client.role_assignments.create(
146+
scope=scope,
147+
role_assignment_name=role_assignment_name,
148+
parameters={
149+
"role_definition_id": f"{scope}/providers/Microsoft.Authorization/roleDefinitions/{azure_ai_user_role_id}",
150+
"principal_id": principal_id,
151+
"principal_type": "ServicePrincipal"
152+
}
153+
)
154+
155+
print(f"Successfully assigned 'Azure AI User' role to project managed identity")
156+
print(f"Role assignment ID: {role_assignment.name}")
157+
158+
except Exception as e:
159+
print(f"Error during role assignment: {e}")
160+
161+
# Check for specific error types and provide helpful guidance
162+
error_message = str(e)
163+
if "AuthorizationFailed" in error_message:
164+
print("\n🔒 AUTHORIZATION ERROR:")
165+
print("You don't have sufficient permissions to assign roles at this scope.")
166+
print("\n📋 REQUIRED PERMISSIONS:")
167+
print("To assign roles, you need one of the following roles:")
168+
print(" • Owner - Full access including role assignments")
169+
print(" • User Access Administrator - Can manage user access to Azure resources")
170+
print(" • Custom role with 'Microsoft.Authorization/roleAssignments/write' permission")
171+
print("\n🎯 SCOPE:")
172+
project_scope = f"/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.CognitiveServices/accounts/{account_name}/projects/{project_name}"
173+
print(f" Resource: {project_scope}")
174+
print("\n💡 SOLUTIONS:")
175+
print("1. Ask your Azure administrator to grant you 'Owner' or 'User Access Administrator' role")
176+
print("2. Ask your admin to assign the 'Azure AI User' role to the project's managed identity")
177+
print("3. Run this script with an account that has the required permissions")
178+
print("4. If you recently got permissions, try refreshing your credentials:")
179+
print(" - Run 'az logout && az login' in Azure CLI")
180+
print(" - Or restart this application")
181+
raise
182+
183+
elif "RoleAssignmentExists" in error_message:
184+
print("\n✅ ROLE ASSIGNMENT ALREADY EXISTS:")
185+
print("The 'Azure AI User' role is already assigned to the project's managed identity.")
186+
print("No action needed - the required permissions are already in place.")
187+
188+
elif "InvalidResourceTypeNameFormat" in error_message:
189+
print("\n🔧 RESOURCE FORMAT ERROR:")
190+
print("The resource path format is incorrect. Please check:")
191+
print(" • Resource group name is correct")
192+
print(" • Project endpoint format matches expected pattern")
193+
print(" • Account and project names are properly extracted")
194+
raise ValueError("Invalid resource type name format")
195+
196+
elif "NoRegisteredProviderFound" in error_message:
197+
print("\n🌐 API VERSION ERROR:")
198+
print("The API version or resource type is not supported in this region.")
199+
print("This usually indicates a service availability issue.")
200+
201+
else:
202+
print(f"\n❌ UNEXPECTED ERROR:")
203+
print("An unexpected error occurred. Please check the error details above.")
204+
raise
61205

62206
def schedule_dataset_evaluation() -> None:
63207
endpoint = os.environ[

0 commit comments

Comments
 (0)