Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions azure_custom.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
name: multi-agent-custom-automation-engine-solution-accelerator
metadata:
template: [email protected]
requiredVersions:
azd: ">=1.15.0 !=1.17.1"

services:
backend:
project: ./src/backend
language: py
host: containerapp
docker:
image: backend
remoteBuild: true

frontend:
project: ./src/frontend
language: py
host: appservice
dist: ./dist
hooks:
prepackage:
windows:
shell: pwsh
run: ../../infra/scripts/package_frontend.ps1
interactive: true
continueOnError: false
posix:
shell: sh
run: bash ../../infra/scripts/package_frontend.sh
interactive: true
continueOnError: false
2 changes: 2 additions & 0 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -1739,3 +1739,5 @@ output AZURE_AI_MODEL_DEPLOYMENT_NAME string = aiFoundryAiServicesModelDeploymen
output AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME string = aiFoundryAiServicesModelDeployment.name
output AZURE_AI_AGENT_ENDPOINT string = aiFoundryAiServices.outputs.aiProjectInfo.apiEndpoint
output APP_ENV string = 'Prod'
output AI_FOUNDRY_RESOURCE_ID string = aiFoundryAiServices.outputs.resourceId
output COSMOSDB_ACCOUNT_NAME string = cosmosDbResourceName
1,798 changes: 1,798 additions & 0 deletions infra/main_custom.bicep

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions infra/scripts/add_cosmosdb_access.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash

# Variables
resource_group="$1"
account_name="$2"
principal_ids="$3"

# Authenticate with Azure
if az account show &> /dev/null; then
echo "Already authenticated with Azure."
else
if [ -n "$managedIdentityClientId" ]; then
# Use managed identity if running in Azure
echo "Authenticating with Managed Identity..."
az login --identity --client-id ${managedIdentityClientId}
else
# Use Azure CLI login if running locally
echo "Authenticating with Azure CLI..."
az login
fi
echo "Not authenticated with Azure. Attempting to authenticate..."
fi


IFS=',' read -r -a principal_ids_array <<< $principal_ids

echo "Assigning Cosmos DB Built-in Data Contributor role to users"
for principal_id in "${principal_ids_array[@]}"; do

# Check if the user has the Cosmos DB Built-in Data Contributor role
echo "Checking if user - ${principal_id} has the Cosmos DB Built-in Data Contributor role"
roleExists=$(az cosmosdb sql role assignment list \
--resource-group $resource_group \
--account-name $account_name \
--query "[?roleDefinitionId.ends_with(@, '00000000-0000-0000-0000-000000000002') && principalId == '$principal_id']" -o tsv)

# Check if the role exists
if [ -n "$roleExists" ]; then
echo "User - ${principal_id} already has the Cosmos DB Built-in Data Contributer role."
else
echo "User - ${principal_id} does not have the Cosmos DB Built-in Data Contributer role. Assigning the role."
MSYS_NO_PATHCONV=1 az cosmosdb sql role assignment create \
--resource-group $resource_group \
--account-name $account_name \
--role-definition-id 00000000-0000-0000-0000-000000000002 \
--principal-id $principal_id \
--scope "/" \
--output none
if [ $? -eq 0 ]; then
echo "Cosmos DB Built-in Data Contributer role assigned successfully."
else
echo "Failed to assign Cosmos DB Built-in Data Contributer role."
fi
fi
done
49 changes: 49 additions & 0 deletions infra/scripts/assign_azure_ai_user_role.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

# Variables
resource_group="$1"
aif_resource_id="$2"
principal_ids="$3"


# Authenticate with Azure
if az account show &> /dev/null; then
echo "Already authenticated with Azure."
else
if [ -n "$managedIdentityClientId" ]; then
# Use managed identity if running in Azure
echo "Authenticating with Managed Identity..."
az login --identity --client-id ${managedIdentityClientId}
else
# Use Azure CLI login if running locally
echo "Authenticating with Azure CLI..."
az login
fi
echo "Not authenticated with Azure. Attempting to authenticate..."
fi


