Skip to content

Commit 37bfb69

Browse files
committed
Add custom Azure infrastructure and scripts
Introduces azure_custom.yaml and main_custom.bicep for custom deployment scenarios, adds several infrastructure scripts for CosmosDB and Azure AI role assignments, and updates main.bicep outputs. Removes unused frontend components and services, and updates backend Dockerfile and foundry_service.py for new infrastructure integration.
2 parents 4ed204c + 939a622 commit 37bfb69

File tree

10 files changed

+2134
-7
lines changed

10 files changed

+2134
-7
lines changed

azure_custom.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
2+
name: multi-agent-custom-automation-engine-solution-accelerator
3+
metadata:
4+
5+
requiredVersions:
6+
azd: ">=1.15.0 !=1.17.1"
7+
8+
services:
9+
backend:
10+
project: ./src/backend
11+
language: py
12+
host: containerapp
13+
docker:
14+
image: backend
15+
remoteBuild: true
16+
17+
frontend:
18+
project: ./src/frontend
19+
language: py
20+
host: appservice
21+
dist: ./dist
22+
hooks:
23+
prepackage:
24+
windows:
25+
shell: pwsh
26+
run: ../../infra/scripts/package_frontend.ps1
27+
interactive: true
28+
continueOnError: false
29+
posix:
30+
shell: sh
31+
run: bash ../../infra/scripts/package_frontend.sh
32+
interactive: true
33+
continueOnError: false

infra/main.bicep

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,3 +1739,5 @@ output AZURE_AI_MODEL_DEPLOYMENT_NAME string = aiFoundryAiServicesModelDeploymen
17391739
output AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME string = aiFoundryAiServicesModelDeployment.name
17401740
output AZURE_AI_AGENT_ENDPOINT string = aiFoundryAiServices.outputs.aiProjectInfo.apiEndpoint
17411741
output APP_ENV string = 'Prod'
1742+
output AI_FOUNDRY_RESOURCE_ID string = aiFoundryAiServices.outputs.resourceId
1743+
output COSMOSDB_ACCOUNT_NAME string = cosmosDbResourceName

infra/main_custom.bicep

