11// ============================================================================== 
22// Bicep IaC template 
3- // Deploy all NanoMon components using Azure Container Apps  
3+ // Deploy all NanoMon components using Azure Container Apps and AVN  
44// ============================================================================== 
55
66targetScope  = 'subscription' 
77
88@description ('Name used for resource group, and default base name for all resources' )
99param  appName  string 
1010
11- @description ('Azure region for all resources' )
12- param  location  string  = deployment ().location 
13- 
1411@description ('Repo and registry where the images are stored' )
1512param  imageRepo  string  = 'ghcr.io/benc-uk' 
1613
@@ -26,11 +23,14 @@ param authTenant string = 'common'
2623@description ('Connection DSN to an external Postgres database, if empty a new Postgres database will be created' )
2724param  postgresDSN  string  = '' 
2825
26+ @description ('IP address granted access to the Postgres database' )
27+ param  allowAccessForIP  string  = '' 
28+ 
2929@description ('Password for the Postgres user' )
3030@secure ()
3131param  postgresPassword  string  = '' 
3232
33- @ description ( ' Alerting parameters, all optional' ) 
33+ //  Alerting parameters, all optional
3434param  alertFrom  string  = '' 
3535param  alertTo  string  = '' 
3636param  alertMailHost  string  = '' 
@@ -40,140 +40,159 @@ param alertMailPort string = ''
4040param  alertPassword  string  = '__ignored_default__' 
4141param  alertFailCount  int  = 3 
4242
43- @description ('IP address granted access to the Postgres database' )
44- param  allowAccessForIP  string  = '' 
45- 
4643// ===== Modules & Resources ================================================== 
4744
4845resource  resGroup  'Microsoft.Resources/resourceGroups@2022-09-01'  = {
4946  name : appName 
50-   location : location 
47+   location : deployment (). location 
5148}
5249
53- module  database  './bicep-iac/modules/database/postgres-cosmosdb.bicep'  = if  (postgresDSN  == '' ) {
54-   scope : resGroup 
55-   params : {
56-     location : location 
57-     name : 'nanomon-db' 
58-     databaseName : 'nanomon' 
59-     version : '16' 
60-     adminPassword : postgresPassword 
61-     allowAccessForIP : allowAccessForIP 
62-   }
63- }
64- 
65- module  logAnalytics  './bicep-iac/modules/monitoring/log-analytics.bicep'  = {
50+ module  database  'br/public:avm/res/db-for-postgre-sql/flexible-server:0.12.1'  = if  (postgresDSN  == '' ) {
6651  scope : resGroup 
6752
6853  params : {
69-     location : location 
70-     name : 'logs' 
54+     name : 'nanomon-db-${substring (uniqueString (resGroup .name ), 0 , 5 )}' 
55+     skuName : 'Standard_B1ms' 
56+     tier : 'Burstable' 
57+     version : '17' 
58+     geoRedundantBackup : 'Disabled' 
59+     highAvailability : 'Disabled' 
60+     availabilityZone : -1 
61+ 
62+     administratorLogin : 'nanomon' 
63+     administratorLoginPassword : postgresPassword 
64+ 
65+     databases : [
66+       { name : 'nanomon'  }
67+     ]
68+ 
69+     publicNetworkAccess : 'Enabled' 
70+     firewallRules : [
71+       {
72+         name : 'AllowAzure' 
73+         endIpAddress : '0.0.0.0' 
74+         startIpAddress : '0.0.0.0' 
75+       }
76+       {
77+         name : 'AllowAccessForIP' 
78+         endIpAddress : allowAccessForIP 
79+         startIpAddress : allowAccessForIP 
80+       }
81+     ]
7182  }
7283}
7384
74- module  containerAppEnv   './bicep-iac/modules/containers/ app-env.bicep '
85+ module  appEnv   'br/public:avm/res/ app/managed-environment:0.11.2 '
7586  scope : resGroup 
7687
7788  params : {
78-     location : location 
79-     name : 'app-environment' 
80-     logAnalyticsName : logAnalytics .outputs .name 
81-     logAnalyticsResGroup : resGroup .name 
89+     name : 'nanomon' 
90+ 
91+     zoneRedundant : false 
92+     publicNetworkAccess : 'Enabled' 
93+     appLogsConfiguration : {
94+       destination : 'azure-monitor' 
95+     }
8296  }
8397}
8498
85- module  api  './bicep-iac/modules/containers/ app.bicep '  = {
99+ module  api  'br/public:avm/res/app/container- app:0.18.1 '  = {
86100  scope : resGroup 
87101
88102  params : {
89-     location : location 
90103    name : 'nanomon-api' 
91-     environmentId : containerAppEnv .outputs .id 
92-     image : '${imageRepo }/nanomon-api:${imageTag }' 
93- 
94-     probePath : '/api/health' 
95-     probePort : 8000 
104+     environmentResourceId : appEnv .outputs .resourceId 
96105
97-     ingressPort : 8000 
106+     ingressTargetPort : 8000 
98107    ingressExternal : true 
99108
100-     cpu : '0.25' 
101-     memory : '0.5Gi' 
102- 
103109    secrets : [
104110      {
105111        name : 'postgres-password' 
106112        value : postgresPassword 
107113      }
108114    ]
109115
110-     envs : [
116+     containers : [
111117      {
112-         name : 'POSTGRES_DSN' 
113-         value : postgresDSN  != ''  ? postgresDSN  : database !.outputs .dsn 
114-       }
115-       {
116-         name : 'POSTGRES_PASSWORD' 
117-         secretRef : 'postgres-password' 
118-       }
119-       {
120-         name : 'AUTH_CLIENT_ID' 
121-         value : authClientId 
122-       }
123-       {
124-         name : 'AUTH_TENANT' 
125-         value : authTenant 
118+         image : '${imageRepo }/nanomon-api:${imageTag }' 
119+         name : 'nanomon-api' 
120+         resources : { cpu : '0.25' , memory : '0.5Gi'  }
121+         probes : [
122+           {
123+             type : 'Liveness' 
124+             httpGet : { path : '/api/health' , port : 8000  }
125+           }
126+         ]
127+         env : [
128+           {
129+             name : 'POSTGRES_DSN' 
130+             value : postgresDSN  != ''  ? postgresDSN  : 'host=${database !.outputs .fqdn } dbname=nanomon user=nanomon' 
131+           }
132+           {
133+             name : 'POSTGRES_PASSWORD' 
134+             secretRef : 'postgres-password' 
135+           }
136+           {
137+             name : 'AUTH_CLIENT_ID' 
138+             value : authClientId 
139+           }
140+           {
141+             name : 'AUTH_TENANT' 
142+             value : authTenant 
143+           }
144+         ]
126145      }
127146    ]
128147  }
129148}
130149
131- module  frontend  './bicep-iac/modules/containers/ app.bicep '  = {
150+ module  frontend  'br/public:avm/res/app/container- app:0.18.1 '  = {
132151  scope : resGroup 
133152
134153  params : {
135-     location : location 
136154    name : 'nanomon-frontend' 
137-     environmentId : containerAppEnv .outputs .id 
138-     image : '${imageRepo }/nanomon-frontend:${imageTag }' 
155+     environmentResourceId : appEnv .outputs .resourceId 
139156
140-     probePath : '/' 
141-     probePort : 8001 
142- 
143-     ingressPort : 8001 
157+     ingressTargetPort : 8001 
144158    ingressExternal : true 
145159
146-     cpu : '0.25' 
147-     memory : '0.5Gi' 
148- 
149-     envs : [
150-       {
151-         name : 'API_ENDPOINT' 
152-         value : 'https://${api .outputs .fqdn }/api' 
153-       }
154-       {
155-         name : 'AUTH_CLIENT_ID' 
156-         value : authClientId 
157-       }
160+     containers : [
158161      {
159-         name : 'AUTH_TENANT' 
160-         value : authTenant 
162+         image : '${imageRepo }/nanomon-frontend:${imageTag }' 
163+         name : 'nanomon-frontend' 
164+         resources : { cpu : '0.25' , memory : '0.5Gi'  }
165+         probes : [
166+           {
167+             type : 'Liveness' 
168+             httpGet : { path : '/' , port : 8001  }
169+           }
170+         ]
171+         env : [
172+           {
173+             name : 'API_ENDPOINT' 
174+             value : 'https://${api .outputs .fqdn }/api' 
175+           }
176+           {
177+             name : 'AUTH_CLIENT_ID' 
178+             value : authClientId 
179+           }
180+           {
181+             name : 'AUTH_TENANT' 
182+             value : authTenant 
183+           }
184+         ]
161185      }
162186    ]
163187  }
164188}
165189
166- module  runner  './bicep-iac/modules/containers/ app.bicep '  = {
190+ module  runner  'br/public:avm/res/app/container- app:0.18.1 '  = {
167191  scope : resGroup 
168192
169193  params : {
170-     location : location 
171194    name : 'nanomon-runner' 
172-     environmentId : containerAppEnv .outputs .id 
173-     image : '${imageRepo }/nanomon-runner:${imageTag }' 
174- 
175-     cpu : '0.25' 
176-     memory : '0.5Gi' 
195+     environmentResourceId : appEnv .outputs .resourceId 
177196
178197    secrets : [
179198      {
@@ -186,44 +205,52 @@ module runner './bicep-iac/modules/containers/app.bicep' = {
186205      }
187206    ]
188207
189-     envs : [
190-       {
191-         name : 'POSTGRES_DSN' 
192-         value : postgresDSN  != ''  ? postgresDSN  : database !.outputs .dsn 
193-       }
194-       {
195-         name : 'POSTGRES_PASSWORD' 
196-         secretRef : 'postgres-password' 
197-       }
198-       {
199-         name : 'ALERT_SMTP_FROM' 
200-         value : alertFrom 
201-       }
202-       {
203-         name : 'ALERT_SMTP_TO' 
204-         value : alertTo 
205-       }
206-       {
207-         name : 'ALERT_SMTP_HOST' 
208-         value : alertMailHost 
209-       }
210-       {
211-         name : 'ALERT_MAIL_PORT' 
212-         value : alertMailPort 
213-       }
214-       {
215-         name : 'ALERT_SMTP_PASSWORD' 
216-         secretRef : 'alert-smtp-password' 
217-       }
208+     containers : [
218209      {
219-         name : 'ALERT_FAIL_COUNT' 
220-         value : '${alertFailCount }' 
210+         image : '${imageRepo }/nanomon-runner:${imageTag }' 
211+         name : 'nanomon-runner' 
212+         resources : { cpu : '0.25' , memory : '0.5Gi'  }
213+ 
214+         env : [
215+           {
216+             name : 'POSTGRES_DSN' 
217+             value : postgresDSN  != ''  ? postgresDSN  : 'host=${database !.outputs .fqdn } dbname=nanomon user=nanomon' 
218+           }
219+           {
220+             name : 'POSTGRES_PASSWORD' 
221+             secretRef : 'postgres-password' 
222+           }
223+           {
224+             name : 'ALERT_SMTP_FROM' 
225+             value : alertFrom 
226+           }
227+           {
228+             name : 'ALERT_SMTP_TO' 
229+             value : alertTo 
230+           }
231+           {
232+             name : 'ALERT_SMTP_HOST' 
233+             value : alertMailHost 
234+           }
235+           {
236+             name : 'ALERT_MAIL_PORT' 
237+             value : alertMailPort 
238+           }
239+           {
240+             name : 'ALERT_SMTP_PASSWORD' 
241+             secretRef : 'alert-smtp-password' 
242+           }
243+           {
244+             name : 'ALERT_FAIL_COUNT' 
245+             value : '${alertFailCount }' 
246+           }
247+         ]
221248      }
222249    ]
223250  }
224251}
225252
226253output  appURL  string  = 'https://${frontend .outputs .fqdn }/' 
227- output  dbHost  string  = postgresDSN  != ''  ? 'Unknown'  : database !.outputs .host 
254+ output  dbHost  string  = postgresDSN  != ''  ? 'Unknown'  : database !.outputs .fqdn 
228255output  resGroup  string  = resGroup .name 
229256output  postgresResName  string  = postgresDSN  != ''  ? 'Unknown'  : database !.outputs .name 
0 commit comments