IFS=',' read -r -a principal_ids_array <<< $principal_ids

echo "Assigning Azure AI User role role to users"

echo "Using provided Azure AI resource id: $aif_resource_id"

for principal_id in "${principal_ids_array[@]}"; do

# Check if the user has the Azure AI User role
echo "Checking if user - ${principal_id} has the Azure AI User role"
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)
if [ -z "$role_assignment" ]; then
echo "User - ${principal_id} does not have the Azure AI User role. Assigning the role."
MSYS_NO_PATHCONV=1 az role assignment create --assignee $principal_id --role 53ca6127-db72-4b80-b1b0-d745d6d5456d --scope $aif_resource_id --output none
if [ $? -eq 0 ]; then
echo "Azure AI User role assigned successfully."
else
echo "Failed to assign Azure AI User role."
exit 1
fi
else
echo "User - ${principal_id} already has the Azure AI User role."
fi
done
163 changes: 163 additions & 0 deletions infra/scripts/cosmosdb_and_ai_user_role_assignment.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
#!/bin/bash

# Variables

principal_ids="$1"
cosmosDbAccountName="$2"
resourceGroupName="$3"
managedIdentityClientId="$4"
aif_resource_id="${5}"

# Function to merge and deduplicate principal IDs
merge_principal_ids() {
local param_ids="$1"
local env_ids="$2"
local all_ids=""

# Add parameter IDs if provided
if [ -n "$param_ids" ]; then
all_ids="$param_ids"
fi

signed_user_id=$(az ad signed-in-user show --query id -o tsv)

# Add environment variable IDs if provided
if [ -n "$env_ids" ]; then
if [ -n "$all_ids" ]; then
all_ids="$all_ids,$env_ids"
else
all_ids="$env_ids"
fi
fi

all_ids="$all_ids,$signed_user_id"
# Remove duplicates and return
if [ -n "$all_ids" ]; then
# Convert to array, remove duplicates, and join back
IFS=',' read -r -a ids_array <<< "$all_ids"
declare -A unique_ids
for id in "${ids_array[@]}"; do
# Trim whitespace
id=$(echo "$id" | xargs)
if [ -n "$id" ]; then
unique_ids["$id"]=1
fi
done

# Join unique IDs back with commas
local result=""
for id in "${!unique_ids[@]}"; do
if [ -n "$result" ]; then
result="$result,$id"
else
result="$id"
fi
done
echo "$result"
fi
}


# get parameters from azd env, if not provided
if [ -z "$resourceGroupName" ]; then
resourceGroupName=$(azd env get-value AZURE_RESOURCE_GROUP)
fi

if [ -z "$cosmosDbAccountName" ]; then
cosmosDbAccountName=$(azd env get-value COSMOSDB_ACCOUNT_NAME)
fi

if [ -z "$aif_resource_id" ]; then
aif_resource_id=$(azd env get-value AI_FOUNDRY_RESOURCE_ID)
fi

azSubscriptionId=$(azd env get-value AZURE_SUBSCRIPTION_ID)
env_principal_ids=$(azd env get-value PRINCIPAL_IDS)

# Merge principal IDs from parameter and environment variable
principal_ids=$(merge_principal_ids "$principal_ids_param" "$env_principal_ids")

# Check if all required arguments are provided
if [ -z "$principal_ids" ] || [ -z "$cosmosDbAccountName" ] || [ -z "$resourceGroupName" ] || [ -z "$aif_resource_id" ] ; then
echo "Usage: $0 <principal_ids> <cosmosDbAccountName> <resourceGroupName> <managedIdentityClientId> <aif_resource_id>"
exit 1
fi

echo "Using principal IDs: $principal_ids"

# Authenticate with Azure
if az account show &> /dev/null; then
echo "Already authenticated with Azure."
else
if [ -n "$managedIdentityClientId" ]; then
# Use managed identity if running in Azure
echo "Authenticating with Managed Identity..."
az login --identity --client-id ${managedIdentityClientId}
else
# Use Azure CLI login if running locally
echo "Authenticating with Azure CLI..."
az login
fi
echo "Not authenticated with Azure. Attempting to authenticate..."
fi

