Skip to content

Commit 1974bc7

Browse files
committed
azd up and deploy build docker image
1 parent a323d0e commit 1974bc7

12 files changed

+242
-40
lines changed

azure.yaml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

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
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
metadata description = 'Creates an Azure Container Registry.'
2+
param name string
3+
param location string = resourceGroup().location
4+
param tags object = {}
5+
6+
@description('Indicates whether admin user is enabled')
7+
param adminUserEnabled bool = false
8+
9+
@description('Indicates whether anonymous pull is enabled')
10+
param anonymousPullEnabled bool = false
11+
12+
@description('Azure ad authentication as arm policy settings')
13+
param azureADAuthenticationAsArmPolicy object = {
14+
status: 'enabled'
15+
}
16+
17+
@description('Indicates whether data endpoint is enabled')
18+
param dataEndpointEnabled bool = false
19+
20+
@description('Encryption settings')
21+
param encryption object = {
22+
status: 'disabled'
23+
}
24+
25+
@description('Export policy settings')
26+
param exportPolicy object = {
27+
status: 'enabled'
28+
}
29+
30+
@description('Metadata search settings')
31+
param metadataSearch string = 'Disabled'
32+
33+
@description('Options for bypassing network rules')
34+
param networkRuleBypassOptions string = 'AzureServices'
35+
36+
@description('Public network access setting')
37+
param publicNetworkAccess string = 'Enabled'
38+
39+
@description('Quarantine policy settings')
40+
param quarantinePolicy object = {
41+
status: 'disabled'
42+
}
43+
44+
@description('Retention policy settings')
45+
param retentionPolicy object = {
46+
days: 7
47+
status: 'disabled'
48+
}
49+
50+
@description('Scope maps setting')
51+
param scopeMaps array = []
52+
53+
@description('SKU settings')
54+
param sku object = {
55+
name: 'Basic'
56+
}
57+
58+
@description('Soft delete policy settings')
59+
param softDeletePolicy object = {
60+
retentionDays: 7
61+
status: 'disabled'
62+
}
63+
64+
@description('Trust policy settings')
65+
param trustPolicy object = {
66+
type: 'Notary'
67+
status: 'disabled'
68+
}
69+
70+
@description('Zone redundancy setting')
71+
param zoneRedundancy string = 'Disabled'
72+
73+
@description('The log analytics workspace ID used for logging and monitoring')
74+
param workspaceId string = ''
75+
76+
// 2023-11-01-preview needed for metadataSearch
77+
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-11-01-preview' = {
78+
name: name
79+
location: location
80+
tags: tags
81+
sku: sku
82+
properties: {
83+
adminUserEnabled: adminUserEnabled
84+
anonymousPullEnabled: anonymousPullEnabled
85+
dataEndpointEnabled: dataEndpointEnabled
86+
encryption: encryption
87+
metadataSearch: metadataSearch
88+
networkRuleBypassOptions: networkRuleBypassOptions
89+
policies:{
90+
quarantinePolicy: quarantinePolicy
91+
trustPolicy: trustPolicy
92+
retentionPolicy: retentionPolicy
93+
exportPolicy: exportPolicy
94+
azureADAuthenticationAsArmPolicy: azureADAuthenticationAsArmPolicy
95+
softDeletePolicy: softDeletePolicy
96+
}
97+
publicNetworkAccess: publicNetworkAccess
98+
zoneRedundancy: zoneRedundancy
99+
}
100+
101+
resource scopeMap 'scopeMaps' = [for scopeMap in scopeMaps: {
102+
name: scopeMap.name
103+
properties: scopeMap.properties
104+
}]
105+
}
106+
107+
// TODO: Update diagnostics to be its own module
108+
// Blocking issue: https://github.com/Azure/bicep/issues/622
109+
// Unable to pass in a `resource` scope or unable to use string interpolation in resource types
110+
resource diagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(workspaceId)) {
111+
name: 'registry-diagnostics'
112+
scope: containerRegistry
113+
properties: {
114+
workspaceId: workspaceId
115+
logs: [
116+
{
117+
category: 'ContainerRegistryRepositoryEvents'
118+
enabled: true
119+
}
120+
{
121+
category: 'ContainerRegistryLoginEvents'
122+
enabled: true
123+
}
124+
]
125+
metrics: [
126+
{
127+
category: 'AllMetrics'
128+
enabled: true
129+
timeGrain: 'PT1M'
130+
}
131+
]
132+
}
133+
}
134+
135+
output id string = containerRegistry.id
136+
output loginServer string = containerRegistry.properties.loginServer
137+
output name string = containerRegistry.name
Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
metadata description = 'Assigns ACR Pull permissions to access an Azure Container Registry.'
2-
param containerRegistryName string
3-
param principalId string
4-
5-
var acrPullRole = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
6-
7-
resource aksAcrPull 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
8-
scope: containerRegistry // Use when specifying a scope that is different than the deployment scope
9-
name: guid(subscription().id, resourceGroup().id, principalId, acrPullRole)
10-
properties: {
11-
roleDefinitionId: acrPullRole
12-
principalType: 'ServicePrincipal'
13-
principalId: principalId
14-
}
15-
}
16-
17-
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' existing = {
18-
name: containerRegistryName
19-
}
1+
metadata description = 'Assigns ACR Pull permissions to access an Azure Container Registry.'
2+
param containerRegistryName string
3+
param principalId string
4+
5+
var acrPullRole = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
6+
7+
resource aksAcrPull 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
8+
scope: containerRegistry // Use when specifying a scope that is different than the deployment scope
9+
name: guid(subscription().id, resourceGroup().id, principalId, acrPullRole)
10+
properties: {
11+
roleDefinitionId: acrPullRole
12+
principalType: 'ServicePrincipal'
13+
principalId: principalId
14+
}
15+
}
16+
17+
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' existing = {
18+
name: containerRegistryName
19+
}

0 commit comments

Comments
 (0)