Skip to content

Commit ac1d46f

Browse files
authored
azd up build image now (#152)
* azd up and deploy build docker image * update readme * make sh executable * make sh executable * update permission * update version number * update doc
1 parent f81029a commit ac1d46f

15 files changed

+263
-57
lines changed

README.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,17 @@ You can optionally use a local development server to test app changes locally. M
237237
```
238238

239239
4. Install [Node.js](https://nodejs.org/) (v20 or later).
240+
241+
5. Install [pnpm](https://pnpm.io/installation)
240242

241-
5. Navigate to the frontend directory and setup for React UI:
243+
6. Navigate to the frontend directory and setup for React UI:
242244

243245
```shell
244246
cd src/frontend
245247
pnpm run setup
246248
```
247249

248-
6. Fill in the environment variables in `.env`.
250+
7. Fill in the environment variables in `.env`.
249251

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

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

278280
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.
279281
280-
1. Login to Azure:
281-
282-
```shell
283-
azd auth login
284-
```
285-
286-
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.
282+
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.
287283
288284
⚠️ **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:
289285
@@ -293,21 +289,21 @@ Once you've opened the project in [Codespaces](#github-codespaces) or in [Dev Co
293289
294290
⚠️ 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/).
295291
296-
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:
292+
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:
297293
298294
```shell
299295
azd up
300296
```
301297
302-
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.
298+
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.
303299
304300
- 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)
305301
- This deployment will take 7-10 minutes to provision the resources in your account and set up the solution with sample data.
306302
- 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.
307303
308304
**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.
309305
310-
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! 🎉
306+
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! 🎉
311307

312308
- 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.
313309

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

320-
6. (Optional) Now that your app has deployed, you can view your resources in the Azure Portal and your deployments in Azure AI Foundry.
316+
5. (Optional) Now that your app has deployed, you can view your resources in the Azure Portal and your deployments in Azure AI Foundry.
321317
- 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.
322318
- 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.
323319
324-
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.
320+
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.
325321
326-
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.
322+
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.
327323
328324
## Tracing and Monitoring
329325

azure.yaml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
name: azd-get-started-with-ai-agents
66
metadata:
7-
template: [email protected].0
7+
template: [email protected].1
88

99
hooks:
1010
preup:
@@ -29,7 +29,25 @@ hooks:
2929
run: chmod u+r+x ./scripts/write_env.sh; ./scripts/write_env.sh;
3030
continueOnError: true
3131
interactive: true
32-
32+
postdeploy:
33+
windows:
34+
shell: pwsh
35+
run: ./scripts/postdeploy.ps1
36+
continueOnError: true
37+
interactive: true
38+
posix:
39+
shell: sh
40+
run: chmod u+r+x ./scripts/postdeploy.sh; ./scripts/postdeploy.sh;
41+
continueOnError: true
42+
interactive: true
43+
services:
44+
api_and_frontend:
45+
project: ./src
46+
language: py
47+
host: containerapp
48+
docker:
49+
image: api_and_frontend
50+
remoteBuild: true
3351
pipeline:
3452
variables:
3553
- AZURE_RESOURCE_GROUP

docs/deploy_customization.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@ This document describes how to customize the deployment of the Agents Chat with
99
* [Customizing model deployments](#customizing-model-deployments)
1010

1111
## Use existing resources
12-
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:
12+
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:
13+
14+
To find the value:
15+
16+
1. Open the azure portal
17+
2. Navigate to the AI foundry resource
18+
3. Select projects in the sidebar and open the desired project
19+
4. Oo to 'Resource Management' -> 'Properties' in the sidebar
20+
5. Copy the value from 'Resource ID'
1321

1422
```shell
1523
azd env set AZURE_EXISTING_AIPROJECT_RESOURCE_ID "/subscriptions/<your-azure-subid>/resourceGroups/<your-rg>/providers/Microsoft.CognitiveServices/accounts/<your-ai-services-account-name>/projects/<your-project-name>"

infra/api.bicep

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ param name string
22
param location string = resourceGroup().location
33
param tags object = {}
44

5+
param containerRegistryName string
56
param identityName string
67
param containerAppsEnvironmentName string
78
param azureExistingAIProjectResourceId string
@@ -13,7 +14,6 @@ param embeddingDeploymentDimensions string
1314
param searchServiceEndpoint string
1415
param agentName string
1516
param agentID string
16-
param projectName string
1717
param enableAzureMonitorTracing bool
1818
param azureTracingGenAIContentRecordingEnabled bool
1919
param projectEndpoint string
@@ -89,12 +89,12 @@ module app 'core/host/container-app-upsert.bicep' = {
8989
params: {
9090
name: name
9191
location: location
92-
tags: tags
92+
tags: union(tags, { 'azd-service-name': 'api_and_frontend' })
9393
identityName: apiIdentity.name
94+
containerRegistryName: containerRegistryName
9495
containerAppsEnvironmentName: containerAppsEnvironmentName
9596
targetPort: 50505
9697
env: env
97-
projectName: projectName
9898
}
9999
}
100100

infra/core/host/container-app-upsert.bicep

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ param containerMinReplicas int = 1
2323
@description('The name of the container')
2424
param containerName string = 'main'
2525

26+
@description('The name of the container registry')
27+
param containerRegistryName string
28+
29+
@description('Hostname suffix for container registry. Set when deploying to sovereign clouds')
30+
param containerRegistryHostSuffix string = 'azurecr.io'
31+
2632
@allowed([ 'http', 'grpc' ])
2733
@description('The protocol used by Dapr to connect to the app, e.g., HTTP or gRPC')
2834
param daprAppProtocol string = 'http'
@@ -43,6 +49,9 @@ param identityType string = 'None'
4349
@description('The name of the user-assigned identity')
4450
param identityName string = ''
4551

52+
@description('The name of the container image')
53+
param imageName string = ''
54+
4655
@description('The secrets required for the container')
4756
@secure()
4857
param secrets object = {}
@@ -59,8 +68,12 @@ param serviceBinds array = []
5968
@description('The target port for the container')
6069
param targetPort int = 80
6170

62-
param projectName string
71+
@description('Specifies if the resource already exists')
72+
param exists bool = false
6373

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

6578
module app 'container-app.bicep' = {
6679
name: '${deployment().name}-update'
@@ -73,6 +86,8 @@ module app 'container-app.bicep' = {
7386
ingressEnabled: ingressEnabled
7487
containerName: containerName
7588
containerAppsEnvironmentName: containerAppsEnvironmentName
89+
containerRegistryName: containerRegistryName
90+
containerRegistryHostSuffix: containerRegistryHostSuffix
7691
containerCpuCoreCount: containerCpuCoreCount
7792
containerMemory: containerMemory
7893
containerMinReplicas: containerMinReplicas
@@ -83,9 +98,9 @@ module app 'container-app.bicep' = {
8398
secrets: secrets
8499
external: external
85100
env: env
101+
imageName: !empty(imageName) ? imageName : exists ? existingApp.properties.template.containers[0].image : ''
86102
targetPort: targetPort
87103
serviceBinds: serviceBinds
88-
dependOn: projectName
89104
}
90105
}
91106

infra/core/host/container-app.bicep

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ param containerMinReplicas int = 1
2525
@description('The name of the container')
2626
param containerName string = 'main'
2727

28+
@description('The name of the container registry')
29+
param containerRegistryName string = ''
30+
31+
@description('Hostname suffix for container registry. Set when deploying to sovereign clouds')
32+
param containerRegistryHostSuffix string = 'azurecr.io'
33+
2834
@description('The protocol used by Dapr to connect to the app, e.g., http or grpc')
2935
@allowed([ 'http', 'grpc' ])
3036
param daprAppProtocol string = 'http'
@@ -48,6 +54,8 @@ param identityName string = ''
4854
@allowed([ 'None', 'SystemAssigned', 'UserAssigned' ])
4955
param identityType string = 'None'
5056

57+
@description('The name of the container image')
58+
param imageName string = ''
5159

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

84+
// Private registry support requires both an ACR name and a User Assigned managed identity
85+
var usePrivateRegistry = !empty(identityName) && !empty(containerRegistryName)
86+
7687
// Automatically set to `UserAssigned` when an `identityName` has been set
7788
var normalizedIdentityType = !empty(identityName) ? 'UserAssigned' : identityType
7889

90+
module containerRegistryAccess '../security/registry-access.bicep' = if (usePrivateRegistry) {
91+
name: '${deployment().name}-registry-access'
92+
params: {
93+
containerRegistryName: containerRegistryName
94+
principalId: usePrivateRegistry ? userIdentity.properties.principalId : ''
95+
}
96+
}
97+
7998
resource app 'Microsoft.App/containerApps@2023-05-02-preview' = {
8099
name: name
81100
location: location
@@ -112,13 +131,18 @@ resource app 'Microsoft.App/containerApps@2023-05-02-preview' = {
112131
value: secret.value
113132
}]
114133
service: !empty(serviceType) ? { type: serviceType } : null
115-
registries: []
134+
registries: usePrivateRegistry ? [
135+
{
136+
server: '${containerRegistryName}.${containerRegistryHostSuffix}'
137+
identity: userIdentity.id
138+
}
139+
] : []
116140
}
117141
template: {
118142
serviceBinds: !empty(serviceBinds) ? serviceBinds : null
119143
containers: [
120144
{
121-
image: 'azdtemplate.azurecr.io/get-start-with-ai-agents:latest'
145+
image: !empty(imageName) ? imageName : 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
122146
name: containerName
123147
env: env
124148
resources: {

infra/core/host/container-apps.bicep

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
metadata description = 'Creates an Azure Container Apps environment.'
1+
metadata description = 'Creates an Azure Container Registry and an Azure Container Apps environment.'
22
param name string
33
param location string = resourceGroup().location
44
param tags object = {}
55

66
param containerAppsEnvironmentName string
7+
param containerRegistryName string
8+
param containerRegistryAdminUserEnabled bool = false
79
param logAnalyticsWorkspaceName string
810
param applicationInsightsName string = ''
911

@@ -18,7 +20,20 @@ module containerAppsEnvironment 'container-apps-environment.bicep' = {
1820
}
1921
}
2022

23+
module containerRegistry 'container-registry.bicep' = {
24+
name: '${name}-container-registry'
25+
scope: resourceGroup()
26+
params: {
27+
name: containerRegistryName
28+
location: location
29+
adminUserEnabled: containerRegistryAdminUserEnabled
30+
tags: tags
31+
}
32+
}
33+
2134
output defaultDomain string = containerAppsEnvironment.outputs.defaultDomain
2235
output environmentName string = containerAppsEnvironment.outputs.name
2336
output environmentId string = containerAppsEnvironment.outputs.id
2437

38+
output registryLoginServer string = containerRegistry.outputs.loginServer
39+
output registryName string = containerRegistry.outputs.name

0 commit comments

Comments
 (0)