azd 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +2 -0
  4. data/lib/generators/azd/install_generator.rb +14 -0
  5. data/lib/generators/templates/azure.yaml.tt +22 -0
  6. data/lib/generators/templates/infra/abbreviations.json +136 -0
  7. data/lib/generators/templates/infra/core/ai/cognitiveservices.bicep +53 -0
  8. data/lib/generators/templates/infra/core/config/configstore.bicep +48 -0
  9. data/lib/generators/templates/infra/core/database/cosmos/cosmos-account.bicep +49 -0
  10. data/lib/generators/templates/infra/core/database/cosmos/mongo/cosmos-mongo-account.bicep +23 -0
  11. data/lib/generators/templates/infra/core/database/cosmos/mongo/cosmos-mongo-db.bicep +47 -0
  12. data/lib/generators/templates/infra/core/database/cosmos/sql/cosmos-sql-account.bicep +22 -0
  13. data/lib/generators/templates/infra/core/database/cosmos/sql/cosmos-sql-db.bicep +74 -0
  14. data/lib/generators/templates/infra/core/database/cosmos/sql/cosmos-sql-role-assign.bicep +19 -0
  15. data/lib/generators/templates/infra/core/database/cosmos/sql/cosmos-sql-role-def.bicep +30 -0
  16. data/lib/generators/templates/infra/core/database/mysql/flexibleserver.bicep +65 -0
  17. data/lib/generators/templates/infra/core/database/postgresql/flexibleserver.bicep +81 -0
  18. data/lib/generators/templates/infra/core/database/sqlserver/sqlserver.bicep +130 -0
  19. data/lib/generators/templates/infra/core/gateway/apim.bicep +79 -0
  20. data/lib/generators/templates/infra/core/host/aks-agent-pool.bicep +18 -0
  21. data/lib/generators/templates/infra/core/host/aks-managed-cluster.bicep +140 -0
  22. data/lib/generators/templates/infra/core/host/aks.bicep +280 -0
  23. data/lib/generators/templates/infra/core/host/appservice-appsettings.bicep +17 -0
  24. data/lib/generators/templates/infra/core/host/appservice.bicep +123 -0
  25. data/lib/generators/templates/infra/core/host/appserviceplan.bicep +22 -0
  26. data/lib/generators/templates/infra/core/host/container-app-upsert.bicep +109 -0
  27. data/lib/generators/templates/infra/core/host/container-app.bicep +165 -0
  28. data/lib/generators/templates/infra/core/host/container-apps-environment.bicep +41 -0
  29. data/lib/generators/templates/infra/core/host/container-apps.bicep +40 -0
  30. data/lib/generators/templates/infra/core/host/container-registry.bicep +83 -0
  31. data/lib/generators/templates/infra/core/host/functions.bicep +86 -0
  32. data/lib/generators/templates/infra/core/host/staticwebapp.bicep +22 -0
  33. data/lib/generators/templates/infra/core/monitor/applicationinsights-dashboard.bicep +1236 -0
  34. data/lib/generators/templates/infra/core/monitor/applicationinsights.bicep +30 -0
  35. data/lib/generators/templates/infra/core/monitor/loganalytics.bicep +22 -0
  36. data/lib/generators/templates/infra/core/monitor/monitoring.bicep +32 -0
  37. data/lib/generators/templates/infra/core/networking/cdn-endpoint.bicep +52 -0
  38. data/lib/generators/templates/infra/core/networking/cdn-profile.bicep +34 -0
  39. data/lib/generators/templates/infra/core/networking/cdn.bicep +42 -0
  40. data/lib/generators/templates/infra/core/search/search-services.bicep +68 -0
  41. data/lib/generators/templates/infra/core/security/aks-managed-cluster-access.bicep +19 -0
  42. data/lib/generators/templates/infra/core/security/configstore-access.bicep +21 -0
  43. data/lib/generators/templates/infra/core/security/keyvault-access.bicep +22 -0
  44. data/lib/generators/templates/infra/core/security/keyvault-secret.bicep +31 -0
  45. data/lib/generators/templates/infra/core/security/keyvault.bicep +31 -0
  46. data/lib/generators/templates/infra/core/security/registry-access.bicep +19 -0
  47. data/lib/generators/templates/infra/core/security/role.bicep +21 -0
  48. data/lib/generators/templates/infra/core/storage/storage-account.bicep +64 -0
  49. data/lib/generators/templates/infra/core/testing/loadtesting.bicep +15 -0
  50. data/lib/generators/templates/infra/identity.bicep +20 -0
  51. data/lib/generators/templates/infra/main.bicep +243 -0
  52. data/lib/generators/templates/infra/main.parameters.json +25 -0
  53. data/lib/generators/templates/infra/rails.bicep +95 -0
  54. metadata +115 -0