#check if user has selected the correct subscription
currentSubscriptionId=$(az account show --query id -o tsv)
currentSubscriptionName=$(az account show --query name -o tsv)
if [ "$currentSubscriptionId" != "$azSubscriptionId" ]; then
echo "Current selected subscription is $currentSubscriptionName ( $currentSubscriptionId )."
read -rp "Do you want to continue with this subscription?(y/n): " confirmation
if [[ "$confirmation" != "y" && "$confirmation" != "Y" ]]; then
echo "Fetching available subscriptions..."
availableSubscriptions=$(az account list --query "[?state=='Enabled'].[name,id]" --output tsv)
while true; do
echo ""
echo "Available Subscriptions:"
echo "========================"
echo "$availableSubscriptions" | awk '{printf "%d. %s ( %s )\n", NR, $1, $2}'
echo "========================"
echo ""
read -rp "Enter the number of the subscription (1-$(echo "$availableSubscriptions" | wc -l)) to use: " subscriptionIndex
if [[ "$subscriptionIndex" =~ ^[0-9]+$ ]] && [ "$subscriptionIndex" -ge 1 ] && [ "$subscriptionIndex" -le $(echo "$availableSubscriptions" | wc -l) ]; then
selectedSubscription=$(echo "$availableSubscriptions" | sed -n "${subscriptionIndex}p")
selectedSubscriptionName=$(echo "$selectedSubscription" | cut -f1)
selectedSubscriptionId=$(echo "$selectedSubscription" | cut -f2)

# Set the selected subscription
if az account set --subscription "$selectedSubscriptionId"; then
echo "Switched to subscription: $selectedSubscriptionName ( $selectedSubscriptionId )"
break
else
echo "Failed to switch to subscription: $selectedSubscriptionName ( $selectedSubscriptionId )."
fi
else
echo "Invalid selection. Please try again."
fi
done
else
echo "Proceeding with the current subscription: $currentSubscriptionName ( $currentSubscriptionId )"
az account set --subscription "$currentSubscriptionId"
fi
else
echo "Proceeding with the subscription: $currentSubscriptionName ( $currentSubscriptionId )"
az account set --subscription "$currentSubscriptionId"
fi

# Call add_cosmosdb_access.sh
echo "Running add_cosmosdb_access.sh"
bash infra/scripts/add_cosmosdb_access.sh "$resourceGroupName" "$cosmosDbAccountName" "$principal_ids" "$managedIdentityClientId"
if [ $? -ne 0 ]; then
echo "Error: add_cosmosdb_access.sh failed."
exit 1
fi
echo "add_cosmosdb_access.sh completed successfully."


# Call add_cosmosdb_access.sh
echo "Running assign_azure_ai_user_role.sh"
bash infra/scripts/assign_azure_ai_user_role.sh "$resourceGroupName" "$aif_resource_id" "$principal_ids" "$managedIdentityClientId"
if [ $? -ne 0 ]; then
echo "Error: assign_azure_ai_user_role.sh failed."
exit 1
fi
echo "assign_azure_ai_user_role.sh completed successfully."
11 changes: 11 additions & 0 deletions infra/scripts/package_frontend.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
mkdir dist -Force
rm dist/* -r -Force

# Python
cp requirements.txt dist -Force
cp *.py dist -Force

# Node
npm install
npm run build
cp -r build dist -Force
14 changes: 14 additions & 0 deletions infra/scripts/package_frontend.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -eou pipefail

mkdir -p dist
rm -rf dist/*

#python
cp -f requirements.txt dist
cp -f *.py dist

#node
npm install
npm run build
cp -rf build dist
13 changes: 8 additions & 5 deletions src/backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ WORKDIR /app
COPY uv.lock pyproject.toml /app/

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

# Backend app setup
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev
#RUN --mount=type=cache,target=/root/.cache/uv uv sync --frozen --no-dev
RUN uv sync --frozen --no-dev


FROM base

Expand Down
Loading
Loading