Lines changed: 1798 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/bin/bash
2+
3+
# Variables
4+
resource_group="$1"
5+
account_name="$2"
6+
principal_ids="$3"
7+
8+
# Authenticate with Azure
9+
if az account show &> /dev/null; then
10+
echo "Already authenticated with Azure."
11+
else
12+
if [ -n "$managedIdentityClientId" ]; then
13+
# Use managed identity if running in Azure
14+
echo "Authenticating with Managed Identity..."
15+
az login --identity --client-id ${managedIdentityClientId}
16+
else
17+
# Use Azure CLI login if running locally
18+
echo "Authenticating with Azure CLI..."
19+
az login
20+
fi
21+
echo "Not authenticated with Azure. Attempting to authenticate..."
22+
fi
23+
24+
25+
IFS=',' read -r -a principal_ids_array <<< $principal_ids
26+
27+
echo "Assigning Cosmos DB Built-in Data Contributor role to users"
28+
for principal_id in "${principal_ids_array[@]}"; do
29+
30+
# Check if the user has the Cosmos DB Built-in Data Contributor role
31+
echo "Checking if user - ${principal_id} has the Cosmos DB Built-in Data Contributor role"
32+
roleExists=$(az cosmosdb sql role assignment list \
33+
--resource-group $resource_group \
34+
--account-name $account_name \
35+
--query "[?roleDefinitionId.ends_with(@, '00000000-0000-0000-0000-000000000002') && principalId == '$principal_id']" -o tsv)
36+
37+
# Check if the role exists
38+
if [ -n "$roleExists" ]; then
39+
echo "User - ${principal_id} already has the Cosmos DB Built-in Data Contributer role."
40+
else
41+
echo "User - ${principal_id} does not have the Cosmos DB Built-in Data Contributer role. Assigning the role."
42+
MSYS_NO_PATHCONV=1 az cosmosdb sql role assignment create \
43+
--resource-group $resource_group \
44+
--account-name $account_name \
45+
--role-definition-id 00000000-0000-0000-0000-000000000002 \
46+
--principal-id $principal_id \
47+
--scope "/" \
48+
--output none
49+
if [ $? -eq 0 ]; then
50+
echo "Cosmos DB Built-in Data Contributer role assigned successfully."
51+
else
52+
echo "Failed to assign Cosmos DB Built-in Data Contributer role."
53+
fi
54+
fi
55+
done
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/bash
2+
3+
# Variables
4+
resource_group="$1"
5+
aif_resource_id="$2"
6+
principal_ids="$3"
7+
8+
9+
# Authenticate with Azure
10+
if az account show &> /dev/null; then
11+
echo "Already authenticated with Azure."
12+
else
13+
if [ -n "$managedIdentityClientId" ]; then
14+
# Use managed identity if running in Azure
15+
echo "Authenticating with Managed Identity..."
16+
az login --identity --client-id ${managedIdentityClientId}
17+
else
18+
# Use Azure CLI login if running locally
19+
echo "Authenticating with Azure CLI..."
20+
az login
21+
fi
22+
echo "Not authenticated with Azure. Attempting to authenticate..."
23+
fi
24+
25+
26+
IFS=',' read -r -a principal_ids_array <<< $principal_ids
27+
28+
echo "Assigning Azure AI User role role to users"
29+
30+
echo "Using provided Azure AI resource id: $aif_resource_id"
31+
32+
for principal_id in "${principal_ids_array[@]}"; do
33+
34+
# Check if the user has the Azure AI User role
35+
echo "Checking if user - ${principal_id} has the Azure AI User role"
36+
role_assignment=$(MSYS_NO_PATHCONV=1 az role assignment list --role 53ca6127-db72-4b80-b1b0-d745d6d5456d --scope $aif_resource_id --assignee $principal_id --query "[].roleDefinitionId" -o tsv)
37+
if [ -z "$role_assignment" ]; then
38+
echo "User - ${principal_id} does not have the Azure AI User role. Assigning the role."
39+
MSYS_NO_PATHCONV=1 az role assignment create --assignee $principal_id --role 53ca6127-db72-4b80-b1b0-d745d6d5456d --scope $aif_resource_id --output none
40+
if [ $? -eq 0 ]; then
41+
echo "Azure AI User role assigned successfully."
42+
else
43+
echo "Failed to assign Azure AI User role."
44+
exit 1
45+
fi
46+
else
47+
echo "User - ${principal_id} already has the Azure AI User role."
48+
fi
49+
done
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#!/bin/bash
2+
3+
# Variables
4+
5+
principal_ids="$1"
6+
cosmosDbAccountName="$2"
7+
resourceGroupName="$3"
8+
managedIdentityClientId="$4"
9+
aif_resource_id="${5}"
10+
11+
# Function to merge and deduplicate principal IDs
12+
merge_principal_ids() {
13+
local param_ids="$1"
14+
local env_ids="$2"
15+
local all_ids=""
16+
17+
# Add parameter IDs if provided
18+
if [ -n "$param_ids" ]; then
19+
all_ids="$param_ids"
20+
fi
21+
22+
signed_user_id=$(az ad signed-in-user show --query id -o tsv)
23+
24+
# Add environment variable IDs if provided
25+
if [ -n "$env_ids" ]; then
26+
if [ -n "$all_ids" ]; then
27+
all_ids="$all_ids,$env_ids"
28+
else
29+
all_ids="$env_ids"
30+
fi
31+
fi
32+
33+
all_ids="$all_ids,$signed_user_id"
34+
# Remove duplicates and return
35+
if [ -n "$all_ids" ]; then
36+
# Convert to array, remove duplicates, and join back
37+
IFS=',' read -r -a ids_array <<< "$all_ids"
38+
declare -A unique_ids
39+
for id in "${ids_array[@]}"; do
40+
# Trim whitespace
41+
id=$(echo "$id" | xargs)
42+
if [ -n "$id" ]; then
43+
unique_ids["$id"]=1
44+
fi
45+
done
46+
47+
# Join unique IDs back with commas
48+
local result=""
49+
for id in "${!unique_ids[@]}"; do
50+
if [ -n "$result" ]; then
51+
result="$result,$id"
52+
else
53+
result="$id"
54+
fi
55+
done
56+
echo "$result"
57+
fi
58+
}
59+
60+
61+
# get parameters from azd env, if not provided
62+
if [ -z "$resourceGroupName" ]; then
63+
resourceGroupName=$(azd env get-value AZURE_RESOURCE_GROUP)
64+
fi
65+
66+
if [ -z "$cosmosDbAccountName" ]; then
67+
cosmosDbAccountName=$(azd env get-value COSMOSDB_ACCOUNT_NAME)
68+
fi
69+
70+
if [ -z "$aif_resource_id" ]; then
71+
aif_resource_id=$(azd env get-value AI_FOUNDRY_RESOURCE_ID)
72+
fi
73+
74+
azSubscriptionId=$(azd env get-value AZURE_SUBSCRIPTION_ID)
75+
env_principal_ids=$(azd env get-value PRINCIPAL_IDS)
76+
77+
# Merge principal IDs from parameter and environment variable
78+
principal_ids=$(merge_principal_ids "$principal_ids_param" "$env_principal_ids")
79+
80+
# Check if all required arguments are provided
81+
if [ -z "$principal_ids" ] || [ -z "$cosmosDbAccountName" ] || [ -z "$resourceGroupName" ] || [ -z "$aif_resource_id" ] ; then
82+
echo "Usage: $0 <principal_ids> <cosmosDbAccountName> <resourceGroupName> <managedIdentityClientId> <aif_resource_id>"
83+
exit 1
84+
fi
85+
86+
echo "Using principal IDs: $principal_ids"
87+
88+
# Authenticate with Azure
89+
if az account show &> /dev/null; then
90+
echo "Already authenticated with Azure."
91+
else
92+
if [ -n "$managedIdentityClientId" ]; then
93+
# Use managed identity if running in Azure
94+
echo "Authenticating with Managed Identity..."
95+
az login --identity --client-id ${managedIdentityClientId}
96+
else
97+
# Use Azure CLI login if running locally
98+
echo "Authenticating with Azure CLI..."
99+
az login
100+
fi
101+
echo "Not authenticated with Azure. Attempting to authenticate..."
102+
fi
103+
104+
#check if user has selected the correct subscription
105+
currentSubscriptionId=$(az account show --query id -o tsv)
106+
currentSubscriptionName=$(az account show --query name -o tsv)
107+
if [ "$currentSubscriptionId" != "$azSubscriptionId" ]; then
108+
echo "Current selected subscription is $currentSubscriptionName ( $currentSubscriptionId )."
109+
read -rp "Do you want to continue with this subscription?(y/n): " confirmation
110+
if [[ "$confirmation" != "y" && "$confirmation" != "Y" ]]; then
111+
echo "Fetching available subscriptions..."
112+
availableSubscriptions=$(az account list --query "[?state=='Enabled'].[name,id]" --output tsv)
113+
while true; do
114+
echo ""
115+
echo "Available Subscriptions:"
116+
echo "========================"
117+
echo "$availableSubscriptions" | awk '{printf "%d. %s ( %s )\n", NR, $1, $2}'
118+
echo "========================"
119+
echo ""
120+
read -rp "Enter the number of the subscription (1-$(echo "$availableSubscriptions" | wc -l)) to use: " subscriptionIndex
121+
if [[ "$subscriptionIndex" =~ ^[0-9]+$ ]] && [ "$subscriptionIndex" -ge 1 ] && [ "$subscriptionIndex" -le $(echo "$availableSubscriptions" | wc -l) ]; then
122+
selectedSubscription=$(echo "$availableSubscriptions" | sed -n "${subscriptionIndex}p")
123+
selectedSubscriptionName=$(echo "$selectedSubscription" | cut -f1)
124+
selectedSubscriptionId=$(echo "$selectedSubscription" | cut -f2)
125+
126+
# Set the selected subscription
127+
if az account set --subscription "$selectedSubscriptionId"; then
128+
echo "Switched to subscription: $selectedSubscriptionName ( $selectedSubscriptionId )"
129+
break
130+
else
131+
echo "Failed to switch to subscription: $selectedSubscriptionName ( $selectedSubscriptionId )."
132+
fi
133+
else
134+
echo "Invalid selection. Please try again."
135+
fi
136+
done
137+
else
138+
echo "Proceeding with the current subscription: $currentSubscriptionName ( $currentSubscriptionId )"
139+
az account set --subscription "$currentSubscriptionId"
140+
fi
141+
else
142+
echo "Proceeding with the subscription: $currentSubscriptionName ( $currentSubscriptionId )"
143+
az account set --subscription "$currentSubscriptionId"
144+
fi
145+
146+
# Call add_cosmosdb_access.sh
147+
echo "Running add_cosmosdb_access.sh"
148+
bash infra/scripts/add_cosmosdb_access.sh "$resourceGroupName" "$cosmosDbAccountName" "$principal_ids" "$managedIdentityClientId"
149+
if [ $? -ne 0 ]; then
150+
echo "Error: add_cosmosdb_access.sh failed."
151+
exit 1
152+
fi
153+
echo "add_cosmosdb_access.sh completed successfully."
154+
155+
156+
# Call add_cosmosdb_access.sh
157+
echo "Running assign_azure_ai_user_role.sh"
158+
bash infra/scripts/assign_azure_ai_user_role.sh "$resourceGroupName" "$aif_resource_id" "$principal_ids" "$managedIdentityClientId"
159+
if [ $? -ne 0 ]; then
160+
echo "Error: assign_azure_ai_user_role.sh failed."
161+
exit 1
162+
fi
163+
echo "assign_azure_ai_user_role.sh completed successfully."