@@ -0,0 +1,165 @@
1
+ metadata description = 'Creates a container app in an Azure Container App environment.'
2
+ param name string
3
+ param location string = resourceGroup().location
4
+ param tags object = {}
5
+
6
+ @description('Allowed origins')
7
+ param allowedOrigins array = []
8
+
9
+ @description('Name of the environment for container apps')
10
+ param containerAppsEnvironmentName string
11
+
12
+ @description('CPU cores allocated to a single container instance, e.g., 0.5')
13
+ param containerCpuCoreCount string = '0.5'
14
+
15
+ @description('The maximum number of replicas to run. Must be at least 1.')
16
+ @minValue(1)
17
+ param containerMaxReplicas int = 10
18
+
19
+ @description('Memory allocated to a single container instance, e.g., 1Gi')
20
+ param containerMemory string = '1.0Gi'
21
+
22
+ @description('The minimum number of replicas to run. Must be at least 1.')
23
+ param containerMinReplicas int = 1
24
+
25
+ @description('The name of the container')
26
+ param containerName string = 'main'
27
+
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
+
34
+ @description('The protocol used by Dapr to connect to the app, e.g., http or grpc')
35
+ @allowed([ 'http', 'grpc' ])
36
+ param daprAppProtocol string = 'http'
37
+
38
+ @description('The Dapr app ID')
39
+ param daprAppId string = containerName
40
+
41
+ @description('Enable Dapr')
42
+ param daprEnabled bool = false
43
+
44
+ @description('The environment variables for the container')
45
+ param env array = []
46
+
47
+ @description('Specifies if the resource ingress is exposed externally')
48
+ param external bool = true
49
+
50
+ @description('The name of the user-assigned identity')
51
+ param identityName string = ''
52
+
53
+ @description('The type of identity for the resource')
54
+ @allowed([ 'None', 'SystemAssigned', 'UserAssigned' ])
55
+ param identityType string = 'None'
56
+
57
+ @description('The name of the container image')
58
+ param imageName string = ''
59
+
60
+ @description('Specifies if Ingress is enabled for the container app')
61
+ param ingressEnabled bool = true
62
+
63
+ param revisionMode string = 'Single'
64
+
65
+ @description('The secrets required for the container')
66
+ param secrets array = []
67
+
68
+ @description('The service binds associated with the container')
69
+ param serviceBinds array = []
70
+
71
+ @description('The name of the container apps add-on to use. e.g. redis')
72
+ param serviceType string = ''
73
+
74
+ @description('The target port for the container')
75
+ param targetPort int = 80
76
+
77
+ resource userIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (!empty(identityName)) {
78
+ name: identityName
79
+ }
80
+
81
+ // Private registry support requires both an ACR name and a User Assigned managed identity
82
+ var usePrivateRegistry = !empty(identityName) && !empty(containerRegistryName)
83
+
84
+ // Automatically set to `UserAssigned` when an `identityName` has been set
85
+ var normalizedIdentityType = !empty(identityName) ? 'UserAssigned' : identityType
86
+
87
+ module containerRegistryAccess '../security/registry-access.bicep' = if (usePrivateRegistry) {
88
+ name: '${deployment().name}-registry-access'
89
+ params: {
90
+ containerRegistryName: containerRegistryName
91
+ principalId: usePrivateRegistry ? userIdentity.properties.principalId : ''
92
+ }
93
+ }
94
+
95
+ resource app 'Microsoft.App/containerApps@2023-05-02-preview' = {
96
+ name: name
97
+ location: location
98
+ tags: tags
99
+ // It is critical that the identity is granted ACR pull access before the app is created
100
+ // otherwise the container app will throw a provision error
101
+ // This also forces us to use an user assigned managed identity since there would no way to
102
+ // provide the system assigned identity with the ACR pull access before the app is created
103
+ dependsOn: usePrivateRegistry ? [ containerRegistryAccess ] : []
104
+ identity: {
105
+ type: normalizedIdentityType
106
+ userAssignedIdentities: !empty(identityName) && normalizedIdentityType == 'UserAssigned' ? { '${userIdentity.id}': {} } : null
107
+ }
108
+ properties: {
109
+ managedEnvironmentId: containerAppsEnvironment.id
110
+ configuration: {
111
+ activeRevisionsMode: revisionMode
112
+ ingress: ingressEnabled ? {
113
+ external: external
114
+ targetPort: targetPort
115
+ transport: 'auto'
116
+ corsPolicy: {
117
+ allowedOrigins: union([ 'https://portal.azure.com', 'https://ms.portal.azure.com' ], allowedOrigins)
118
+ }
119
+ } : null
120
+ dapr: daprEnabled ? {
121
+ enabled: true
122
+ appId: daprAppId
123
+ appProtocol: daprAppProtocol
124
+ appPort: ingressEnabled ? targetPort : 0
125
+ } : { enabled: false }
126
+ secrets: secrets
127
+ service: !empty(serviceType) ? { type: serviceType } : null
128
+ registries: usePrivateRegistry ? [
129
+ {
130
+ server: '${containerRegistryName}.${containerRegistryHostSuffix}'
131
+ identity: userIdentity.id
132
+ }
133
+ ] : []
134
+ }
135
+ template: {
136
+ serviceBinds: !empty(serviceBinds) ? serviceBinds : null
137
+ containers: [
138
+ {
139
+ image: !empty(imageName) ? imageName : 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
140
+ name: containerName
141
+ env: env
142
+ resources: {
143
+ cpu: json(containerCpuCoreCount)
144
+ memory: containerMemory
145
+ }
146
+ }
147
+ ]
148
+ scale: {
149
+ minReplicas: containerMinReplicas
150
+ maxReplicas: containerMaxReplicas
151
+ }
152
+ }
153
+ }
154
+ }
155
+
156
+ resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' existing = {
157
+ name: containerAppsEnvironmentName
158
+ }
159
+
160
+ output defaultDomain string = containerAppsEnvironment.properties.defaultDomain
161
+ output identityPrincipalId string = normalizedIdentityType == 'None' ? '' : (empty(identityName) ? app.identity.principalId : userIdentity.properties.principalId)
162
+ output imageName string = imageName
163
+ output name string = app.name
164
+ output serviceBind object = !empty(serviceType) ? { serviceId: app.id, name: name } : {}
165
+ output uri string = ingressEnabled ? 'https://${app.properties.configuration.ingress.fqdn}' : ''
@@ -0,0 +1,41 @@
1
+ metadata description = 'Creates an Azure Container Apps environment.'
2
+ param name string
3
+ param location string = resourceGroup().location
4
+ param tags object = {}
5
+
6
+ @description('Name of the Application Insights resource')
7
+ param applicationInsightsName string = ''
8
+
9
+ @description('Specifies if Dapr is enabled')
10
+ param daprEnabled bool = false
11
+
12
+ @description('Name of the Log Analytics workspace')
13
+ param logAnalyticsWorkspaceName string
14
+
15
+ resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = {
16
+ name: name
17
+ location: location
18
+ tags: tags
19
+ properties: {
20
+ appLogsConfiguration: {
21
+ destination: 'log-analytics'
22
+ logAnalyticsConfiguration: {
23
+ customerId: logAnalyticsWorkspace.properties.customerId
24
+ sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
25
+ }
26
+ }
27
+ daprAIInstrumentationKey: daprEnabled && !empty(applicationInsightsName) ? applicationInsights.properties.InstrumentationKey : ''
28
+ }
29
+ }
30
+
31
+ resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = {
32
+ name: logAnalyticsWorkspaceName
33
+ }
34
+
35
+ resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = if (daprEnabled && !empty(applicationInsightsName)) {
36
+ name: applicationInsightsName
37
+ }
38
+
39
+ output defaultDomain string = containerAppsEnvironment.properties.defaultDomain
40
+ output id string = containerAppsEnvironment.id
41
+ output name string = containerAppsEnvironment.name
@@ -0,0 +1,40 @@
1
+ metadata description = 'Creates an Azure Container Registry and an Azure Container Apps environment.'
2
+ param name string
3
+ param location string = resourceGroup().location
4
+ param tags object = {}
5
+
6
+ param containerAppsEnvironmentName string
7
+ param containerRegistryName string
8
+ param containerRegistryResourceGroupName string = ''
9
+ param containerRegistryAdminUserEnabled bool = false
10
+ param logAnalyticsWorkspaceName string
11
+ param applicationInsightsName string = ''
12
+
13
+ module containerAppsEnvironment 'container-apps-environment.bicep' = {
14
+ name: '${name}-container-apps-environment'
15
+ params: {
16
+ name: containerAppsEnvironmentName
17
+ location: location
18
+ tags: tags
19
+ logAnalyticsWorkspaceName: logAnalyticsWorkspaceName
20
+ applicationInsightsName: applicationInsightsName
21
+ }
22
+ }
23
+
24
+ module containerRegistry 'container-registry.bicep' = {
25
+ name: '${name}-container-registry'
26
+ scope: !empty(containerRegistryResourceGroupName) ? resourceGroup(containerRegistryResourceGroupName) : resourceGroup()
27
+ params: {
28
+ name: containerRegistryName
29
+ location: location
30
+ adminUserEnabled: containerRegistryAdminUserEnabled
31
+ tags: tags
32
+ }
33
+ }
34
+
35
+ output defaultDomain string = containerAppsEnvironment.outputs.defaultDomain
36
+ output environmentName string = containerAppsEnvironment.outputs.name
37
+ output environmentId string = containerAppsEnvironment.outputs.id
38
+
39
+ output registryLoginServer string = containerRegistry.outputs.loginServer
40
+ output registryName string = containerRegistry.outputs.name
@@ -0,0 +1,83 @@
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('Indicates whether data endpoint is enabled')
13
+ param dataEndpointEnabled bool = false
14
+
15
+ @description('Encryption settings')
16
+ param encryption object = {
17
+ status: 'disabled'
18
+ }
19
+
20
+ @description('Options for bypassing network rules')
21
+ param networkRuleBypassOptions string = 'AzureServices'
22
+
23
+ @description('Public network access setting')
24
+ param publicNetworkAccess string = 'Enabled'
25
+
26
+ @description('SKU settings')
27
+ param sku object = {
28
+ name: 'Basic'
29
+ }
30
+
31
+ @description('Zone redundancy setting')
32
+ param zoneRedundancy string = 'Disabled'
33
+
34
+ @description('The log analytics workspace ID used for logging and monitoring')
35
+ param workspaceId string = ''
36
+
37
+ // 2023-01-01-preview needed for anonymousPullEnabled
38
+ resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = {
39
+ name: name
40
+ location: location
41
+ tags: tags
42
+ sku: sku
43
+ properties: {
44
+ adminUserEnabled: adminUserEnabled
45
+ anonymousPullEnabled: anonymousPullEnabled
46
+ dataEndpointEnabled: dataEndpointEnabled
47
+ encryption: encryption
48
+ networkRuleBypassOptions: networkRuleBypassOptions
49
+ publicNetworkAccess: publicNetworkAccess
50
+ zoneRedundancy: zoneRedundancy
51
+ }
52
+ }
53
+
54
+ // TODO: Update diagnostics to be its own module
55
+ // Blocking issue: https://github.com/Azure/bicep/issues/622
56
+ // Unable to pass in a `resource` scope or unable to use string interpolation in resource types
57
+ resource diagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(workspaceId)) {
58
+ name: 'registry-diagnostics'
59
+ scope: containerRegistry
60
+ properties: {
61
+ workspaceId: workspaceId
62
+ logs: [
63
+ {
64
+ category: 'ContainerRegistryRepositoryEvents'
65
+ enabled: true
66
+ }
67
+ {
68
+ category: 'ContainerRegistryLoginEvents'
69
+ enabled: true
70
+ }
71
+ ]
72
+ metrics: [
73
+ {
74
+ category: 'AllMetrics'
75
+ enabled: true
76
+ timeGrain: 'PT1M'
77
+ }
78
+ ]
79
+ }
80
+ }
81
+
82
+ output loginServer string = containerRegistry.properties.loginServer
83
+ output name string = containerRegistry.name
@@ -0,0 +1,86 @@
1
+ metadata description = 'Creates an Azure Function in an existing Azure App Service plan.'
2
+ param name string
3
+ param location string = resourceGroup().location
4
+ param tags object = {}
5
+
6
+ // Reference Properties
7
+ param applicationInsightsName string = ''
8
+ param appServicePlanId string
9
+ param keyVaultName string = ''
10
+ param managedIdentity bool = !empty(keyVaultName)
11
+ param storageAccountName string
12
+
13
+ // Runtime Properties
14
+ @allowed([
15
+ 'dotnet', 'dotnetcore', 'dotnet-isolated', 'node', 'python', 'java', 'powershell', 'custom'
16
+ ])
17
+ param runtimeName string
18
+ param runtimeNameAndVersion string = '${runtimeName}|${runtimeVersion}'
19
+ param runtimeVersion string
20
+
21
+ // Function Settings
22
+ @allowed([
23
+ '~4', '~3', '~2', '~1'
24
+ ])
25
+ param extensionVersion string = '~4'
26
+
27
+ // Microsoft.Web/sites Properties
28
+ param kind string = 'functionapp,linux'
29
+
30
+ // Microsoft.Web/sites/config
31
+ param allowedOrigins array = []
32
+ param alwaysOn bool = true
33
+ param appCommandLine string = ''
34
+ @secure()
35
+ param appSettings object = {}
36
+ param clientAffinityEnabled bool = false
37
+ param enableOryxBuild bool = contains(kind, 'linux')
38
+ param functionAppScaleLimit int = -1
39
+ param linuxFxVersion string = runtimeNameAndVersion
40
+ param minimumElasticInstanceCount int = -1
41
+ param numberOfWorkers int = -1
42
+ param scmDoBuildDuringDeployment bool = true
43
+ param use32BitWorkerProcess bool = false
44
+ param healthCheckPath string = ''
45
+
46
+ module functions 'appservice.bicep' = {
47
+ name: '${name}-functions'
48
+ params: {
49
+ name: name
50
+ location: location
51
+ tags: tags
52
+ allowedOrigins: allowedOrigins
53
+ alwaysOn: alwaysOn
54
+ appCommandLine: appCommandLine
55
+ applicationInsightsName: applicationInsightsName
56
+ appServicePlanId: appServicePlanId
57
+ appSettings: union(appSettings, {
58
+ AzureWebJobsStorage: 'DefaultEndpointsProtocol=https;AccountName=${storage.name};AccountKey=${storage.listKeys().keys[0].value};EndpointSuffix=${environment().suffixes.storage}'
59
+ FUNCTIONS_EXTENSION_VERSION: extensionVersion
60
+ FUNCTIONS_WORKER_RUNTIME: runtimeName
61
+ })
62
+ clientAffinityEnabled: clientAffinityEnabled
63
+ enableOryxBuild: enableOryxBuild
64
+ functionAppScaleLimit: functionAppScaleLimit
65
+ healthCheckPath: healthCheckPath
66
+ keyVaultName: keyVaultName
67
+ kind: kind
68
+ linuxFxVersion: linuxFxVersion
69
+ managedIdentity: managedIdentity
70
+ minimumElasticInstanceCount: minimumElasticInstanceCount
71
+ numberOfWorkers: numberOfWorkers
72
+ runtimeName: runtimeName
73
+ runtimeVersion: runtimeVersion
74
+ runtimeNameAndVersion: runtimeNameAndVersion
75
+ scmDoBuildDuringDeployment: scmDoBuildDuringDeployment
76
+ use32BitWorkerProcess: use32BitWorkerProcess
77
+ }
78
+ }
79
+
80
+ resource storage 'Microsoft.Storage/storageAccounts@2021-09-01' existing = {
81
+ name: storageAccountName
82
+ }
83
+
84
+ output identityPrincipalId string = managedIdentity ? functions.outputs.identityPrincipalId : ''
85
+ output name string = functions.outputs.name
86
+ output uri string = functions.outputs.uri
@@ -0,0 +1,22 @@
1
+ metadata description = 'Creates an Azure Static Web Apps instance.'
2
+ param name string
3
+ param location string = resourceGroup().location
4
+ param tags object = {}
5
+
6
+ param sku object = {
7
+ name: 'Free'
8
+ tier: 'Free'
9
+ }
10
+
11
+ resource web 'Microsoft.Web/staticSites@2022-03-01' = {
12
+ name: name
13
+ location: location
14
+ tags: tags
15
+ sku: sku
16
+ properties: {
17
+ provider: 'Custom'
18
+ }
19
+ }
20
+
21
+ output name string = web.name
22
+ output uri string = 'https://${web.properties.defaultHostname}'