From 785f819f51ceb2d749bb51d7136f3505e8c0c6da Mon Sep 17 00:00:00 2001 From: "Menghua Chen (WICRESOFT NORTH AMERICA LTD)" Date: Mon, 2 Sep 2024 16:20:42 +0800 Subject: [PATCH] Add Infra/app files --- templates/todo/api/python/todo/models.py | 7 -- .../todo/common/infra/bicep/app/api-avm.bicep | 57 +++++++++++ .../todo/common/infra/bicep/app/web-avm.bicep | 35 +++++++ .../.repo/bicep/infra/main.bicep | 75 +++++---------- .../csharp-cosmos-sql/.repo/bicep/repo.yaml | 6 ++ .../.repo/bicep/infra/main.bicep | 47 +++------ .../csharp-sql-swa-func/.repo/bicep/repo.yaml | 3 + .../csharp-sql/.repo/bicep/infra/main.bicep | 67 ++++--------- .../projects/csharp-sql/.repo/bicep/repo.yaml | 6 ++ .../.repo/bicep/infra/main.bicep | 6 +- .../java-mongo/.repo/bicep/infra/main.bicep | 95 +++++++------------ .../projects/java-mongo/.repo/bicep/repo.yaml | 6 ++ .../.repo/bicep/infra/main.bicep | 6 +- .../.repo/bicep/infra/main.bicep | 6 +- .../.repo/bicep/infra/main.bicep | 52 ++++------ .../.repo/bicep/repo.yaml | 3 + .../nodejs-mongo/.repo/bicep/infra/main.bicep | 73 +++++--------- .../nodejs-mongo/.repo/bicep/repo.yaml | 6 ++ .../.repo/bicep/infra/main.bicep | 12 +-- .../.repo/bicep/infra/main.bicep | 55 ++++------- .../.repo/bicep/repo.yaml | 3 + .../python-mongo/.repo/bicep/infra/main.bicep | 78 +++++---------- .../python-mongo/.repo/bicep/repo.yaml | 6 ++ 23 files changed, 320 insertions(+), 390 deletions(-) create mode 100644 templates/todo/common/infra/bicep/app/api-avm.bicep create mode 100644 templates/todo/common/infra/bicep/app/web-avm.bicep diff --git a/templates/todo/api/python/todo/models.py b/templates/todo/api/python/todo/models.py index 4b76159de06..7710395dc9d 100644 --- a/templates/todo/api/python/todo/models.py +++ b/templates/todo/api/python/todo/models.py @@ -31,13 +31,6 @@ def __init__(self, *args, **kwargs): AZURE_KEY_VAULT_ENDPOINT: Optional[str] = None APPLICATIONINSIGHTS_CONNECTION_STRING: Optional[str] = None APPLICATIONINSIGHTS_ROLENAME: Optional[str] = "API" - PRIMARY_WRITE_KEY: str = "" - PRIMARY_READONLY_KEY: str = "" - SECONDARY_WRITE_CONNECTION_STRING: str = "" - PRIMARY_READONLY_CONNECTION_STRING: str = "" - SECONDARY_WRITE_KEY: str = "" - SECONDARY_READONLY_KEY: str = "" - SECONDARY_READONLY_CONNECTION_STRING: str = "" class Config: env_file = ".env" diff --git a/templates/todo/common/infra/bicep/app/api-avm.bicep b/templates/todo/common/infra/bicep/app/api-avm.bicep new file mode 100644 index 00000000000..a424ea6ac04 --- /dev/null +++ b/templates/todo/common/infra/bicep/app/api-avm.bicep @@ -0,0 +1,57 @@ +param name string +param location string = resourceGroup().location +param tags object = {} + +param allowedOrigins array = [] +param appCommandLine string = '' +param appInsightResourceId string +param appServicePlanId string +@secure() +param appSettings object = {} +param siteConfig object = {} +param serviceName string = 'api' +param linuxFxVersion string + +@description('Required. Type of site to deploy.') +param kind string + +@description('Optional. If client affinity is enabled.') +param clientAffinityEnabled bool = true + +@description('Optional. Required if app of kind functionapp. Resource ID of the storage account to manage triggers and logging function executions.') +param storageAccountResourceId string? + +module api 'br/public:avm/res/web/site:0.6.0' = { + name: '${name}-app-module' + params: { + kind: kind + name: name + serverFarmResourceId: appServicePlanId + tags: union(tags, { 'azd-service-name': serviceName }) + location: location + appInsightResourceId: appInsightResourceId + clientAffinityEnabled: clientAffinityEnabled + storageAccountResourceId: storageAccountResourceId + managedIdentities: { + systemAssigned: true + } + siteConfig: union(siteConfig, { + cors: { + allowedOrigins: union(['https://portal.azure.com', 'https://ms.portal.azure.com'], allowedOrigins) + } + linuxFxVersion: linuxFxVersion + appCommandLine: appCommandLine + }) + appSettingsKeyValuePairs: union(appSettings, { SCM_DO_BUILD_DURING_DEPLOYMENT: 'True', ENABLE_ORYX_BUILD: 'True' }) + logsConfiguration: { + applicationLogs: { fileSystem: { level: 'Verbose' } } + detailedErrorMessages: { enabled: true } + failedRequestsTracing: { enabled: true } + httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } + } + } +} + +output SERVICE_API_IDENTITY_PRINCIPAL_ID string = api.outputs.systemAssignedMIPrincipalId +output SERVICE_API_NAME string = api.outputs.name +output SERVICE_API_URI string = 'https://${api.outputs.defaultHostname}' diff --git a/templates/todo/common/infra/bicep/app/web-avm.bicep b/templates/todo/common/infra/bicep/app/web-avm.bicep new file mode 100644 index 00000000000..0dda981fe81 --- /dev/null +++ b/templates/todo/common/infra/bicep/app/web-avm.bicep @@ -0,0 +1,35 @@ +param name string +param location string = resourceGroup().location +param tags object = {} +param serviceName string = 'web' +param appCommandLine string = 'pm2 serve /home/site/wwwroot --no-daemon --spa' +param appInsightResourceId string +param appServicePlanId string +param linuxFxVersion string + +module web 'br/public:avm/res/web/site:0.6.0' = { + name: '${name}-deployment' + params: { + kind: 'app' + name: name + serverFarmResourceId: appServicePlanId + tags: union(tags, { 'azd-service-name': serviceName }) + location: location + appInsightResourceId: appInsightResourceId + siteConfig: { + appCommandLine: appCommandLine + linuxFxVersion: linuxFxVersion + alwaysOn: true + } + logsConfiguration: { + applicationLogs: { fileSystem: { level: 'Verbose' } } + detailedErrorMessages: { enabled: true } + failedRequestsTracing: { enabled: true } + httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } + } + } +} + +output SERVICE_WEB_IDENTITY_PRINCIPAL_ID string = web.outputs.systemAssignedMIPrincipalId +output SERVICE_WEB_NAME string = web.outputs.name +output SERVICE_WEB_URI string = 'https://${web.outputs.defaultHostname}' diff --git a/templates/todo/projects/csharp-cosmos-sql/.repo/bicep/infra/main.bicep b/templates/todo/projects/csharp-cosmos-sql/.repo/bicep/infra/main.bicep index 4d35fb68e82..6ec940c1afa 100644 --- a/templates/todo/projects/csharp-cosmos-sql/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/csharp-cosmos-sql/.repo/bicep/infra/main.bicep @@ -41,8 +41,6 @@ var abbrs = loadJsonContent('../../../../../../common/infra/bicep/abbreviations. var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) var tags = { 'azd-env-name': environmentName } var actualDatabaseName = !empty(cosmosDatabaseName) ? cosmosDatabaseName : 'Todo' -var webUri = 'https://${web.outputs.defaultHostname}' -var apiUri = 'https://${api.outputs.defaultHostname}' var apimApiUri = 'https://${apim.outputs.name}.azure-api.net/todo' var apimServiceId = useAPIM ? apim.outputs.resourceId : '' @@ -54,67 +52,42 @@ resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { } // The application frontend -module web 'br/public:avm/res/web/site:0.3.9' = { +module web '../../../../../common/infra/bicep/app/web-avm.bicep' = { name: 'web' scope: rg params: { - kind: 'app' name: !empty(webServiceName) ? webServiceName : '${abbrs.webSitesAppService}web-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'web' }) location: location + tags: tags + appServicePlanId: appServicePlan.outputs.resourceId appInsightResourceId: applicationInsights.outputs.resourceId - siteConfig: { - appCommandLine: 'pm2 serve /home/site/wwwroot --no-daemon --spa' - linuxFxVersion: 'node|20-lts' - alwaysOn: true - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } - } + linuxFxVersion: 'node|20-lts' } } // The application backend -module api 'br/public:avm/res/web/site:0.3.9' = { +module api '../../../../../common/infra/bicep/app/api-avm.bicep' = { name: 'api' scope: rg params: { - kind: 'app' name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesAppService}api-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'api' }) location: location - appInsightResourceId: applicationInsights.outputs.resourceId - managedIdentities: { - systemAssigned: true - } + tags: tags + kind: 'app' + appServicePlanId: appServicePlan.outputs.resourceId siteConfig: { - cors: { - allowedOrigins: [ 'https://portal.azure.com', 'https://ms.portal.azure.com' , webUri ] - } alwaysOn: true - linuxFxVersion: 'dotnetcore|8.0' - appCommandLine: '' } - appSettingsKeyValuePairs: { + appSettings: { AZURE_KEY_VAULT_ENDPOINT: keyVault.outputs.uri AZURE_COSMOS_CONNECTION_STRING_KEY: connectionStringKey AZURE_COSMOS_DATABASE_NAME: actualDatabaseName AZURE_COSMOS_ENDPOINT: cosmos.outputs.endpoint - API_ALLOW_ORIGINS: webUri - SCM_DO_BUILD_DURING_DEPLOYMENT: 'False' - ENABLE_ORYX_BUILD: 'True' - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } + API_ALLOW_ORIGINS: web.outputs.SERVICE_WEB_URI } + appInsightResourceId: applicationInsights.outputs.resourceId + linuxFxVersion: 'dotnetcore|8.0' + allowedOrigins: [ web.outputs.SERVICE_WEB_URI ] } } @@ -137,7 +110,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.5.1' = { } } { - objectId: api.outputs.systemAssignedMIPrincipalId + objectId: api.outputs.SERVICE_API_IDENTITY_PRINCIPAL_ID permissions: { secrets: [ 'get', 'list' ] } @@ -147,7 +120,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.5.1' = { } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.5.5' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -160,8 +133,8 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.5.5' = { isZoneRedundant: false } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration:{ + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey } capabilitiesToAdd: [ 'EnableServerless' ] @@ -197,7 +170,7 @@ module apiCosmosSqlRoleAssign 'br/public:avm/res/document-db/database-account:0. params: { name: cosmos.outputs.name location: location - sqlRoleAssignmentsPrincipalIds: [ api.outputs.systemAssignedMIPrincipalId ] + sqlRoleAssignmentsPrincipalIds: [ api.outputs.SERVICE_API_IDENTITY_PRINCIPAL_ID ] sqlRoleDefinitions: [ { name: 'writer' @@ -340,14 +313,14 @@ module apim 'br/public:avm/res/api-management/service:0.2.0' = if (useAPIM) { path: 'todo' displayName: 'Simple Todo API' apiDescription: 'This is a simple Todo API' - serviceUrl: apiUri + serviceUrl: api.outputs.SERVICE_API_URI subscriptionRequired: false protocols: [ 'https' ] type: 'http' value: loadTextContent('../../../../../api/common/openapi.yaml') policies: [ { - value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', webUri) + value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', web.outputs.SERVICE_WEB_URI) format: 'rawxml' } ] @@ -362,7 +335,7 @@ module apiConfig 'br/public:avm/res/web/site:0.3.9' = if (useAPIM) { scope: rg params: { kind: 'app' - name: api.outputs.name + name: api.outputs.SERVICE_API_NAME tags: union(tags, { 'azd-service-name': 'api' }) serverFarmResourceId: appServicePlan.outputs.resourceId location: location @@ -385,7 +358,7 @@ output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.uri output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId -output API_BASE_URL string = useAPIM ? apimApiUri : apiUri -output REACT_APP_WEB_BASE_URL string = webUri +output API_BASE_URL string = useAPIM ? apimApiUri : api.outputs.SERVICE_API_URI +output REACT_APP_WEB_BASE_URL string = web.outputs.SERVICE_WEB_URI output USE_APIM bool = useAPIM -output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, apiUri ]: [] +output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, api.outputs.SERVICE_API_URI ]: [] diff --git a/templates/todo/projects/csharp-cosmos-sql/.repo/bicep/repo.yaml b/templates/todo/projects/csharp-cosmos-sql/.repo/bicep/repo.yaml index 017054e98fe..fbb4362c378 100644 --- a/templates/todo/projects/csharp-cosmos-sql/.repo/bicep/repo.yaml +++ b/templates/todo/projects/csharp-cosmos-sql/.repo/bicep/repo.yaml @@ -118,6 +118,12 @@ repo: - from: ../../../../common/infra/bicep/app/applicationinsights-dashboard.bicep to: ./infra/app/applicationinsights-dashboard.bicep + - from: ../../../../common/infra/bicep/app/web-avm.bicep + to: ./infra/app/web-avm.bicep + + - from: ../../../../common/infra/bicep/app/api-avm.bicep + to: ./infra/app/api-avm.bicep + - from: ./../../ to: ./ ignore: diff --git a/templates/todo/projects/csharp-sql-swa-func/.repo/bicep/infra/main.bicep b/templates/todo/projects/csharp-sql-swa-func/.repo/bicep/infra/main.bicep index 6ae430e72c8..0aa8daefdc8 100644 --- a/templates/todo/projects/csharp-sql-swa-func/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/csharp-sql-swa-func/.repo/bicep/infra/main.bicep @@ -54,7 +54,6 @@ var tags = { 'azd-env-name': environmentName } var defaultDatabaseName = 'Todo' var actualDatabaseName = !empty(sqlDatabaseName) ? sqlDatabaseName : defaultDatabaseName var webUri = 'https://${web.outputs.defaultHostname}' -var apiUri = 'https://${api.outputs.defaultHostname}' var apimApiUri = 'https://${apim.outputs.name}.azure-api.net/todo' var apimServiceId = useAPIM ? apim.outputs.resourceId : '' @@ -78,43 +77,27 @@ module web 'br/public:avm/res/web/static-site:0.3.0' = { } // The application backend -module api 'br/public:avm/res/web/site:0.3.9' = { +module api '../../../../../common/infra/bicep/app/api-avm.bicep' = { name: 'api' scope: rg params: { - kind: 'functionapp' - name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesFunctions}api-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'api' }) + name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesAppService}api-${resourceToken}' location: location - appInsightResourceId: applicationInsights.outputs.resourceId - managedIdentities: { - systemAssigned: true - } - clientAffinityEnabled: false - siteConfig: { - cors: { - allowedOrigins: [ 'https://portal.azure.com', 'https://ms.portal.azure.com' , webUri ] - } - linuxFxVersion: 'dotnet-isolated|8.0' - use32BitWorkerProcess: false - } - appSettingsKeyValuePairs: { + tags: tags + kind: 'functionapp' + appServicePlanId: appServicePlan.outputs.resourceId + appSettings: { AZURE_KEY_VAULT_ENDPOINT: keyVault.outputs.uri AZURE_SQL_CONNECTION_STRING_KEY: connectionStringKey API_ALLOW_ORIGINS: webUri FUNCTIONS_EXTENSION_VERSION: '~4' FUNCTIONS_WORKER_RUNTIME: 'dotnet-isolated' - SCM_DO_BUILD_DURING_DEPLOYMENT: 'False' - ENABLE_ORYX_BUILD: 'True' - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } } + appInsightResourceId: applicationInsights.outputs.resourceId + linuxFxVersion: 'dotnet-isolated|8.0' + allowedOrigins: [ webUri ] storageAccountResourceId: storage.outputs.resourceId + clientAffinityEnabled: false } } @@ -137,7 +120,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.5.1' = { } } { - objectId: api.outputs.systemAssignedMIPrincipalId + objectId: api.outputs.SERVICE_API_IDENTITY_PRINCIPAL_ID permissions: { secrets: [ 'get', 'list' ] } @@ -353,7 +336,7 @@ module apim 'br/public:avm/res/api-management/service:0.2.0' = if (useAPIM) { path: 'todo' displayName: 'Simple Todo API' apiDescription: 'This is a simple Todo API' - serviceUrl: apiUri + serviceUrl: api.outputs.SERVICE_API_URI subscriptionRequired: false protocols: [ 'https' ] type: 'http' @@ -375,7 +358,7 @@ module apiConfig 'br/public:avm/res/web/site:0.3.9' = if (useAPIM) { scope: rg params: { kind: 'functionapp' - name: api.outputs.name + name: api.outputs.SERVICE_API_NAME tags: union(tags, { 'azd-service-name': 'api' }) siteConfig: { cors: { @@ -403,7 +386,7 @@ output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.uri output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId -output API_BASE_URL string = useAPIM ? apimApiUri : apiUri +output API_BASE_URL string = useAPIM ? apimApiUri : api.outputs.SERVICE_API_URI output REACT_APP_WEB_BASE_URL string = webUri output USE_APIM bool = useAPIM -output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, apiUri ]: [] +output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, api.outputs.SERVICE_API_URI ]: [] diff --git a/templates/todo/projects/csharp-sql-swa-func/.repo/bicep/repo.yaml b/templates/todo/projects/csharp-sql-swa-func/.repo/bicep/repo.yaml index 06a724c23f9..4a9d6c3744f 100644 --- a/templates/todo/projects/csharp-sql-swa-func/.repo/bicep/repo.yaml +++ b/templates/todo/projects/csharp-sql-swa-func/.repo/bicep/repo.yaml @@ -121,6 +121,9 @@ repo: - from: ../../../../common/infra/bicep/app/sql-deployment-script.bicep to: ./infra/app/sql-deployment-script.bicep + - from: ../../../../common/infra/bicep/app/api-avm.bicep + to: ./infra/app/api-avm.bicep + - from: ./../../ to: ./ ignore: diff --git a/templates/todo/projects/csharp-sql/.repo/bicep/infra/main.bicep b/templates/todo/projects/csharp-sql/.repo/bicep/infra/main.bicep index cb53a514502..c7c119eaf8e 100644 --- a/templates/todo/projects/csharp-sql/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/csharp-sql/.repo/bicep/infra/main.bicep @@ -51,8 +51,6 @@ var resourceToken = toLower(uniqueString(subscription().id, environmentName, loc var tags = { 'azd-env-name': environmentName } var defaultDatabaseName = 'Todo' var actualDatabaseName = !empty(sqlDatabaseName) ? sqlDatabaseName : defaultDatabaseName -var webUri = 'https://${web.outputs.defaultHostname}' -var apiUri = 'https://${api.outputs.defaultHostname}' var apimApiUri = 'https://${apim.outputs.name}.azure-api.net/todo' var apimServiceId = useAPIM ? apim.outputs.resourceId : '' @@ -64,64 +62,39 @@ resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { } // The application frontend -module web 'br/public:avm/res/web/site:0.3.9' = { +module web '../../../../../common/infra/bicep/app/web-avm.bicep' = { name: 'web' scope: rg params: { - kind: 'app' name: !empty(webServiceName) ? webServiceName : '${abbrs.webSitesAppService}web-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'web' }) location: location + tags: tags + appServicePlanId: appServicePlan.outputs.resourceId appInsightResourceId: applicationInsights.outputs.resourceId - siteConfig: { - appCommandLine: 'pm2 serve /home/site/wwwroot --no-daemon --spa' - linuxFxVersion: 'node|20-lts' - alwaysOn: true - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } - } + linuxFxVersion: 'node|20-lts' } } // The application backend -module api 'br/public:avm/res/web/site:0.3.9' = { +module api '../../../../../common/infra/bicep/app/api-avm.bicep' = { name: 'api' scope: rg params: { - kind: 'app' name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesAppService}api-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'api' }) location: location - appInsightResourceId: applicationInsights.outputs.resourceId - managedIdentities: { - systemAssigned: true - } + tags: tags + kind: 'app' + appServicePlanId: appServicePlan.outputs.resourceId siteConfig: { - cors: { - allowedOrigins: [ 'https://portal.azure.com', 'https://ms.portal.azure.com' , webUri ] - } - linuxFxVersion: 'dotnetcore|8.0' alwaysOn: true - appCommandLine: '' } - appSettingsKeyValuePairs: { - AZURE_SQL_CONNECTION_STRING_KEY: connectionStringKey + appSettings: { AZURE_KEY_VAULT_ENDPOINT: keyVault.outputs.uri - SCM_DO_BUILD_DURING_DEPLOYMENT: 'False' - ENABLE_ORYX_BUILD: 'True' - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } + AZURE_COSMOS_CONNECTION_STRING_KEY: connectionStringKey } + appInsightResourceId: applicationInsights.outputs.resourceId + linuxFxVersion: 'dotnetcore|8.0' + allowedOrigins: [ web.outputs.SERVICE_WEB_URI ] } } @@ -144,7 +117,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.3.5' = { } } { - objectId: api.outputs.systemAssignedMIPrincipalId + objectId: api.outputs.SERVICE_API_IDENTITY_PRINCIPAL_ID permissions: { secrets: [ 'get', 'list' ] } @@ -342,14 +315,14 @@ module apim 'br/public:avm/res/api-management/service:0.2.0' = if (useAPIM) { path: 'todo' displayName: 'Simple Todo API' apiDescription: 'This is a simple Todo API' - serviceUrl: apiUri + serviceUrl: api.outputs.SERVICE_API_URI subscriptionRequired: false protocols: [ 'https' ] type: 'http' value: loadTextContent('../../../../../api/common/openapi.yaml') policies: [ { - value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', webUri) + value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', web.outputs.SERVICE_WEB_URI) format: 'rawxml' } ] @@ -364,7 +337,7 @@ module apiConfig 'br/public:avm/res/web/site:0.3.9' = if (useAPIM) { scope: rg params: { kind: 'app' - name: api.outputs.name + name: api.outputs.SERVICE_API_NAME tags: union(tags, { 'azd-service-name': 'api' }) serverFarmResourceId: appServicePlan.outputs.resourceId location: location @@ -385,7 +358,7 @@ output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.uri output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId -output API_BASE_URL string = useAPIM ? apimApiUri : apiUri -output REACT_APP_WEB_BASE_URL string = webUri +output API_BASE_URL string = useAPIM ? apimApiUri : api.outputs.SERVICE_API_URI +output REACT_APP_WEB_BASE_URL string = web.outputs.SERVICE_WEB_URI output USE_APIM bool = useAPIM -output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, apiUri ]: [] +output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, api.outputs.SERVICE_API_URI ]: [] diff --git a/templates/todo/projects/csharp-sql/.repo/bicep/repo.yaml b/templates/todo/projects/csharp-sql/.repo/bicep/repo.yaml index 8fb4748118c..3764550917d 100644 --- a/templates/todo/projects/csharp-sql/.repo/bicep/repo.yaml +++ b/templates/todo/projects/csharp-sql/.repo/bicep/repo.yaml @@ -122,6 +122,12 @@ repo: - from: ../../../../common/infra/bicep/app/sql-deployment-script.bicep to: ./infra/app/sql-deployment-script.bicep + - from: ../../../../common/infra/bicep/app/web-avm.bicep + to: ./infra/app/web-avm.bicep + + - from: ../../../../common/infra/bicep/app/api-avm.bicep + to: ./infra/app/api-avm.bicep + - from: ./../../ to: ./ ignore: diff --git a/templates/todo/projects/java-mongo-aca/.repo/bicep/infra/main.bicep b/templates/todo/projects/java-mongo-aca/.repo/bicep/infra/main.bicep index 02b9731a64d..f97b0f3782a 100644 --- a/templates/todo/projects/java-mongo-aca/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/java-mongo-aca/.repo/bicep/infra/main.bicep @@ -242,7 +242,7 @@ module api 'br/public:avm/res/app/container-app:0.2.0' = { } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -262,8 +262,8 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { collections: collections } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration: { + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey } } diff --git a/templates/todo/projects/java-mongo/.repo/bicep/infra/main.bicep b/templates/todo/projects/java-mongo/.repo/bicep/infra/main.bicep index 6ba8238230f..bb8c3351428 100644 --- a/templates/todo/projects/java-mongo/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/java-mongo/.repo/bicep/infra/main.bicep @@ -31,9 +31,11 @@ param collections array = [ { name: 'TodoList' id: 'TodoList' - shardKey: {keys: [ - 'Hash' - ]} + shardKey: { + keys: [ + 'Hash' + ] + } indexes: [ { key: { @@ -47,9 +49,11 @@ param collections array = [ { name: 'TodoItem' id: 'TodoItem' - shardKey: {keys: [ - 'Hash' - ]} + shardKey: { + keys: [ + 'Hash' + ] + } indexes: [ { key: { @@ -76,8 +80,6 @@ var resourceToken = toLower(uniqueString(subscription().id, environmentName, loc var tags = { 'azd-env-name': environmentName } var defaultDatabaseName = 'Todo' var actualDatabaseName = !empty(cosmosDatabaseName) ? cosmosDatabaseName : defaultDatabaseName -var webUri = 'https://${web.outputs.defaultHostname}' -var apiUri = 'https://${api.outputs.defaultHostname}' var apimApiUri = 'https://${apim.outputs.name}.azure-api.net/todo' var apimServiceId = useAPIM ? apim.outputs.resourceId : '' @@ -89,72 +91,43 @@ resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { } // The application frontend -module web 'br/public:avm/res/web/site:0.3.9' = { +module web '../../../../../common/infra/bicep/app/web-avm.bicep' = { name: 'web' scope: rg params: { - kind: 'app' name: !empty(webServiceName) ? webServiceName : '${abbrs.webSitesAppService}web-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'web' }) location: location + tags: tags + appServicePlanId: appServicePlan.outputs.resourceId appInsightResourceId: applicationInsights.outputs.resourceId - siteConfig: { - appCommandLine: 'pm2 serve /home/site/wwwroot --no-daemon --spa' - linuxFxVersion: 'node|20-lts' - alwaysOn: true - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } - } + linuxFxVersion: 'node|20-lts' } } // The application backend -module api 'br/public:avm/res/web/site:0.3.9' = { +module api '../../../../../common/infra/bicep/app/api-avm.bicep' = { name: 'api' scope: rg params: { - kind: 'app' name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesAppService}api-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'api' }) location: location - appInsightResourceId: applicationInsights.outputs.resourceId - managedIdentities: { - systemAssigned: true - } + tags: tags + kind: 'app' + appServicePlanId: appServicePlan.outputs.resourceId siteConfig: { - cors: { - allowedOrigins: [ 'https://portal.azure.com', 'https://ms.portal.azure.com' , webUri ] - } - linuxFxVersion: 'java|17-java17' alwaysOn: true - appCommandLine: '' } - appSettingsKeyValuePairs: { + appSettings: { AZURE_KEY_VAULT_ENDPOINT: keyVault.outputs.uri AZURE_COSMOS_CONNECTION_STRING_KEY: connectionStringKey AZURE_COSMOS_DATABASE_NAME: actualDatabaseName AZURE_COSMOS_ENDPOINT: 'https://${cosmos.outputs.name}.mongo.cosmos.azure.com:443/' - API_ALLOW_ORIGINS: webUri - SCM_DO_BUILD_DURING_DEPLOYMENT: 'True' - ENABLE_ORYX_BUILD: 'True' - JAVA_OPTS: join( - concat( - [], - ['-Djdk.attach.allowAttachSelf=true']), - ' ') - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } + API_ALLOW_ORIGINS: web.outputs.SERVICE_WEB_URI + JAVA_OPTS: join(concat([], [ '-Djdk.attach.allowAttachSelf=true' ]), ' ') } + appInsightResourceId: applicationInsights.outputs.resourceId + linuxFxVersion: 'java|17-java17' + allowedOrigins: [ web.outputs.SERVICE_WEB_URI ] } } @@ -177,7 +150,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.3.5' = { } } { - objectId: api.outputs.systemAssignedMIPrincipalId + objectId: api.outputs.SERVICE_API_IDENTITY_PRINCIPAL_ID permissions: { secrets: [ 'get', 'list' ] } @@ -187,7 +160,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.3.5' = { } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -207,8 +180,8 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { collections: collections } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration: { + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey } } @@ -348,14 +321,14 @@ module apim 'br/public:avm/res/api-management/service:0.2.0' = if (useAPIM) { path: 'todo' displayName: 'Simple Todo API' apiDescription: 'This is a simple Todo API' - serviceUrl: apiUri + serviceUrl: api.outputs.SERVICE_API_URI subscriptionRequired: false protocols: [ 'https' ] type: 'http' value: loadTextContent('../../../../../api/common/openapi.yaml') policies: [ { - value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', webUri) + value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', web.outputs.SERVICE_WEB_URI) format: 'rawxml' } ] @@ -370,7 +343,7 @@ module apiConfig 'br/public:avm/res/web/site:0.3.9' = if (useAPIM) { scope: rg params: { kind: 'app' - name: api.outputs.name + name: api.outputs.SERVICE_API_NAME tags: union(tags, { 'azd-service-name': 'api' }) serverFarmResourceId: appServicePlan.outputs.resourceId location: location @@ -392,7 +365,7 @@ output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.uri output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId -output API_BASE_URL string = useAPIM ? apimApiUri : apiUri -output REACT_APP_WEB_BASE_URL string = webUri +output API_BASE_URL string = useAPIM ? apimApiUri : api.outputs.SERVICE_API_URI +output REACT_APP_WEB_BASE_URL string = web.outputs.SERVICE_WEB_URI output USE_APIM bool = useAPIM -output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, apiUri ]: [] +output SERVICE_API_ENDPOINTS array = useAPIM ? [apimApiUri, api.outputs.SERVICE_API_URI] : [] diff --git a/templates/todo/projects/java-mongo/.repo/bicep/repo.yaml b/templates/todo/projects/java-mongo/.repo/bicep/repo.yaml index 444e80425b0..685e6a48a71 100644 --- a/templates/todo/projects/java-mongo/.repo/bicep/repo.yaml +++ b/templates/todo/projects/java-mongo/.repo/bicep/repo.yaml @@ -115,6 +115,12 @@ repo: - from: ../../../../common/infra/bicep/app/applicationinsights-dashboard.bicep to: ./infra/app/applicationinsights-dashboard.bicep + - from: ../../../../common/infra/bicep/app/web-avm.bicep + to: ./infra/app/web-avm.bicep + + - from: ../../../../common/infra/bicep/app/api-avm.bicep + to: ./infra/app/api-avm.bicep + - from: ./../../ to: ./ ignore: diff --git a/templates/todo/projects/nodejs-mongo-aca/.repo/bicep/infra/main.bicep b/templates/todo/projects/nodejs-mongo-aca/.repo/bicep/infra/main.bicep index 02b9731a64d..e35f4eb239d 100644 --- a/templates/todo/projects/nodejs-mongo-aca/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/nodejs-mongo-aca/.repo/bicep/infra/main.bicep @@ -242,7 +242,7 @@ module api 'br/public:avm/res/app/container-app:0.2.0' = { } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -262,8 +262,8 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { collections: collections } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration:{ + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey } } diff --git a/templates/todo/projects/nodejs-mongo-aks/.repo/bicep/infra/main.bicep b/templates/todo/projects/nodejs-mongo-aks/.repo/bicep/infra/main.bicep index ff05dfc38b4..8ab77f7291d 100644 --- a/templates/todo/projects/nodejs-mongo-aks/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/nodejs-mongo-aks/.repo/bicep/infra/main.bicep @@ -246,7 +246,7 @@ module containerRegistry 'br/public:avm/res/container-registry/registry:0.1.1' = } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.5.1' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -266,8 +266,8 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.5.1' = { collections: collections } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration:{ + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey } } diff --git a/templates/todo/projects/nodejs-mongo-swa-func/.repo/bicep/infra/main.bicep b/templates/todo/projects/nodejs-mongo-swa-func/.repo/bicep/infra/main.bicep index fa6abdcf127..777eaa7d112 100644 --- a/templates/todo/projects/nodejs-mongo-swa-func/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/nodejs-mongo-swa-func/.repo/bicep/infra/main.bicep @@ -77,7 +77,6 @@ var resourceToken = toLower(uniqueString(subscription().id, environmentName, loc var tags = { 'azd-env-name': environmentName } var defaultDatabaseName = 'Todo' var actualDatabaseName = !empty(cosmosDatabaseName) ? cosmosDatabaseName : defaultDatabaseName -var apiUri = 'https://${api.outputs.defaultHostname}' var webUri = 'https://${web.outputs.defaultHostname}' var apimApiUri = 'https://${apim.outputs.name}.azure-api.net/todo' var apimServiceId = useAPIM ? apim.outputs.resourceId : '' @@ -102,28 +101,19 @@ module web 'br/public:avm/res/web/static-site:0.3.0' = { } // The application backend -module api 'br/public:avm/res/web/site:0.3.9' = { +module api '../../../../../common/infra/bicep/app/api-avm.bicep' = { name: 'api' scope: rg params: { - kind: 'functionapp' - name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesFunctions}api-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'api' }) + name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesAppService}api-${resourceToken}' location: location - appInsightResourceId: applicationInsights.outputs.resourceId - managedIdentities: { - systemAssigned: true - } - clientAffinityEnabled: false + tags: tags + kind: 'app' + appServicePlanId: appServicePlan.outputs.resourceId siteConfig: { - cors: { - allowedOrigins: [ 'https://portal.azure.com', 'https://ms.portal.azure.com' , webUri ] - } - linuxFxVersion: 'node|20' - use32BitWorkerProcess: false + alwaysOn: true } - appSettingsKeyValuePairs: { + appSettings: { API_ALLOW_ORIGINS: webUri AZURE_COSMOS_CONNECTION_STRING_KEY: connectionStringKey AZURE_COSMOS_DATABASE_NAME: actualDatabaseName @@ -131,16 +121,12 @@ module api 'br/public:avm/res/web/site:0.3.9' = { AZURE_COSMOS_ENDPOINT: 'https://${cosmos.outputs.name}.documents.azure.com:443/' FUNCTIONS_EXTENSION_VERSION: '~4' FUNCTIONS_WORKER_RUNTIME: 'node' - SCM_DO_BUILD_DURING_DEPLOYMENT: 'True' - ENABLE_ORYX_BUILD: 'True' - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } } + appInsightResourceId: applicationInsights.outputs.resourceId + linuxFxVersion: 'node|20' + allowedOrigins: [ webUri ] storageAccountResourceId: storage.outputs.resourceId + clientAffinityEnabled: false } } @@ -157,7 +143,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.5.1' = { sku: 'standard' accessPolicies: [ { - objectId: api.outputs.systemAssignedMIPrincipalId + objectId: api.outputs.SERVICE_API_IDENTITY_PRINCIPAL_ID permissions: { secrets: [ 'get', 'list' ] } @@ -173,7 +159,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.5.1' = { } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -193,8 +179,8 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { collections: collections } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration:{ + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey } } @@ -352,7 +338,7 @@ module apim 'br/public:avm/res/api-management/service:0.2.0' = if (useAPIM) { path: 'todo' displayName: 'Simple Todo API' apiDescription: 'This is a simple Todo API' - serviceUrl: apiUri + serviceUrl: api.outputs.SERVICE_API_URI subscriptionRequired: false protocols: [ 'https' ] type: 'http' @@ -374,7 +360,7 @@ module apiConfig 'br/public:avm/res/web/site:0.3.9' = if (useAPIM) { scope: rg params: { kind: 'functionapp' - name: api.outputs.name + name: api.outputs.SERVICE_API_NAME tags: union(tags, { 'azd-service-name': 'api' }) siteConfig: { cors: { @@ -403,7 +389,7 @@ output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.uri output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId -output API_BASE_URL string = useAPIM ? apimApiUri : apiUri +output API_BASE_URL string = useAPIM ? apimApiUri : api.outputs.SERVICE_API_URI output REACT_APP_WEB_BASE_URL string = webUri output USE_APIM bool = useAPIM -output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, apiUri ]: [] +output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, api.outputs.SERVICE_API_URI ]: [] diff --git a/templates/todo/projects/nodejs-mongo-swa-func/.repo/bicep/repo.yaml b/templates/todo/projects/nodejs-mongo-swa-func/.repo/bicep/repo.yaml index 3140b4ef005..ebb7b329470 100644 --- a/templates/todo/projects/nodejs-mongo-swa-func/.repo/bicep/repo.yaml +++ b/templates/todo/projects/nodejs-mongo-swa-func/.repo/bicep/repo.yaml @@ -118,6 +118,9 @@ repo: - from: ../../../../common/infra/bicep/app/applicationinsights-dashboard.bicep to: ./infra/app/applicationinsights-dashboard.bicep + - from: ../../../../common/infra/bicep/app/api-avm.bicep + to: ./infra/app/api-avm.bicep + - from: ./../../ to: ./ ignore: diff --git a/templates/todo/projects/nodejs-mongo/.repo/bicep/infra/main.bicep b/templates/todo/projects/nodejs-mongo/.repo/bicep/infra/main.bicep index 1a53bb3a867..51d354c38c2 100644 --- a/templates/todo/projects/nodejs-mongo/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/nodejs-mongo/.repo/bicep/infra/main.bicep @@ -76,8 +76,6 @@ var resourceToken = toLower(uniqueString(subscription().id, environmentName, loc var tags = { 'azd-env-name': environmentName } var defaultDatabaseName = 'Todo' var actualDatabaseName = !empty(cosmosDatabaseName) ? cosmosDatabaseName : defaultDatabaseName -var apiUri = 'https://${api.outputs.defaultHostname}' -var webUri = 'https://${web.outputs.defaultHostname}' var apimApiUri = 'https://${apim.outputs.name}.azure-api.net/todo' var apimServiceId = useAPIM ? apim.outputs.resourceId : '' @@ -89,67 +87,42 @@ resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { } // The application frontend -module web 'br/public:avm/res/web/site:0.3.9' = { +module web '../../../../../common/infra/bicep/app/web-avm.bicep' = { name: 'web' scope: rg params: { - kind: 'app' name: !empty(webServiceName) ? webServiceName : '${abbrs.webSitesAppService}web-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'web' }) location: location + tags: tags + appServicePlanId: appServicePlan.outputs.resourceId appInsightResourceId: applicationInsights.outputs.resourceId - siteConfig: { - linuxFxVersion: 'node|20-lts' - appCommandLine: 'pm2 serve /home/site/wwwroot --no-daemon --spa' - alwaysOn: true - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } - } + linuxFxVersion: 'node|20-lts' } } // The application backend -module api 'br/public:avm/res/web/site:0.3.9' = { +module api '../../../../../common/infra/bicep/app/api-avm.bicep' = { name: 'api' scope: rg params: { - kind: 'app' name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesAppService}api-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'api' }) location: location - appInsightResourceId: applicationInsights.outputs.resourceId - managedIdentities: { - systemAssigned: true - } + tags: tags + kind: 'app' + appServicePlanId: appServicePlan.outputs.resourceId siteConfig: { - cors: { - allowedOrigins: [ 'https://portal.azure.com', 'https://ms.portal.azure.com' , webUri ] - } alwaysOn: true - linuxFxVersion: 'node|20-lts' - appCommandLine: '' } - appSettingsKeyValuePairs: { + appSettings: { AZURE_KEY_VAULT_ENDPOINT: keyVault.outputs.uri AZURE_COSMOS_CONNECTION_STRING_KEY: connectionStringKey AZURE_COSMOS_DATABASE_NAME: actualDatabaseName AZURE_COSMOS_ENDPOINT: 'https://${cosmos.outputs.name}.documents.azure.com:443/' - API_ALLOW_ORIGINS: webUri - SCM_DO_BUILD_DURING_DEPLOYMENT: 'True' - ENABLE_ORYX_BUILD: 'True' - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } + API_ALLOW_ORIGINS: web.outputs.SERVICE_WEB_URI } + appInsightResourceId: applicationInsights.outputs.resourceId + linuxFxVersion: 'node|20-lts' + allowedOrigins: [ web.outputs.SERVICE_WEB_URI ] } } @@ -172,7 +145,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.3.5' = { } } { - objectId: api.outputs.systemAssignedMIPrincipalId + objectId: api.outputs.SERVICE_API_IDENTITY_PRINCIPAL_ID permissions: { secrets: [ 'get', 'list' ] } @@ -182,7 +155,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.3.5' = { } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.5.4' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -202,8 +175,8 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.5.4' = { collections: collections } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration:{ + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey } } @@ -343,14 +316,14 @@ module apim 'br/public:avm/res/api-management/service:0.2.0' = if (useAPIM) { path: 'todo' displayName: 'Simple Todo API' apiDescription: 'This is a simple Todo API' - serviceUrl: apiUri + serviceUrl: api.outputs.SERVICE_API_URI subscriptionRequired: false protocols: [ 'https' ] type: 'http' value: loadTextContent('../../../../../api/common/openapi.yaml') policies: [ { - value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', webUri) + value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', web.outputs.SERVICE_WEB_URI) format: 'rawxml' } ] @@ -365,7 +338,7 @@ module apiConfig 'br/public:avm/res/web/site:0.3.9' = if (useAPIM) { scope: rg params: { kind: 'app' - name: api.outputs.name + name: api.outputs.SERVICE_API_NAME tags: union(tags, { 'azd-service-name': 'api' }) serverFarmResourceId: appServicePlan.outputs.resourceId location: location @@ -387,7 +360,7 @@ output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.uri output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId -output API_BASE_URL string = useAPIM ? apimApiUri : apiUri -output REACT_APP_WEB_BASE_URL string = webUri +output API_BASE_URL string = useAPIM ? apimApiUri : api.outputs.SERVICE_API_URI +output REACT_APP_WEB_BASE_URL string = web.outputs.SERVICE_WEB_URI output USE_APIM bool = useAPIM -output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, apiUri ]: [] +output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, api.outputs.SERVICE_API_URI ]: [] diff --git a/templates/todo/projects/nodejs-mongo/.repo/bicep/repo.yaml b/templates/todo/projects/nodejs-mongo/.repo/bicep/repo.yaml index 474664a4d17..2addfa5f8b6 100644 --- a/templates/todo/projects/nodejs-mongo/.repo/bicep/repo.yaml +++ b/templates/todo/projects/nodejs-mongo/.repo/bicep/repo.yaml @@ -115,6 +115,12 @@ repo: - from: ../../../../common/infra/bicep/app/applicationinsights-dashboard.bicep to: ./infra/app/applicationinsights-dashboard.bicep + - from: ../../../../common/infra/bicep/app/web-avm.bicep + to: ./infra/app/web-avm.bicep + + - from: ../../../../common/infra/bicep/app/api-avm.bicep + to: ./infra/app/api-avm.bicep + - from: ./../../ to: ./ ignore: diff --git a/templates/todo/projects/python-mongo-aca/.repo/bicep/infra/main.bicep b/templates/todo/projects/python-mongo-aca/.repo/bicep/infra/main.bicep index 39140062566..e35f4eb239d 100644 --- a/templates/todo/projects/python-mongo-aca/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/python-mongo-aca/.repo/bicep/infra/main.bicep @@ -26,9 +26,6 @@ param resourceGroupName string = '' param webContainerAppName string = '' param apimServiceName string = '' param connectionStringKey string = 'AZURE-COSMOS-CONNECTION-STRING' -param primaryReadonlyConnectionStringSecretName string= 'PRIMARY-READONLY-CONNECTION-STRING' -param secondaryWriteConnectionStringSecretName string = 'SECONDARY-WRITE-CONNECTION-STRING' -param secondaryReadonlyConnectionStringSecretName string = 'SECONDARY-READONLY-CONNECTION-STRING' param apimApiName string = 'todo-api' param apimLoggerName string = 'app-insights-logger' param collections array = [ @@ -245,7 +242,7 @@ module api 'br/public:avm/res/app/container-app:0.2.0' = { } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -265,12 +262,9 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { collections: collections } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration:{ + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey - primaryReadonlyConnectionStringSecretName: primaryReadonlyConnectionStringSecretName - secondaryWriteConnectionStringSecretName: secondaryWriteConnectionStringSecretName - secondaryReadonlyConnectionStringSecretName: secondaryReadonlyConnectionStringSecretName } } } diff --git a/templates/todo/projects/python-mongo-swa-func/.repo/bicep/infra/main.bicep b/templates/todo/projects/python-mongo-swa-func/.repo/bicep/infra/main.bicep index 3a5f2790a67..77e596e9f71 100644 --- a/templates/todo/projects/python-mongo-swa-func/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/python-mongo-swa-func/.repo/bicep/infra/main.bicep @@ -81,7 +81,6 @@ var tags = { 'azd-env-name': environmentName } var defaultDatabaseName = 'Todo' var actualDatabaseName = !empty(cosmosDatabaseName) ? cosmosDatabaseName : defaultDatabaseName var webUri = 'https://${web.outputs.defaultHostname}' -var apiUri = 'https://${api.outputs.defaultHostname}' var apimApiUri = 'https://${apim.outputs.name}.azure-api.net/todo' var apimServiceId = useAPIM ? apim.outputs.resourceId : '' @@ -105,28 +104,19 @@ module web 'br/public:avm/res/web/static-site:0.3.0' = { } // The application backend -module api 'br/public:avm/res/web/site:0.3.9' = { +module api '../../../../../common/infra/bicep/app/api-avm.bicep' = { name: 'api' scope: rg params: { - kind: 'functionapp' - name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesFunctions}api-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'api' }) + name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesAppService}api-${resourceToken}' location: location - appInsightResourceId: applicationInsights.outputs.resourceId - managedIdentities: { - systemAssigned: true - } - clientAffinityEnabled: false + tags: tags + kind: 'app' + appServicePlanId: appServicePlan.outputs.resourceId siteConfig: { - cors: { - allowedOrigins: [ 'https://portal.azure.com', 'https://ms.portal.azure.com' , webUri ] - } - linuxFxVersion: 'python|3.10' - use32BitWorkerProcess: false + alwaysOn: true } - appSettingsKeyValuePairs: { + appSettings: { API_ALLOW_ORIGINS: webUri AZURE_COSMOS_CONNECTION_STRING_KEY: connectionStringKey AZURE_COSMOS_DATABASE_NAME: actualDatabaseName @@ -134,16 +124,12 @@ module api 'br/public:avm/res/web/site:0.3.9' = { AZURE_COSMOS_ENDPOINT: 'https://${cosmos.outputs.name}.documents.azure.com:443/' FUNCTIONS_EXTENSION_VERSION: '~4' FUNCTIONS_WORKER_RUNTIME: 'python' - SCM_DO_BUILD_DURING_DEPLOYMENT: 'True' - ENABLE_ORYX_BUILD: 'True' - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } } + appInsightResourceId: applicationInsights.outputs.resourceId + linuxFxVersion: 'python|3.10' + allowedOrigins: [ webUri ] storageAccountResourceId: storage.outputs.resourceId + clientAffinityEnabled: false } } @@ -160,7 +146,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.5.1' = { sku: 'standard' accessPolicies: [ { - objectId: api.outputs.systemAssignedMIPrincipalId + objectId: api.outputs.SERVICE_API_IDENTITY_PRINCIPAL_ID permissions: { secrets: [ 'get', 'list' ] } @@ -176,7 +162,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.5.1' = { } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -196,12 +182,9 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { collections: collections } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration:{ + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey - primaryReadonlyConnectionStringSecretName: primaryReadonlyConnectionStringSecretName - secondaryWriteConnectionStringSecretName: secondaryWriteConnectionStringSecretName - secondaryReadonlyConnectionStringSecretName: secondaryReadonlyConnectionStringSecretName } } } @@ -358,7 +341,7 @@ module apim 'br/public:avm/res/api-management/service:0.2.0' = if (useAPIM) { path: 'todo' displayName: 'Simple Todo API' apiDescription: 'This is a simple Todo API' - serviceUrl: apiUri + serviceUrl: api.outputs.SERVICE_API_URI subscriptionRequired: false protocols: [ 'https' ] type: 'http' @@ -380,7 +363,7 @@ module apiConfig 'br/public:avm/res/web/site:0.3.9' = if (useAPIM) { scope: rg params: { kind: 'functionapp' - name: api.outputs.name + name: api.outputs.SERVICE_API_NAME tags: union(tags, { 'azd-service-name': 'api' }) siteConfig: { cors: { @@ -409,7 +392,7 @@ output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.uri output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId -output API_BASE_URL string = useAPIM ? apimApiUri : apiUri +output API_BASE_URL string = useAPIM ? apimApiUri : api.outputs.SERVICE_API_URI output REACT_APP_WEB_BASE_URL string = webUri output USE_APIM bool = useAPIM -output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, apiUri ]: [] +output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, api.outputs.SERVICE_API_URI ]: [] diff --git a/templates/todo/projects/python-mongo-swa-func/.repo/bicep/repo.yaml b/templates/todo/projects/python-mongo-swa-func/.repo/bicep/repo.yaml index 15236ca7628..95019c60301 100644 --- a/templates/todo/projects/python-mongo-swa-func/.repo/bicep/repo.yaml +++ b/templates/todo/projects/python-mongo-swa-func/.repo/bicep/repo.yaml @@ -118,6 +118,9 @@ repo: - from: ../../../../common/infra/bicep/app/applicationinsights-dashboard.bicep to: ./infra/app/applicationinsights-dashboard.bicep + - from: ../../../../common/infra/bicep/app/api-avm.bicep + to: ./infra/app/api-avm.bicep + - from: ./../../ to: ./ ignore: diff --git a/templates/todo/projects/python-mongo/.repo/bicep/infra/main.bicep b/templates/todo/projects/python-mongo/.repo/bicep/infra/main.bicep index 56e4d10cec1..48f66b4a86e 100644 --- a/templates/todo/projects/python-mongo/.repo/bicep/infra/main.bicep +++ b/templates/todo/projects/python-mongo/.repo/bicep/infra/main.bicep @@ -25,9 +25,6 @@ param resourceGroupName string = '' param webServiceName string = '' param apimServiceName string = '' param connectionStringKey string = 'AZURE-COSMOS-CONNECTION-STRING' -param primaryReadonlyConnectionStringSecretName string= 'PRIMARY-READONLY-CONNECTION-STRING' -param secondaryWriteConnectionStringSecretName string = 'SECONDARY-WRITE-CONNECTION-STRING' -param secondaryReadonlyConnectionStringSecretName string = 'SECONDARY-READONLY-CONNECTION-STRING' param apimApiName string = 'todo-api' param apimLoggerName string = 'app-insights-logger' param collections array = [ @@ -79,8 +76,6 @@ var resourceToken = toLower(uniqueString(subscription().id, environmentName, loc var tags = { 'azd-env-name': environmentName } var defaultDatabaseName = 'Todo' var actualDatabaseName = !empty(cosmosDatabaseName) ? cosmosDatabaseName : defaultDatabaseName -var webUri = 'https://${web.outputs.defaultHostname}' -var apiUri = 'https://${api.outputs.defaultHostname}' var apimApiUri = 'https://${apim.outputs.name}.azure-api.net/todo' var apimServiceId = useAPIM ? apim.outputs.resourceId : '' @@ -92,67 +87,43 @@ resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = { } // The application frontend -module web 'br/public:avm/res/web/site:0.3.9' = { +module web '../../../../../common/infra/bicep/app/web-avm.bicep' = { name: 'web' scope: rg params: { - kind: 'app' name: !empty(webServiceName) ? webServiceName : '${abbrs.webSitesAppService}web-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'web' }) location: location + tags: tags + appServicePlanId: appServicePlan.outputs.resourceId appInsightResourceId: applicationInsights.outputs.resourceId - siteConfig: { - linuxFxVersion: 'node|20-lts' - appCommandLine: 'pm2 serve /home/site/wwwroot --no-daemon --spa' - alwaysOn: true - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } - } + linuxFxVersion: 'node|20-lts' } } // The application backend -module api 'br/public:avm/res/web/site:0.3.9' = { +module api '../../../../../common/infra/bicep/app/api-avm.bicep' = { name: 'api' scope: rg params: { - kind: 'app' name: !empty(apiServiceName) ? apiServiceName : '${abbrs.webSitesAppService}api-${resourceToken}' - serverFarmResourceId: appServicePlan.outputs.resourceId - tags: union(tags, { 'azd-service-name': 'api' }) location: location - appInsightResourceId: applicationInsights.outputs.resourceId - managedIdentities: { - systemAssigned: true - } + tags: tags + kind: 'app' + appServicePlanId: appServicePlan.outputs.resourceId siteConfig: { - cors: { - allowedOrigins: [ 'https://portal.azure.com', 'https://ms.portal.azure.com' , webUri ] - } alwaysOn: true - linuxFxVersion: 'python|3.10' appCommandLine: 'gunicorn --workers 4 --threads 2 --timeout 60 --access-logfile "-" --error-logfile "-" --bind=0.0.0.0:8000 -k uvicorn.workers.UvicornWorker todo.app:app' } - appSettingsKeyValuePairs: { + appSettings: { AZURE_KEY_VAULT_ENDPOINT: keyVault.outputs.uri AZURE_COSMOS_CONNECTION_STRING_KEY: connectionStringKey AZURE_COSMOS_DATABASE_NAME: actualDatabaseName AZURE_COSMOS_ENDPOINT: 'https://${cosmos.outputs.name}.documents.azure.com:443/' - API_ALLOW_ORIGINS: webUri - SCM_DO_BUILD_DURING_DEPLOYMENT: 'True' - ENABLE_ORYX_BUILD: 'True' - } - logsConfiguration: { - applicationLogs: { fileSystem: { level: 'Verbose' } } - detailedErrorMessages: { enabled: true } - failedRequestsTracing: { enabled: true } - httpLogs: { fileSystem: { enabled: true, retentionInDays: 1, retentionInMb: 35 } } + API_ALLOW_ORIGINS: web.outputs.SERVICE_WEB_URI } + appInsightResourceId: applicationInsights.outputs.resourceId + linuxFxVersion: 'python|3.10' + allowedOrigins: [ web.outputs.SERVICE_WEB_URI ] } } @@ -175,7 +146,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.3.5' = { } } { - objectId: api.outputs.systemAssignedMIPrincipalId + objectId: api.outputs.SERVICE_API_IDENTITY_PRINCIPAL_ID permissions: { secrets: [ 'get', 'list' ] } @@ -185,7 +156,7 @@ module accessKeyVault 'br/public:avm/res/key-vault/vault:0.3.5' = { } // The application database -module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { +module cosmos 'br/public:avm/res/document-db/database-account:0.6.0' = { name: 'cosmos' scope: rg params: { @@ -205,12 +176,9 @@ module cosmos 'br/public:avm/res/document-db/database-account:0.4.0' = { collections: collections } ] - secretsKeyVault: { - keyVaultName: keyVault.outputs.name + secretsExportConfiguration:{ + keyVaultResourceId: keyVault.outputs.resourceId primaryWriteConnectionStringSecretName: connectionStringKey - primaryReadonlyConnectionStringSecretName: primaryReadonlyConnectionStringSecretName - secondaryWriteConnectionStringSecretName: secondaryWriteConnectionStringSecretName - secondaryReadonlyConnectionStringSecretName: secondaryReadonlyConnectionStringSecretName } } } @@ -349,14 +317,14 @@ module apim 'br/public:avm/res/api-management/service:0.2.0' = if (useAPIM) { path: 'todo' displayName: 'Simple Todo API' apiDescription: 'This is a simple Todo API' - serviceUrl: apiUri + serviceUrl: api.outputs.SERVICE_API_URI subscriptionRequired: false protocols: [ 'https' ] type: 'http' value: loadTextContent('../../../../../api/common/openapi.yaml') policies: [ { - value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', webUri) + value: replace(loadTextContent('../../../../../../common/infra/shared/gateway/apim/apim-api-policy.xml'), '{origin}', web.outputs.SERVICE_WEB_URI) format: 'rawxml' } ] @@ -371,7 +339,7 @@ module apiConfig 'br/public:avm/res/web/site:0.3.9' = if (useAPIM) { scope: rg params: { kind: 'app' - name: api.outputs.name + name: api.outputs.SERVICE_API_NAME tags: union(tags, { 'azd-service-name': 'api' }) serverFarmResourceId: appServicePlan.outputs.resourceId location: location @@ -393,7 +361,7 @@ output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.uri output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name output AZURE_LOCATION string = location output AZURE_TENANT_ID string = tenant().tenantId -output API_BASE_URL string = useAPIM ? apimApiUri : apiUri -output REACT_APP_WEB_BASE_URL string = webUri +output API_BASE_URL string = useAPIM ? apimApiUri : api.outputs.SERVICE_API_URI +output REACT_APP_WEB_BASE_URL string = web.outputs.SERVICE_WEB_URI output USE_APIM bool = useAPIM -output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, apiUri ]: [] +output SERVICE_API_ENDPOINTS array = useAPIM ? [ apimApiUri, api.outputs.SERVICE_API_URI ]: [] diff --git a/templates/todo/projects/python-mongo/.repo/bicep/repo.yaml b/templates/todo/projects/python-mongo/.repo/bicep/repo.yaml index 9eaa7010712..11381190b47 100644 --- a/templates/todo/projects/python-mongo/.repo/bicep/repo.yaml +++ b/templates/todo/projects/python-mongo/.repo/bicep/repo.yaml @@ -128,6 +128,12 @@ repo: - from: ../../../../common/infra/bicep/app/applicationinsights-dashboard.bicep to: ./infra/app/applicationinsights-dashboard.bicep + - from: ../../../../common/infra/bicep/app/web-avm.bicep + to: ./infra/app/web-avm.bicep + + - from: ../../../../common/infra/bicep/app/api-avm.bicep + to: ./infra/app/api-avm.bicep + - from: ./../../ to: ./ ignore: