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
34 changes: 27 additions & 7 deletions docs/DeploymentGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,16 +335,23 @@ The files for the dev container are located in `/.devcontainer/` folder.

- If you are using `venv`, create and activate your virtual environment for both the frontend and backend folders.

8. **Install requirements - frontend:**
8. **Install requirements - Backend:**

- In each of the frontend and backend folders -
Open a terminal in the `src` folder and run:
- To install the requirement for backend -
Open a terminal in the `src/backend` folder and run:
```bash
pip install -r requirements.txt
pip install uv
uv sync
```

9. **Build the frontend (important):**

- To install the requirement for frontend -
Open a terminal in the `src/frontend` folder and run:
```bash
pip install -r requirements.txt
```

- Before running the frontend server, you must build the frontend to generate the necessary `build/assets` directory.

From the `src/frontend` directory, run:
Expand All @@ -356,7 +363,7 @@ The files for the dev container are located in `/.devcontainer/` folder.

10. **Run the application:**

- From the src/backend directory:
- From the src/backend directory activate the virtual environment created through step 8:

```bash
python app_kernel.py
Expand All @@ -368,8 +375,21 @@ python app_kernel.py
python frontend_server.py
```

10. Open a browser and navigate to `http://localhost:3000`
11. To see swagger API documentation, you can navigate to `http://localhost:8000/docs`
11. Open a browser and navigate to `http://localhost:3000`
12. To see swagger API documentation, you can navigate to `http://localhost:8000/docs`

## Deploy Your local changes

To Deploy your local changes rename the below files.

1. Rename `azure.yaml` to `azure_custom2.yaml` and `azure_custom.yaml` to `azure.yaml`.
2. Go to `infra` directory
- Remove `main.bicep` to `main_custom2.bicep` and `main_custom.bicep` to `main.bicep`.

Continue with the [deploying steps](#deploying-with-azd).




## Debugging the solution locally

Expand Down
201 changes: 201 additions & 0 deletions infra/main_custom.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,22 @@ module containerApp 'br/public:avm/res/app/container-app:0.14.2' = if (container
name: 'APP_ENV'
value: 'Prod'
}
{
name: 'AZURE_STORAGE_BLOB_URL'
value: avmStorageAccount.outputs.serviceEndpoints.blob
}
{
name: 'AZURE_STORAGE_CONTAINER_NAME'
value: storageContainerName
}
{
name: 'AZURE_SEARCH_ENDPOINT'
value: searchService.outputs.endpoint
}
{
name: 'AZURE_SEARCH_CONNECTION_NAME'
value: aiSearchConnectionName
}
]
}
]
Expand Down Expand Up @@ -1274,6 +1290,186 @@ module webSite 'br/public:avm/res/web/site:0.15.1' = if (webSiteEnabled) {
}
}


// ========== Storage Account ========== //

module privateDnsZonesStorageAccount 'br/public:avm/res/network/private-dns-zone:0.7.0' = if (virtualNetworkEnabled) {
name: take('avm.res.network.private-dns-zone.storage-account.${solutionPrefix}', 64)
params: {
name: 'privatelink.blob.core.windows.net'
enableTelemetry: enableTelemetry
virtualNetworkLinks: [
{
name: 'vnetlink-storage-account'
virtualNetworkResourceId: virtualNetwork.outputs.resourceId
}
]
tags: tags
}
}

var storageAccountName = replace('st${solutionPrefix}', '-', '')
param storageContainerName string = 'sample-dataset'
module avmStorageAccount 'br/public:avm/res/storage/storage-account:0.20.0' = {
name: take('avm.res.storage.storage-account.${storageAccountName}', 64)
params: {
name: storageAccountName
location: solutionLocation
managedIdentities: { systemAssigned: true }
minimumTlsVersion: 'TLS1_2'
enableTelemetry: enableTelemetry
tags: tags
accessTier: 'Hot'
supportsHttpsTrafficOnly: true

roleAssignments: [
{
principalId: userAssignedIdentity.outputs.principalId
roleDefinitionIdOrName: 'Storage Blob Data Contributor'
principalType: 'ServicePrincipal'
}
{
principalId: deployingUserPrincipalId
roleDefinitionIdOrName: 'Storage Blob Data Contributor'
principalType: 'User'
}
]

// WAF aligned networking
networkAcls: {
bypass: 'AzureServices'
defaultAction: virtualNetworkEnabled ? 'Deny' : 'Allow'
}
allowBlobPublicAccess: false
publicNetworkAccess: virtualNetworkEnabled ? 'Disabled' : 'Enabled'

// Private endpoints for blob
privateEndpoints: virtualNetworkEnabled
? [
{
name: 'pep-blob-${solutionPrefix}'
privateDnsZoneGroup: {
privateDnsZoneGroupConfigs: [
{
name: 'storage-dns-zone-group-blob'
privateDnsZoneResourceId: privateDnsZonesStorageAccount.outputs.resourceId
}
]
}
subnetResourceId: virtualNetwork.outputs.subnetResourceIds[0]
service: 'blob'
}
]
: []
blobServices: {
automaticSnapshotPolicyEnabled: true
containerDeleteRetentionPolicyDays: 10
containerDeleteRetentionPolicyEnabled: true
containers: [
{
name: storageContainerName
publicAccess: 'None'
}
]
deleteRetentionPolicyDays: 9
deleteRetentionPolicyEnabled: true
lastAccessTimeTrackingPolicyEnabled: true
}
}
}

// ========== Search Service ========== //

module privateDnsZonesSearchService 'br/public:avm/res/network/private-dns-zone:0.7.0' = if (virtualNetworkEnabled) {
name: take('avm.res.network.private-dns-zone.search-service.${solutionPrefix}', 64)
params: {
name: 'privatelink.search.windows.net'
enableTelemetry: enableTelemetry
virtualNetworkLinks: [
{
name: 'vnetlink-search-service'
virtualNetworkResourceId: virtualNetwork.outputs.resourceId
}
]
tags: tags
}
}

var searchServiceName = 'srch-${solutionPrefix}'
module searchService 'br/public:avm/res/search/search-service:0.11.1' = {
name: take('avm.res.search.search-service.${solutionPrefix}', 64)
params: {
name: searchServiceName
authOptions: {
aadOrApiKey: {
aadAuthFailureMode: 'http401WithBearerChallenge'
}
}
disableLocalAuth: false
hostingMode: 'default'
managedIdentities: {
systemAssigned: true
}
publicNetworkAccess: virtualNetworkEnabled ? 'Disabled' : 'Enabled'
networkRuleSet: {
bypass: 'AzureServices'
}
partitionCount: 1
replicaCount: 1
sku: 'standard'
tags: tags
roleAssignments: [
{
principalId: userAssignedIdentity.outputs.principalId
roleDefinitionIdOrName: 'Search Index Data Contributor'
principalType: 'ServicePrincipal'
}
{
principalId: deployingUserPrincipalId
roleDefinitionIdOrName: 'Search Index Data Contributor'
principalType: 'User'
}
]
privateEndpoints: virtualNetworkEnabled
? [
{
name: 'pep-search-${solutionPrefix}'
privateDnsZoneGroup: {
privateDnsZoneGroupConfigs: [
{
privateDnsZoneResourceId: privateDnsZonesSearchService.outputs.resourceId
}
]
}
subnetResourceId: virtualNetwork.outputs.subnetResourceIds[0]
service: 'searchService'
}
]
: []
}
}

// ========== Search Service - AI Project Connection ========== //

var aiSearchConnectionName = 'aifp-srch-connection-${solutionPrefix}'
var aifSubscriptionId = useExistingFoundryProject ? split(existingFoundryProjectResourceId, '/')[2] : subscription().subscriptionId
var aifResourceGroup = useExistingFoundryProject ? split(existingFoundryProjectResourceId, '/')[4] : resourceGroup().name
module aiSearchFoundryConnection 'modules/aifp_search_connection.bicep' = if (aiFoundryAIservicesEnabled) {
name: take('aifp-srch-connection.${solutionPrefix}', 64)
scope: resourceGroup(aifSubscriptionId, aifResourceGroup)
params: {
aiFoundryProjectName: aiFoundryAiProjectName
aiFoundryName: aiFoundryAiServicesResourceName
aifSearchConnectionName: aiSearchConnectionName
searchServiceResourceId: searchService.outputs.resourceId
searchServiceLocation: searchService.outputs.location
searchServiceName: searchService.outputs.name
}
dependsOn: [
aiFoundryAiServices
]
}

// ============ //
// Outputs //
// ============ //
Expand All @@ -1283,6 +1479,11 @@ module webSite 'br/public:avm/res/web/site:0.15.1' = if (webSiteEnabled) {
@description('The default url of the website to connect to the Multi-Agent Custom Automation Engine solution.')
output webSiteDefaultHostname string = webSite.outputs.defaultHostname

output AZURE_STORAGE_BLOB_URL string = avmStorageAccount.outputs.serviceEndpoints.blob
output AZURE_STORAGE_ACCOUNT_NAME string = storageAccountName
output AZURE_STORAGE_CONTAINER_NAME string = storageContainerName
output AZURE_SEARCH_ENDPOINT string = searchService.outputs.endpoint
output AZURE_SEARCH_NAME string = searchService.outputs.name


output AZURE_CONTAINER_REGISTRY_ENDPOINT string = containerRegistry.outputs.loginServer
Expand Down
Loading
Loading