infra/scripts/package_frontend.ps1

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
mkdir dist -Force
2+
rm dist/* -r -Force
3+
4+
# Python
5+
cp requirements.txt dist -Force
6+
cp *.py dist -Force
7+
8+
# Node
9+
npm install
10+
npm run build
11+
cp -r build dist -Force

infra/scripts/package_frontend.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
set -eou pipefail
3+
4+
mkdir -p dist
5+
rm -rf dist/*
6+
7+
#python
8+
cp -f requirements.txt dist
9+
cp -f *.py dist
10+
11+
#node
12+
npm install
13+
npm run build
14+
cp -rf build dist

src/backend/Dockerfile

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ WORKDIR /app
1010
COPY uv.lock pyproject.toml /app/
1111

1212
# Install the project's dependencies using the lockfile and settings
13-
RUN --mount=type=cache,target=/root/.cache/uv \
14-
--mount=type=bind,source=uv.lock,target=uv.lock \
15-
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
16-
uv sync --frozen --no-install-project --no-dev
13+
# RUN --mount=type=cache,target=/root/.cache/uv \
14+
# --mount=type=bind,source=uv.lock,target=uv.lock \
15+
# --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
16+
# uv sync --frozen --no-install-project --no-dev
17+
RUN uv sync --frozen --no-install-project --no-dev
1718

1819
# Backend app setup
1920
COPY . /app
20-
RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev
21+
#RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev
22+
RUN uv sync --frozen --no-dev
23+
2124

2225
FROM base
2326

src/backend/v3/common/services/foundry_service.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
from typing import Any, Dict
1+
from typing import Any, Dict, List
22
import logging
33
import re
44
from azure.ai.projects.aio import AIProjectClient
5-
from git import List
65
import aiohttp
76
from common.config.app_config import config
87

0 commit comments

Comments
 (0)