Skip to content

Commit

Permalink
Merge from main
Browse files Browse the repository at this point in the history
  • Loading branch information
pamelafox committed Jun 16, 2024
2 parents 5bc8f06 + b1038b9 commit 2ec5bbe
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 95 deletions.
20 changes: 8 additions & 12 deletions infra/core/ai/cognitiveservices.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,24 @@ param publicNetworkAccess string = 'Enabled'
param sku object = {
name: 'S0'
}
@allowed([ 'None', 'AzureServices' ])
param bypass string = 'None'

var networkAcls = {
param allowedIpRules array = []
param networkAcls object = empty(allowedIpRules) ? {
defaultAction: 'Allow'
} : {
ipRules: allowedIpRules
defaultAction: 'Deny'
}

var networkAclsWithBypass = {
defaultAction: 'Allow'
bypass: bypass
}

resource account 'Microsoft.CognitiveServices/accounts@2023-10-01-preview' = {
resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' = {
name: name
location: location
tags: tags
kind: kind
properties: {
customSubDomainName: customSubDomainName
publicNetworkAccess: publicNetworkAccess
// Document Intelligence (FormRecognizer) does not support bypass in network acls
networkAcls: kind == 'FormRecognizer' ? networkAcls : networkAclsWithBypass
networkAcls: networkAcls
disableLocalAuth: disableLocalAuth
}
sku: sku
Expand All @@ -55,6 +51,6 @@ resource deployment 'Microsoft.CognitiveServices/accounts/deployments@2023-05-01
}]

output endpoint string = account.properties.endpoint
output endpoints object = account.properties.endpoints
output id string = account.id
output name string = account.name
output skuName string = account.sku.name
88 changes: 61 additions & 27 deletions infra/core/host/container-app-upsert.bicep
Original file line number Diff line number Diff line change
@@ -1,46 +1,77 @@
metadata description = 'Creates or updates an existing Azure Container App.'
param name string
param location string = resourceGroup().location
param tags object = {}

@description('The environment name for the container apps')
param containerAppsEnvironmentName string
param containerName string = 'main'
param containerRegistryName string

@description('Minimum number of replicas to run')
@minValue(1)
param containerMinReplicas int = 1
@description('Maximum number of replicas to run')
@description('The number of CPU cores allocated to a single container instance, e.g., 0.5')
param containerCpuCoreCount string = '0.5'

@description('The maximum number of replicas to run. Must be at least 1.')
@minValue(1)
param containerMaxReplicas int = 10

param secrets array = []
param env array = []
param external bool = true
param targetPort int = 80
param exists bool
@description('The amount of memory allocated to a single container instance, e.g., 1Gi')
param containerMemory string = '1.0Gi'

@description('User assigned identity name')
param identityName string
@description('The minimum number of replicas to run. Must be at least 1.')
@minValue(1)
param containerMinReplicas int = 1

@description('Enabled Ingress for container app')
param ingressEnabled bool = true
@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'

// Dapr Options
@description('Enable Dapr')
param daprEnabled bool = false
@description('Dapr app ID')
param daprAppId string = containerName
@allowed([ 'http', 'grpc' ])
@description('Protocol used by Dapr to connect to the app, e.g. http or grpc')
@description('The protocol used by Dapr to connect to the app, e.g., HTTP or gRPC')
param daprAppProtocol string = 'http'

@description('CPU cores allocated to a single container instance, e.g. 0.5')
param containerCpuCoreCount string = '0.5'
@description('Enable or disable Dapr for the container app')
param daprEnabled bool = false

@description('Memory allocated to a single container instance, e.g. 1Gi')
param containerMemory string = '1.0Gi'
@description('The Dapr app ID')
param daprAppId string = containerName

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

@description('Specifies if Ingress is enabled for the container app')
param ingressEnabled bool = true

@description('The type of identity for the resource')
@allowed([ 'None', 'SystemAssigned', 'UserAssigned' ])
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 = {}

@description('The environment variables for the container')
param env array = []

@description('Specifies if the resource ingress is exposed externally')
param external bool = true

@description('The service binds associated with the container')
param serviceBinds array = []

@description('The target port for the container')
param targetPort int = 80

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

Expand All @@ -50,11 +81,13 @@ module app 'container-app.bicep' = {
name: name
location: location
tags: tags
identityType: identityType
identityName: identityName
ingressEnabled: ingressEnabled
containerName: containerName
containerAppsEnvironmentName: containerAppsEnvironmentName
containerRegistryName: containerRegistryName
containerRegistryHostSuffix: containerRegistryHostSuffix
containerCpuCoreCount: containerCpuCoreCount
containerMemory: containerMemory
containerMinReplicas: containerMinReplicas
Expand All @@ -65,8 +98,9 @@ module app 'container-app.bicep' = {
secrets: secrets
external: external
env: env
imageName: exists ? existingApp.properties.template.containers[0].image : ''
imageName: !empty(imageName) ? imageName : exists ? existingApp.properties.template.containers[0].image : ''
targetPort: targetPort
serviceBinds: serviceBinds
}
}

Expand Down
134 changes: 90 additions & 44 deletions infra/core/host/container-app.bicep
Original file line number Diff line number Diff line change
@@ -1,94 +1,143 @@
metadata description = 'Creates a container app in an Azure Container App environment.'
param name string
param location string = resourceGroup().location
param tags object = {}

