Skip to content
Merged
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
26 changes: 11 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,17 @@ You can optionally use a local development server to test app changes locally. M
```

4. Install [Node.js](https://nodejs.org/) (v20 or later).

5. Install [pnpm](https://pnpm.io/installation)

5. Navigate to the frontend directory and setup for React UI:
6. Navigate to the frontend directory and setup for React UI:

```shell
cd src/frontend
pnpm run setup
```

6. Fill in the environment variables in `.env`.
7. Fill in the environment variables in `.env`.

(Optional) if you have changes in `src/frontend`, execute:

Expand Down Expand Up @@ -277,13 +279,7 @@ The build output will be placed in the `../api/static/react` directory, where th

Once you've opened the project in [Codespaces](#github-codespaces) or in [Dev Containers](#vs-code-dev-containers) or [locally](#local-environment), you can deploy it to Azure following the following steps.

1. Login to Azure:

```shell
azd auth login
```

2. (Optional) If you would like to customize the deployment to [disable resources](docs/deploy_customization.md#disabling-resources), [customize resource names](docs/deploy_customization.md#customizing-resource-names), [customize the models](docs/deploy_customization.md#customizing-model-deployments) or [increase quota](docs/deploy_customization.md#setting-capacity-and-deployment-sku), you can follow those steps now.
1. (Optional) If you would like to customize the deployment to [disable resources](docs/deploy_customization.md#disabling-resources), [customize resource names](docs/deploy_customization.md#customizing-resource-names), [customize the models](docs/deploy_customization.md#customizing-model-deployments) or [increase quota](docs/deploy_customization.md#setting-capacity-and-deployment-sku), you can follow those steps now.

⚠️ **NOTE!** For optimal performance, the recommended quota is 100k tokens per minute. If you have the capacity, we recommend increasing the quota by running the following command:

Expand All @@ -293,21 +289,21 @@ Once you've opened the project in [Codespaces](#github-codespaces) or in [Dev Co

⚠️ If you do not increase your quota, you may encounter rate limit issues. If needed, you can increase the quota after deployment by editing your model in the Models and Endpoints tab of the [Azure AI Foundry Portal](https://ai.azure.com/).

3. Provision and deploy all the resources with public docker image `azdtemplate.azurecr.io/get-start-with-ai-agents:latest` by running the following in get-started-with-ai-agents directory:
2. Provision and deploy all the resources with public docker image `azdtemplate.azurecr.io/get-start-with-ai-agents:latest` by running the following in get-started-with-ai-agents directory:

```shell
azd up
```

4. You will be prompted to provide an `azd` environment name (like "azureaiapp"), select a subscription from your Azure account, and select a location which has quota for all the resources. Then, it will provision the resources in your account and deploy the latest code.
3. You will be prompted to provide an `azd` environment name (like "azureaiapp"), select a subscription from your Azure account, and select a location which has quota for all the resources. Then, it will provision the resources in your account and deploy the latest code.

- For guidance on selecting a region with quota and model availability, follow the instructions in the [quota recommendations](#quota-recommendations-optional) section and ensure that your model is available in your selected region by checking the [list of models supported by Azure AI Agent Service](https://learn.microsoft.com/azure/ai-services/agents/concepts/model-region-support)
- This deployment will take 7-10 minutes to provision the resources in your account and set up the solution with sample data.
- If you get an error or timeout with deployment, changing the location can help, as there may be availability constraints for the resources. You can do this by running `azd down` and deleting the `.azure` folder from your code, and then running `azd up` again and selecting a new region.

**NOTE!** If you get authorization failed and/or permission related errors during the deployment, please refer to the Azure account requirements in the [Prerequisites](#prerequisites) section. If you were recently granted these permissions, it may take a few minutes for the authorization to apply.

5. When `azd` has finished deploying, you'll see an endpoint URI in the command output. Visit that URI, and you should see the app! 🎉
4. When `azd` has finished deploying, you'll see an endpoint URI in the command output. Visit that URI, and you should see the app! 🎉

- From here, you can interact with the agent. Try chatting with the agent by asking for a joke, or you could try a more specific query to see the agent's citation capabilities. By default, this solution uploads two documents from the `src/files` folder. To see the agent use this information, try asking about Contoso's products.

Expand All @@ -317,13 +313,13 @@ Once you've opened the project in [Codespaces](#github-codespaces) or in [Dev Co
azd show
```

6. (Optional) Now that your app has deployed, you can view your resources in the Azure Portal and your deployments in Azure AI Foundry.
5. (Optional) Now that your app has deployed, you can view your resources in the Azure Portal and your deployments in Azure AI Foundry.
- In the [Azure Portal](https://portal.azure.com/), navigate to your environment's resource group. The name will be `rg-[your environment name]`. Here, you should see your container app, storage account, and all of the other [resources](#resources) that are created in the deployment.
- In the [Azure AI Foundry Portal](https://ai.azure.com/), select your project. If you navigate to the Agents tab, you should be able to view your new agent, named `agent-template-assistant`. If you navigate to the Models and Endpoints tab, you should see your AI Services connection with your model deployments.

7. (Optional) You can use a local development server to test app changes locally. To do so, follow the steps in [local deployment server](#local-development-server) after your app is deployed.
6. (Optional) You can use a local development server to test app changes locally. To do so, follow the steps in [local deployment server](#local-development-server) after your app is deployed.

8. (Optional) Follow this [tutorial](https://learn.microsoft.com/en-us/azure/container-registry/container-registry-tutorial-quick-task) to build your changes into a Docker image and deploy to Azure Container App.
7. (Optional) To redeploy, run `azd deploy`. This will cause new docker image rebuilt, push to Azure Container Registry, and a new revision in Azure Container App with a new docker image.

## Tracing and Monitoring

Expand Down
22 changes: 20 additions & 2 deletions azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

name: azd-get-started-with-ai-agents
metadata:
template: [email protected].0
template: [email protected].1

hooks:
preup:
Expand All @@ -29,7 +29,25 @@ hooks:
run: chmod u+r+x ./scripts/write_env.sh; ./scripts/write_env.sh;
continueOnError: true
interactive: true

postdeploy:
windows:
shell: pwsh
run: ./scripts/postdeploy.ps1
continueOnError: true
interactive: true
posix:
shell: sh
run: chmod u+r+x ./scripts/postdeploy.sh; ./scripts/postdeploy.sh;
continueOnError: true
interactive: true
services:
api_and_frontend:
project: ./src
language: py
host: containerapp
docker:
image: api_and_frontend
remoteBuild: true
pipeline:
variables:
- AZURE_RESOURCE_GROUP
Expand Down
10 changes: 9 additions & 1 deletion docs/deploy_customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ This document describes how to customize the deployment of the Agents Chat with
* [Customizing model deployments](#customizing-model-deployments)

## Use existing resources
Be default, this template provisions a new resource group along with other resources. If you already have provisioned Azure AI Foundry and Azure AI Foundry Project, you might reuse these resources by setting:
Be default, this template provisions a new resource group along with other resources. If you already have provisioned Azure AI Foundry and Azure AI Foundry Project (not a hub based project), you might reuse these resources by setting:

To find the value:

1. Open the azure portal
2. Navigate to the AI foundry resource
3. Select projects in the sidebar and open the desired project
4. Oo to 'Resource Management' -> 'Properties' in the sidebar
5. Copy the value from 'Resource ID'

```shell
azd env set AZURE_EXISTING_AIPROJECT_RESOURCE_ID "https://<your-ai-services-account-name>.services.ai.azure.com/api/projects/<your-project-name>"
Expand Down
6 changes: 3 additions & 3 deletions infra/api.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ param name string
param location string = resourceGroup().location
param tags object = {}

param containerRegistryName string
param identityName string
param containerAppsEnvironmentName string
param azureExistingAIProjectResourceId string
Expand All @@ -13,7 +14,6 @@ param embeddingDeploymentDimensions string
param searchServiceEndpoint string
param agentName string
param agentID string
param projectName string
param enableAzureMonitorTracing bool
param azureTracingGenAIContentRecordingEnabled bool
param projectEndpoint string
Expand Down Expand Up @@ -89,12 +89,12 @@ module app 'core/host/container-app-upsert.bicep' = {
params: {
name: name
location: location
tags: tags
tags: union(tags, { 'azd-service-name': 'api_and_frontend' })
identityName: apiIdentity.name
containerRegistryName: containerRegistryName
containerAppsEnvironmentName: containerAppsEnvironmentName
targetPort: 50505
env: env
projectName: projectName
}
}

Expand Down
19 changes: 17 additions & 2 deletions infra/core/host/container-app-upsert.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ param containerMinReplicas int = 1
@description('The name of the container')
param containerName string = 'main'

@description('The name of the container registry')
param containerRegistryName string

@description('Hostname suffix for container registry. Set when deploying to sovereign clouds')
param containerRegistryHostSuffix string = 'azurecr.io'

@allowed([ 'http', 'grpc' ])
@description('The protocol used by Dapr to connect to the app, e.g., HTTP or gRPC')
param daprAppProtocol string = 'http'
Expand All @@ -43,6 +49,9 @@ param identityType string = 'None'
@description('The name of the user-assigned identity')
param identityName string = ''

@description('The name of the container image')
param imageName string = ''

@description('The secrets required for the container')
@secure()
param secrets object = {}
Expand All @@ -59,8 +68,12 @@ param serviceBinds array = []
@description('The target port for the container')
param targetPort int = 80

param projectName string
@description('Specifies if the resource already exists')
param exists bool = false

resource existingApp 'Microsoft.App/containerApps@2023-05-02-preview' existing = if (exists) {
name: name
}

module app 'container-app.bicep' = {
name: '${deployment().name}-update'
Expand All @@ -73,6 +86,8 @@ module app 'container-app.bicep' = {
ingressEnabled: ingressEnabled
containerName: containerName
containerAppsEnvironmentName: containerAppsEnvironmentName
containerRegistryName: containerRegistryName
containerRegistryHostSuffix: containerRegistryHostSuffix
containerCpuCoreCount: containerCpuCoreCount
containerMemory: containerMemory
containerMinReplicas: containerMinReplicas
Expand All @@ -83,9 +98,9 @@ module app 'container-app.bicep' = {
secrets: secrets
external: external
env: env
imageName: !empty(imageName) ? imageName : exists ? existingApp.properties.template.containers[0].image : ''
targetPort: targetPort
serviceBinds: serviceBinds
dependOn: projectName
}
}

Expand Down
28 changes: 26 additions & 2 deletions infra/core/host/container-app.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ param containerMinReplicas int = 1
@description('The name of the container')
param containerName string = 'main'

@description('The name of the container registry')
param containerRegistryName string = ''

@description('Hostname suffix for container registry. Set when deploying to sovereign clouds')
param containerRegistryHostSuffix string = 'azurecr.io'

@description('The protocol used by Dapr to connect to the app, e.g., http or grpc')
@allowed([ 'http', 'grpc' ])
param daprAppProtocol string = 'http'
Expand All @@ -48,6 +54,8 @@ param identityName string = ''
@allowed([ 'None', 'SystemAssigned', 'UserAssigned' ])
param identityType string = 'None'

@description('The name of the container image')
param imageName string = ''

@description('Specifies if Ingress is enabled for the container app')
param ingressEnabled bool = true
Expand All @@ -73,9 +81,20 @@ resource userIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-
name: identityName
}

// Private registry support requires both an ACR name and a User Assigned managed identity
var usePrivateRegistry = !empty(identityName) && !empty(containerRegistryName)

// Automatically set to `UserAssigned` when an `identityName` has been set
var normalizedIdentityType = !empty(identityName) ? 'UserAssigned' : identityType

module containerRegistryAccess '../security/registry-access.bicep' = if (usePrivateRegistry) {
name: '${deployment().name}-registry-access'
params: {
containerRegistryName: containerRegistryName
principalId: usePrivateRegistry ? userIdentity.properties.principalId : ''
}
}

resource app 'Microsoft.App/containerApps@2023-05-02-preview' = {
name: name
location: location
Expand Down Expand Up @@ -112,13 +131,18 @@ resource app 'Microsoft.App/containerApps@2023-05-02-preview' = {
value: secret.value
}]
service: !empty(serviceType) ? { type: serviceType } : null
registries: []
registries: usePrivateRegistry ? [
{
server: '${containerRegistryName}.${containerRegistryHostSuffix}'
identity: userIdentity.id
}
] : []
}
template: {
serviceBinds: !empty(serviceBinds) ? serviceBinds : null
containers: [
{
image: 'azdtemplate.azurecr.io/get-start-with-ai-agents:latest'
image: !empty(imageName) ? imageName : 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
name: containerName
env: env
resources: {
Expand Down
17 changes: 16 additions & 1 deletion infra/core/host/container-apps.bicep
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
metadata description = 'Creates an Azure Container Apps environment.'
metadata description = 'Creates an Azure Container Registry and an Azure Container Apps environment.'
param name string
param location string = resourceGroup().location
param tags object = {}

param containerAppsEnvironmentName string
param containerRegistryName string
param containerRegistryAdminUserEnabled bool = false
param logAnalyticsWorkspaceName string
param applicationInsightsName string = ''

Expand All @@ -18,7 +20,20 @@ module containerAppsEnvironment 'container-apps-environment.bicep' = {
}
}

module containerRegistry 'container-registry.bicep' = {
name: '${name}-container-registry'
scope: resourceGroup()
params: {
name: containerRegistryName
location: location
adminUserEnabled: containerRegistryAdminUserEnabled
tags: tags
}
}

output defaultDomain string = containerAppsEnvironment.outputs.defaultDomain
output environmentName string = containerAppsEnvironment.outputs.name
output environmentId string = containerAppsEnvironment.outputs.id

output registryLoginServer string = containerRegistry.outputs.loginServer
output registryName string = containerRegistry.outputs.name
Loading