@description('Allowed origins')
param allowedOrigins array = []

@description('Name of the environment for container apps')
param containerAppsEnvironmentName string
param containerName string = 'main'
param containerRegistryName string

@description('Minimum number of replicas to run')
@minValue(1)
param containerMinReplicas int = 1
@description('Maximum number of replicas to run')
@description('CPU cores allocated to a single container instance, e.g., 0.5')
param containerCpuCoreCount string = '0.5'

@description('The maximum number of replicas to run. Must be at least 1.')
@minValue(1)
param containerMaxReplicas int = 10

param secrets array = []
@description('Memory allocated to a single container instance, e.g., 1Gi')
param containerMemory string = '1.0Gi'

@description('The minimum number of replicas to run. Must be at least 1.')
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'

@description('The Dapr app ID')
param daprAppId string = containerName

@description('Enable Dapr')
param daprEnabled bool = false

@description('The environment variables for the container')
param env array = []

@description('Specifies if the resource ingress is exposed externally')
param external bool = true
param imageName string
param targetPort int = 80

@description('User assigned identity name')
param identityName string
@description('The name of the user-assigned identity')
param identityName string = ''

@description('Enabled Ingress for container app')
@description('The type of identity for the resource')
@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

// Dapr Options
@description('Enable Dapr')
param daprEnabled bool = false
@description('Dapr app ID')
param daprAppId string = containerName
@allowed([ 'http', 'grpc' ])
@description('Protocol used by Dapr to connect to the app, e.g. http or grpc')
param daprAppProtocol string = 'http'
param revisionMode string = 'Single'

@description('CPU cores allocated to a single container instance, e.g. 0.5')
param containerCpuCoreCount string = '0.5'
@description('The secrets required for the container')
@secure()
param secrets object = {}

@description('Memory allocated to a single container instance, e.g. 1Gi')
param containerMemory string = '1.0Gi'
@description('The service binds associated with the container')
param serviceBinds array = []

@description('The name of the container apps add-on to use. e.g. redis')
param serviceType string = ''

resource userIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = {
@description('The target port for the container')
param targetPort int = 80

resource userIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (!empty(identityName)) {
name: identityName
}

module containerRegistryAccess '../security/registry-access.bicep' = {
// 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: userIdentity.properties.principalId
principalId: usePrivateRegistry ? userIdentity.properties.principalId : ''
}
}

resource app 'Microsoft.App/containerApps@2022-03-01' = {
resource app 'Microsoft.App/containerApps@2023-05-02-preview' = {
name: name
location: location
tags: tags
// It is critical that the identity is granted ACR pull access before the app is created
// otherwise the container app will throw a provision error
// This also forces us to use an user assigned managed identity since there would no way to
// This also forces us to use an user assigned managed identity since there would no way to
// provide the system assigned identity with the ACR pull access before the app is created
dependsOn: [ containerRegistryAccess ]
dependsOn: usePrivateRegistry ? [ containerRegistryAccess ] : []
identity: {
type: 'UserAssigned'
userAssignedIdentities: { '${userIdentity.id}': {} }
type: normalizedIdentityType
userAssignedIdentities: !empty(identityName) && normalizedIdentityType == 'UserAssigned' ? { '${userIdentity.id}': {} } : null
}
properties: {
managedEnvironmentId: containerAppsEnvironment.id
configuration: {
activeRevisionsMode: 'single'
activeRevisionsMode: revisionMode
ingress: ingressEnabled ? {
external: external
targetPort: targetPort
transport: 'auto'
corsPolicy: {
allowedOrigins: union([ 'https://portal.azure.com', 'https://ms.portal.azure.com' ], allowedOrigins)
}
} : null
dapr: daprEnabled ? {
enabled: true
appId: daprAppId
appProtocol: daprAppProtocol
appPort: ingressEnabled ? targetPort : 0
} : { enabled: false }
secrets: secrets
registries: [
secrets: [for secret in items(secrets): {
name: secret.key
value: secret.value
}]
service: !empty(serviceType) ? { type: serviceType } : null
registries: usePrivateRegistry ? [
{
server: '${containerRegistry.name}.azurecr.io'
server: '${containerRegistryName}.${containerRegistryHostSuffix}'
identity: userIdentity.id
}
]
] : []
}
template: {
serviceBinds: !empty(serviceBinds) ? serviceBinds : null
containers: [
{
image: !empty(imageName) ? imageName : 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
Expand All @@ -108,16 +157,13 @@ resource app 'Microsoft.App/containerApps@2022-03-01' = {
}
}

resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2022-03-01' existing = {
resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' existing = {
name: containerAppsEnvironmentName
}

// 2022-02-01-preview needed for anonymousPullEnabled
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2022-02-01-preview' existing = {
name: containerRegistryName
}

output defaultDomain string = containerAppsEnvironment.properties.defaultDomain
output identityPrincipalId string = normalizedIdentityType == 'None' ? '' : (empty(identityName) ? app.identity.principalId : userIdentity.properties.principalId)
output imageName string = imageName
output name string = app.name
output uri string = 'https://${app.properties.configuration.ingress.fqdn}'
output serviceBind object = !empty(serviceType) ? { serviceId: app.id, name: name } : {}
output uri string = ingressEnabled ? 'https://${app.properties.configuration.ingress.fqdn}' : ''
Loading

0 comments on commit 2ec5bbe

Please sign in to comment.