From 2b50c06ee663b01bb84b4ee2517056799697e7ba Mon Sep 17 00:00:00 2001
From: Atharv Kirtikar <42913997+wi0lono@users.noreply.github.com>
Date: Mon, 29 Jul 2024 14:33:10 +0530
Subject: [PATCH 1/4] Added pwr-studio-hld.drawio
---
docs/assets/pwr-studio-hld.drawio | 85 +++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
create mode 100644 docs/assets/pwr-studio-hld.drawio
diff --git a/docs/assets/pwr-studio-hld.drawio b/docs/assets/pwr-studio-hld.drawio
new file mode 100644
index 0000000..53ba6bb
--- /dev/null
+++ b/docs/assets/pwr-studio-hld.drawio
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 48774840973d4c9c351f0404e24976470f332b85 Mon Sep 17 00:00:00 2001
From: Atharv Kirtikar
Date: Tue, 30 Jul 2024 19:33:20 +0530
Subject: [PATCH 2/4] Trying out bicep (not working yet)
---
.gitignore | 2 +
deployments/bicep/README.md | 5 +
deployments/bicep/main.bicep | 75 +++++++++++
deployments/bicep/modules/engine.bicep | 121 ++++++++++++++++++
deployments/bicep/modules/eventhub.bicep | 65 ++++++++++
deployments/bicep/modules/postgres.bicep | 85 +++++++++++++
deployments/bicep/modules/server.bicep | 152 +++++++++++++++++++++++
deployments/bicep/modules/storage.bicep | 110 ++++++++++++++++
8 files changed, 615 insertions(+)
create mode 100644 deployments/bicep/README.md
create mode 100644 deployments/bicep/main.bicep
create mode 100644 deployments/bicep/modules/engine.bicep
create mode 100644 deployments/bicep/modules/eventhub.bicep
create mode 100644 deployments/bicep/modules/postgres.bicep
create mode 100644 deployments/bicep/modules/server.bicep
create mode 100644 deployments/bicep/modules/storage.bicep
diff --git a/.gitignore b/.gitignore
index 0712879..cb961fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -171,3 +171,5 @@ studio/dist
.env-dev
.env-prod
dump.sql
+mainTemplate.parameters.json
+*.bicepparam
\ No newline at end of file
diff --git a/deployments/bicep/README.md b/deployments/bicep/README.md
new file mode 100644
index 0000000..f210526
--- /dev/null
+++ b/deployments/bicep/README.md
@@ -0,0 +1,5 @@
+```bash
+az deployment group create --name ExampleDeployment --resource-group jb-studio-test --parameters storage.bicepparam
+
+az deployment group create --resource-group jb-studio-test --template-file ./main.bicep --parameters main.bicepparam
+```
\ No newline at end of file
diff --git a/deployments/bicep/main.bicep b/deployments/bicep/main.bicep
new file mode 100644
index 0000000..285a8d0
--- /dev/null
+++ b/deployments/bicep/main.bicep
@@ -0,0 +1,75 @@
+// create bicep version of the stuff above
+
+param resourceNamePrefix string
+param location string
+param availabilityZones array
+param postgresAdminUser string
+
+@secure()
+param postgresAdminPassword string
+
+param postgresDatabaseName string
+param cpu string = '0.5'
+param memory string = '1Gi'
+
+var eventhubNamespace = '${resourceNamePrefix}-eventhub-namespace'
+var publicIpName = '${resourceNamePrefix}-public-ip'
+var containerAppEnvironmentName = '${resourceNamePrefix}-container-app-environment'
+var containerAppName = '${resourceNamePrefix}-container-app'
+var presetEnvironmentVariables = []
+
+
+// deploy the files ./eventhub.bicep and postgres.bicep
+
+module eventhub './modules/eventhub.bicep' = {
+ name: '${resourceNamePrefix}-eventhub'
+ params: {
+ eventHubNamespace: eventhubNamespace
+ location: location
+ }
+}
+
+module postgres './modules/postgres.bicep' = {
+ name: '${resourceNamePrefix}-postgres'
+ params: {
+ resourceNamePrefix: resourceNamePrefix
+ location: location
+ postgresAdminUser: postgresAdminUser
+ postgresAdminPassword: postgresAdminPassword
+ postgresDatabaseName: postgresDatabaseName
+ }
+}
+
+module storage './modules/storage.bicep' = {
+ name: '${resourceNamePrefix}-storage'
+ params: {
+ location: location
+ resourceNamePrefix: resourceNamePrefix
+ }
+}
+
+
+// deploy the files ./server.bicep and ./engine.bicep
+
+module server './modules/server.bicep' = {
+ name: '${resourceNamePrefix}-server'
+ params: {
+ location: location
+ resourceNamePrefix: resourceNamePrefix
+ postgresServerName: postgres.outputs.postgresqlServerIP
+ eventhubNamespace: eventhub.outputs.kafkaBroker
+ }
+}
+
+module engine './modules/engine.bicep' = {
+ name: '${resourceNamePrefix}-engine'
+ params: {
+ location: location
+ resourceNamePrefix: resourceNamePrefix
+ postgresServerName: postgres.outputs.postgresqlServerIP
+ eventhubNamespace: eventhub.outputs.kafkaBroker
+ }
+}
+
+output eventhubNamespace string = eventhub.outputs.kafkaBroker
+output postgresqlServerName string = postgres.outputs.postgresqlServerIP
diff --git a/deployments/bicep/modules/engine.bicep b/deployments/bicep/modules/engine.bicep
new file mode 100644
index 0000000..5bf593e
--- /dev/null
+++ b/deployments/bicep/modules/engine.bicep
@@ -0,0 +1,121 @@
+param availabilityZones array
+param location string
+param containerName string
+param imageName string
+
+@allowed([
+ 'Linux'
+ 'Windows'
+])
+param osType string
+param numberCpuCores string
+param memory string
+
+@allowed([
+ 'OnFailure'
+ 'Always'
+ 'Never'
+])
+param restartPolicy string
+
+@allowed([
+ 'Standard'
+ 'Confidential'
+])
+param sku string
+param imageRegistryLoginServer string
+param imageUsername string
+
+@secure()
+param imagePassword string
+param KAFKA_BROKER string
+param KAFKA_USE_SASL string
+param KAFKA_CONSUMER_USERNAME string
+
+@secure()
+param KAFKA_CONSUMER_PASSWORD string
+param KAFKA_ENGINE_TOPIC string
+
+@secure()
+param AZURE_OPENAI_API_KEY string
+param AZURE_OPENAI_API_VERSION string
+param AZURE_OPENAI_ENDPOINT string
+param FAST_MODEL string
+param SLOW_MODEL string
+param ports array
+
+resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-preview' = {
+ location: location
+ name: containerName
+ zones: availabilityZones
+ properties: {
+ containers: [
+ {
+ name: containerName
+ properties: {
+ image: imageName
+ resources: {
+ requests: {
+ cpu: int(numberCpuCores)
+ memoryInGB: json(memory)
+ }
+ }
+ environmentVariables: [
+ {
+ name: 'KAFKA_BROKER'
+ value: KAFKA_BROKER
+ }
+ {
+ name: 'KAFKA_USE_SASL'
+ value: KAFKA_USE_SASL
+ }
+ {
+ name: 'KAFKA_CONSUMER_USERNAME'
+ value: KAFKA_CONSUMER_USERNAME
+ }
+ {
+ name: 'KAFKA_CONSUMER_PASSWORD'
+ secureValue: KAFKA_CONSUMER_PASSWORD
+ }
+ {
+ name: 'KAFKA_ENGINE_TOPIC'
+ value: KAFKA_ENGINE_TOPIC
+ }
+ {
+ name: 'AZURE_OPENAI_API_KEY'
+ value: AZURE_OPENAI_API_KEY
+ }
+ {
+ name: 'AZURE_OPENAI_API_VERSION'
+ value: AZURE_OPENAI_API_VERSION
+ }
+ {
+ name: 'AZURE_OPENAI_ENDPOINT'
+ value: AZURE_OPENAI_ENDPOINT
+ }
+ {
+ name: 'FAST_MODEL'
+ value: FAST_MODEL
+ }
+ {
+ name: 'SLOW_MODEL'
+ value: SLOW_MODEL
+ }
+ ]
+ ports: ports
+ }
+ }
+ ]
+ restartPolicy: restartPolicy
+ osType: osType
+ sku: sku
+ imageRegistryCredentials: [
+ {
+ server: imageRegistryLoginServer
+ username: imageUsername
+ password: imagePassword
+ }
+ ]
+ }
+ tags: {}
+}
diff --git a/deployments/bicep/modules/eventhub.bicep b/deployments/bicep/modules/eventhub.bicep
new file mode 100644
index 0000000..9ca866f
--- /dev/null
+++ b/deployments/bicep/modules/eventhub.bicep
@@ -0,0 +1,65 @@
+@description('The name of the Event Hub namespace.')
+param eventHubNamespace string
+
+@description('The location for the resources.')
+param location string
+
+resource eventhubNamespace_resource 'Microsoft.EventHub/namespaces@2024-01-01' = {
+ name: eventHubNamespace
+ location: location
+ sku: {
+ name: 'Standard'
+ tier: 'Standard'
+ capacity: 1
+ }
+ properties: {
+ minimumTlsVersion: '1.2'
+ publicNetworkAccess: 'Enabled'
+ disableLocalAuth: false
+ zoneRedundant: true
+ isAutoInflateEnabled: true
+ maximumThroughputUnits: 5
+ kafkaEnabled: true
+ }
+}
+
+resource eventhubNamespace_sendlisten 'Microsoft.EventHub/namespaces/authorizationrules@2024-01-01' = {
+ parent: eventhubNamespace_resource
+ name: 'sendlisten'
+ properties: {
+ rights: [
+ 'Send'
+ 'Listen'
+ ]
+ }
+}
+
+resource eventhubNamespace_pwr 'Microsoft.EventHub/namespaces/eventhubs@2024-01-01' = {
+ parent: eventhubNamespace_resource
+ name: 'pwr'
+ properties: {
+ retentionDescription: {
+ cleanupPolicy: 'Delete'
+ retentionTimeInHours: 1
+ }
+ messageRetentionInDays: 1
+ partitionCount: 3
+ status: 'Active'
+ }
+}
+
+resource eventhubNamespace_pwr_Default 'Microsoft.EventHub/namespaces/eventhubs/consumergroups@2024-01-01' = {
+ parent: eventhubNamespace_pwr
+ name: '$Default'
+ properties: {}
+}
+
+resource eventhubNamespace_pwr_cooler_group_id 'Microsoft.EventHub/namespaces/eventhubs/consumergroups@2024-01-01' = {
+ parent: eventhubNamespace_pwr
+ name: 'cooler_group_id'
+ properties: {}
+}
+
+output kafkaConnectionUsername string = '$ConnectionString'
+output kafkaConnectionPassword string = eventhubNamespace_sendlisten.listKeys().primaryConnectionString
+output kafkaBroker string = '${eventHubNamespace}.servicebus.windows.net:9093'
diff --git a/deployments/bicep/modules/postgres.bicep b/deployments/bicep/modules/postgres.bicep
new file mode 100644
index 0000000..c162622
--- /dev/null
+++ b/deployments/bicep/modules/postgres.bicep
@@ -0,0 +1,85 @@
+@description('The prefix used by all resources created by this template.')
+param resourceNamePrefix string
+
+@description('The location for the resources.')
+param location string
+
+@description('The administrator username for the PostgreSQL Flexible Server.')
+param postgresAdminUser string
+
+@description('The administrator password for the PostgreSQL Flexible Server.')
+@secure()
+param postgresAdminPassword string
+
+@description('The name of the database to create in the PostgreSQL Flexible Server.')
+param postgresDatabaseName string
+
+var postgresqlServerName = '${resourceNamePrefix}-postgresql-server'
+
+resource postgresqlServer 'Microsoft.DBforPostgreSQL/flexibleServers@2023-12-01-preview' = {
+ name: postgresqlServerName
+ location: location
+ properties: {
+ replica: {
+ role: 'Primary'
+ }
+ storage: {
+ iops: 120
+ tier: 'P4'
+ storageSizeGB: 32
+ autoGrow: 'Enabled'
+ }
+ network: {
+ publicNetworkAccess: 'Enabled'
+ }
+ dataEncryption: {
+ type: 'SystemManaged'
+ }
+ authConfig: {
+ activeDirectoryAuth: 'Disabled'
+ passwordAuth: 'Enabled'
+ }
+ version: '16'
+ administratorLogin: postgresAdminUser
+ administratorLoginPassword: postgresAdminPassword
+ availabilityZone: '1'
+ backup: {
+ backupRetentionDays: 7
+ geoRedundantBackup: 'Disabled'
+ }
+ highAvailability: {
+ mode: 'Disabled'
+ }
+ maintenanceWindow: {
+ customWindow: 'Disabled'
+ dayOfWeek: 0
+ startHour: 0
+ startMinute: 0
+ }
+ replicationRole: 'Primary'
+ }
+ sku: {
+ name: 'Standard_D2ds_v4'
+ tier: 'GeneralPurpose'
+ }
+}
+
+resource postgresAllowAllAzureIPs 'Microsoft.DBforPostgreSQL/flexibleServers/firewallRules@2023-12-01-preview' = {
+ parent: postgresqlServer
+ name: 'AllowAllAzureIPs'
+ properties: {
+ startIpAddress: '0.0.0.0'
+ endIpAddress: '0.0.0.0'
+ }
+}
+
+resource postgresqlServerName_postgresDatabase 'Microsoft.DBforPostgreSQL/flexibleServers/databases@2023-12-01-preview' = {
+ parent: postgresqlServer
+ name: postgresDatabaseName
+ properties: {
+ charset: 'UTF8'
+ collation: 'en_US.utf8'
+ }
+}
+
+output postgresqlServerIP string = postgresqlServer.properties.fullyQualifiedDomainName
diff --git a/deployments/bicep/modules/server.bicep b/deployments/bicep/modules/server.bicep
new file mode 100644
index 0000000..26c8ebd
--- /dev/null
+++ b/deployments/bicep/modules/server.bicep
@@ -0,0 +1,152 @@
+param availabilityZones array
+param location string
+param containerName string
+param imageName string
+
+@allowed([
+ 'Linux'
+ 'Windows'
+])
+param osType string
+param numberCpuCores string
+param memory string
+
+@allowed([
+ 'OnFailure'
+ 'Always'
+ 'Never'
+])
+param restartPolicy string
+
+@allowed([
+ 'Standard'
+ 'Confidential'
+])
+param sku string
+param imageRegistryLoginServer string
+param imageUsername string
+
+@secure()
+param imagePassword string
+param SERVER_HOST string
+param dbConnectionString string
+param AAD_APP_CLIENT_ID string
+param AAD_APP_TENANT_ID string
+param ISSUER string
+param KAFKA_BROKER string
+param KAFKA_USE_SASL string
+param KAFKA_ENGINE_TOPIC string
+param KAFKA_PRODUCER_USERNAME string
+
+@secure()
+param KAFKA_PRODUCER_PASSWORD string
+param KAFKA_CONSUMER_USERNAME string
+
+@secure()
+param KAFKA_CONSUMER_PASSWORD string
+param ipAddressType string
+param ports array
+
+resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-preview' = {
+ location: location
+ name: containerName
+ zones: availabilityZones
+ properties: {
+ containers: [
+ {
+ name: containerName
+ properties: {
+ image: imageName
+ resources: {
+ requests: {
+ cpu: int(numberCpuCores)
+ memoryInGB: json(memory)
+ }
+ }
+ environmentVariables: [
+ {
+ name: 'SERVER_HOST'
+ value: SERVER_HOST
+ }
+ {
+ name: 'DB_CONNECTION_STRING'
+ value: dbConnectionString
+ }
+ {
+ name: 'AAD_APP_CLIENT_ID'
+ value: AAD_APP_CLIENT_ID
+ }
+ {
+ name: 'AAD_APP_TENANT_ID'
+ value: AAD_APP_TENANT_ID
+ }
+ {
+ name: 'ISSUER'
+ value: ISSUER
+ }
+ {
+ name: 'KAFKA_BROKER'
+ value: KAFKA_BROKER
+ }
+ {
+ name: 'KAFKA_USE_SASL'
+ value: KAFKA_USE_SASL
+ }
+ {
+ name: 'KAFKA_ENGINE_TOPIC'
+ value: KAFKA_ENGINE_TOPIC
+ }
+ {
+ name: 'KAFKA_PRODUCER_USERNAME'
+ value: KAFKA_PRODUCER_USERNAME
+ }
+ {
+ name: 'KAFKA_PRODUCER_PASSWORD'
+ secureValue: KAFKA_PRODUCER_PASSWORD
+ }
+ {
+ name: 'KAFKA_CONSUMER_USERNAME'
+ value: KAFKA_CONSUMER_USERNAME
+ }
+ {
+ name: 'KAFKA_CONSUMER_PASSWORD'
+ secureValue: KAFKA_CONSUMER_PASSWORD
+ }
+ ]
+ ports: ports
+ command: [
+ 'uvicorn'
+ 'app.main:app'
+ '--workers'
+ '1'
+ '--host'
+ '0.0.0.0'
+ '--port'
+ '80'
+ ]
+ }
+ }
+ ]
+ restartPolicy: restartPolicy
+ osType: osType
+ sku: sku
+ imageRegistryCredentials: [
+ {
+ server: imageRegistryLoginServer
+ username: imageUsername
+ password: imagePassword
+ }
+ ]
+ ipAddress: {
+ type: ipAddressType
+ ports: ports
+ }
+ subnetIds: [
+ {
+ // generate dynamically instead of hardcoding
+ id: 'sss'
+ }
+ ]
+ }
+ tags: {}
+}
diff --git a/deployments/bicep/modules/storage.bicep b/deployments/bicep/modules/storage.bicep
new file mode 100644
index 0000000..bd43e04
--- /dev/null
+++ b/deployments/bicep/modules/storage.bicep
@@ -0,0 +1,110 @@
+@description('The prefix used by all resources created by this template.')
+param resourceNamePrefix string
+
+@description('The location for the resources.')
+param location string
+
+var storageAccountName = '${resourceNamePrefix}storageaccount'
+var storageContainerName = '${resourceNamePrefix}-storage-container'
+
+resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
+ name: storageAccountName
+ location: location
+ sku: {
+ name: 'Standard_LRS'
+ }
+ kind: 'StorageV2'
+ properties: {
+ dnsEndpointType: 'Standard'
+ defaultToOAuthAuthentication: false
+ publicNetworkAccess: 'Enabled'
+ allowCrossTenantReplication: false
+ minimumTlsVersion: 'TLS1_2'
+ allowBlobPublicAccess: true
+ allowSharedKeyAccess: true
+ networkAcls: {
+ bypass: 'AzureServices'
+ virtualNetworkRules: []
+ ipRules: []
+ defaultAction: 'Allow'
+ }
+ supportsHttpsTrafficOnly: true
+ encryption: {
+ requireInfrastructureEncryption: false
+ services: {
+ file: {
+ keyType: 'Account'
+ enabled: true
+ }
+ blob: {
+ keyType: 'Account'
+ enabled: true
+ }
+ }
+ keySource: 'Microsoft.Storage'
+ }
+ accessTier: 'Hot'
+ }
+}
+
+resource storageAccountName_default 'Microsoft.Storage/storageAccounts/blobServices@2023-05-01' = {
+ parent: storageAccount
+ name: 'default'
+ sku: {
+ name: 'Standard_LRS'
+ }
+ properties: {
+ changeFeed: {
+ enabled: false
+ }
+ restorePolicy: {
+ enabled: false
+ }
+ containerDeleteRetentionPolicy: {
+ enabled: true
+ days: 7
+ }
+ cors: {
+ corsRules: []
+ }
+ deleteRetentionPolicy: {
+ allowPermanentDelete: false
+ enabled: true
+ days: 7
+ }
+ isVersioningEnabled: false
+ }
+}
+
+resource storageAccountName_default_storageContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = {
+ parent: storageAccountName_default
+ name: storageContainerName
+ properties: {
+ immutableStorageWithVersioning: {
+ enabled: false
+ }
+ defaultEncryptionScope: '$account-encryption-key'
+ denyEncryptionScopeOverride: false
+ publicAccess: 'None'
+ }
+}
+
+resource storageAccountName_default_web 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = {
+ parent: storageAccountName_default
+ name: '$web'
+ properties: {
+ immutableStorageWithVersioning: {
+ enabled: false
+ }
+ defaultEncryptionScope: '$account-encryption-key'
+ denyEncryptionScopeOverride: false
+ publicAccess: 'Container'
+ }
+ dependsOn: [
+ storageAccountName_default_storageContainer
+ ]
+}
+
+output AZURE_STORAGE_ACCOUNT_URL string = storageAccount.properties.primaryEndpoints.blob
+output AZURE_STORAGE_ACCOUNT_KEY string = listKeys(storageAccountName, '2023-05-01').keys[0].value
+output AZURE_STORAGE_CONTAINER string = storageContainerName
From a73d2eb73455f7f0937b127cddb38e2c43a4106f Mon Sep 17 00:00:00 2001
From: Atharv Kirtikar
Date: Thu, 1 Aug 2024 16:12:15 +0530
Subject: [PATCH 3/4] 10 percent
---
.gitignore | 2 +-
deployments/bicep/README.md | 2 +-
deployments/bicep/main.bicep | 92 +++++++++++++++----
.../modules/{ => containers}/engine.bicep | 46 +++-------
.../modules/{ => containers}/server.bicep | 68 ++++----------
deployments/bicep/modules/eventhub.bicep | 2 +-
deployments/bicep/modules/storage.bicep | 3 -
deployments/bicep/modules/vnet.bicep | 47 ++++++++++
8 files changed, 156 insertions(+), 106 deletions(-)
rename deployments/bicep/modules/{ => containers}/engine.bicep (79%)
rename deployments/bicep/modules/{ => containers}/server.bicep (69%)
create mode 100644 deployments/bicep/modules/vnet.bicep
diff --git a/.gitignore b/.gitignore
index cb961fc..56d9d2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -171,5 +171,5 @@ studio/dist
.env-dev
.env-prod
dump.sql
-mainTemplate.parameters.json
+*.parameters.json
*.bicepparam
\ No newline at end of file
diff --git a/deployments/bicep/README.md b/deployments/bicep/README.md
index f210526..519a325 100644
--- a/deployments/bicep/README.md
+++ b/deployments/bicep/README.md
@@ -1,5 +1,5 @@
```bash
az deployment group create --name ExampleDeployment --resource-group jb-studio-test --parameters storage.bicepparam
-az deployment group create --resource-group jb-studio-test --template-file ./main.bicep --parameters main.bicepparam
+az deployment group create --resource-group jbstudiotest --template-file ./main.bicep --parameters main.bicepparam
```
\ No newline at end of file
diff --git a/deployments/bicep/main.bicep b/deployments/bicep/main.bicep
index 285a8d0..043f706 100644
--- a/deployments/bicep/main.bicep
+++ b/deployments/bicep/main.bicep
@@ -2,7 +2,6 @@
param resourceNamePrefix string
param location string
-param availabilityZones array
param postgresAdminUser string
@secure()
@@ -12,19 +11,42 @@ param postgresDatabaseName string
param cpu string = '0.5'
param memory string = '1Gi'
-var eventhubNamespace = '${resourceNamePrefix}-eventhub-namespace'
-var publicIpName = '${resourceNamePrefix}-public-ip'
-var containerAppEnvironmentName = '${resourceNamePrefix}-container-app-environment'
-var containerAppName = '${resourceNamePrefix}-container-app'
-var presetEnvironmentVariables = []
+@secure()
+param AZURE_OPENAI_API_KEY string
+param AZURE_OPENAI_API_VERSION string
+param AZURE_OPENAI_ENDPOINT string
+param FAST_MODEL string = 'gpt-4-turbo'
+param SLOW_MODEL string = 'gpt-4-turbo'
+
+param pwrEngineImageName string
+param pwrServerImageName string
+@secure()
+param imagePassword string
+param imageRegistryLoginServer string
+param imageUsername string
+
+param AAD_APP_CLIENT_ID string
+param AAD_APP_TENANT_ID string
+param ISSUER string
+
+param SERVER_HOST string
+
+// deploy ./vnet.bicep
+
+module vnet './modules/vnet.bicep' = {
+ name: '${resourceNamePrefix}-vnet'
+ params: {
+ vnetName: '${resourceNamePrefix}-vnet'
+ }
+}
// deploy the files ./eventhub.bicep and postgres.bicep
module eventhub './modules/eventhub.bicep' = {
name: '${resourceNamePrefix}-eventhub'
params: {
- eventHubNamespace: eventhubNamespace
+ eventHubNamespace: '${resourceNamePrefix}-eventhub-namespace'
location: location
}
}
@@ -51,25 +73,61 @@ module storage './modules/storage.bicep' = {
// deploy the files ./server.bicep and ./engine.bicep
-module server './modules/server.bicep' = {
- name: '${resourceNamePrefix}-server'
+module engine './modules/containers/engine.bicep' = {
+ name: '${resourceNamePrefix}-engine'
params: {
location: location
- resourceNamePrefix: resourceNamePrefix
- postgresServerName: postgres.outputs.postgresqlServerIP
- eventhubNamespace: eventhub.outputs.kafkaBroker
+ AZURE_OPENAI_API_KEY: AZURE_OPENAI_API_KEY
+ AZURE_OPENAI_API_VERSION: AZURE_OPENAI_API_VERSION
+ AZURE_OPENAI_ENDPOINT: AZURE_OPENAI_ENDPOINT
+ FAST_MODEL: FAST_MODEL
+ SLOW_MODEL: SLOW_MODEL
+
+ containerName: '${resourceNamePrefix}-pwr-engine'
+ imageName: pwrEngineImageName
+ imagePassword: imagePassword
+ imageRegistryLoginServer: imageRegistryLoginServer
+ imageUsername: imageUsername
+ KAFKA_BROKER: eventhub.outputs.kafkaBroker
+ KAFKA_CONSUMER_PASSWORD: eventhub.outputs.kafkaConnectionPassword
+ KAFKA_CONSUMER_USERNAME: eventhub.outputs.kafkaConnectionUsername
+ memory: memory
+ numberCpuCores: cpu
+ subnetId: vnet.outputs.defaultSubnetId
}
}
-module engine './modules/engine.bicep' = {
- name: '${resourceNamePrefix}-engine'
+
+
+module server './modules/containers/server.bicep' = {
+ name: '${resourceNamePrefix}-server'
params: {
location: location
- resourceNamePrefix: resourceNamePrefix
- postgresServerName: postgres.outputs.postgresqlServerIP
- eventhubNamespace: eventhub.outputs.kafkaBroker
+
+ containerName: '${resourceNamePrefix}-pwr-server'
+ AAD_APP_CLIENT_ID: AAD_APP_CLIENT_ID
+ AAD_APP_TENANT_ID: AAD_APP_TENANT_ID
+ ISSUER: ISSUER
+ // construct a full db string using the postgress params and the output server ip
+ dbConnectionString: 'postgresql://${postgresAdminUser}:${postgresAdminPassword}@${postgres.outputs.postgresqlServerIP}:5432/${postgresDatabaseName}'
+ SERVER_HOST: SERVER_HOST
+
+ imageName: pwrServerImageName
+ imagePassword: imagePassword
+ imageRegistryLoginServer: imageRegistryLoginServer
+ imageUsername: imageUsername
+ KAFKA_BROKER: eventhub.outputs.kafkaBroker
+ KAFKA_PRODUCER_PASSWORD: eventhub.outputs.kafkaConnectionPassword
+ KAFKA_PRODUCER_USERNAME: eventhub.outputs.kafkaConnectionUsername
+ memory: memory
+ numberCpuCores: cpu
+ subnetId: vnet.outputs.defaultSubnetId
+
}
}
+
+
output eventhubNamespace string = eventhub.outputs.kafkaBroker
output postgresqlServerName string = postgres.outputs.postgresqlServerIP
+
diff --git a/deployments/bicep/modules/engine.bicep b/deployments/bicep/modules/containers/engine.bicep
similarity index 79%
rename from deployments/bicep/modules/engine.bicep
rename to deployments/bicep/modules/containers/engine.bicep
index 5bf593e..cb64a72 100644
--- a/deployments/bicep/modules/engine.bicep
+++ b/deployments/bicep/modules/containers/engine.bicep
@@ -1,53 +1,32 @@
-param availabilityZones array
param location string
param containerName string
-param imageName string
+param subnetId string
-@allowed([
- 'Linux'
- 'Windows'
-])
-param osType string
param numberCpuCores string
param memory string
-@allowed([
- 'OnFailure'
- 'Always'
- 'Never'
-])
-param restartPolicy string
-
-@allowed([
- 'Standard'
- 'Confidential'
-])
-param sku string
param imageRegistryLoginServer string
param imageUsername string
-
@secure()
param imagePassword string
+param imageName string
+
param KAFKA_BROKER string
-param KAFKA_USE_SASL string
param KAFKA_CONSUMER_USERNAME string
@secure()
param KAFKA_CONSUMER_PASSWORD string
-param KAFKA_ENGINE_TOPIC string
@secure()
param AZURE_OPENAI_API_KEY string
param AZURE_OPENAI_API_VERSION string
param AZURE_OPENAI_ENDPOINT string
-param FAST_MODEL string
-param SLOW_MODEL string
-param ports array
+param FAST_MODEL string = 'gpt-4-turbo'
+param SLOW_MODEL string = 'gpt-4-turbo'
resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-preview' = {
location: location
name: containerName
- zones: availabilityZones
properties: {
containers: [
{
@@ -67,7 +46,7 @@ resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-previ
}
{
name: 'KAFKA_USE_SASL'
- value: KAFKA_USE_SASL
+ value: 'true'
}
{
name: 'KAFKA_CONSUMER_USERNAME'
@@ -79,7 +58,7 @@ resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-previ
}
{
name: 'KAFKA_ENGINE_TOPIC'
- value: KAFKA_ENGINE_TOPIC
+ value: 'pwr_engine'
}
{
name: 'AZURE_OPENAI_API_KEY'
@@ -102,13 +81,13 @@ resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-previ
value: SLOW_MODEL
}
]
- ports: ports
+ ports: [{port: 80, protocol: 'TCP'}]
}
}
]
- restartPolicy: restartPolicy
- osType: osType
- sku: sku
+ restartPolicy: 'OnFailure'
+ osType: 'Linux'
+ sku: 'Standard'
imageRegistryCredentials: [
{
server: imageRegistryLoginServer
@@ -116,6 +95,9 @@ resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-previ
password: imagePassword
}
]
+ subnetIds: [
+ {id: subnetId}
+ ]
}
tags: {}
}
diff --git a/deployments/bicep/modules/server.bicep b/deployments/bicep/modules/containers/server.bicep
similarity index 69%
rename from deployments/bicep/modules/server.bicep
rename to deployments/bicep/modules/containers/server.bicep
index 26c8ebd..c74c5be 100644
--- a/deployments/bicep/modules/server.bicep
+++ b/deployments/bicep/modules/containers/server.bicep
@@ -1,56 +1,32 @@
-param availabilityZones array
param location string
param containerName string
-param imageName string
+param subnetId string
-@allowed([
- 'Linux'
- 'Windows'
-])
-param osType string
param numberCpuCores string
param memory string
-@allowed([
- 'OnFailure'
- 'Always'
- 'Never'
-])
-param restartPolicy string
-
-@allowed([
- 'Standard'
- 'Confidential'
-])
-param sku string
param imageRegistryLoginServer string
+param imageName string
param imageUsername string
-
@secure()
param imagePassword string
+
param SERVER_HOST string
param dbConnectionString string
+
param AAD_APP_CLIENT_ID string
param AAD_APP_TENANT_ID string
param ISSUER string
+
param KAFKA_BROKER string
-param KAFKA_USE_SASL string
-param KAFKA_ENGINE_TOPIC string
param KAFKA_PRODUCER_USERNAME string
-
@secure()
param KAFKA_PRODUCER_PASSWORD string
-param KAFKA_CONSUMER_USERNAME string
-@secure()
-param KAFKA_CONSUMER_PASSWORD string
-param ipAddressType string
-param ports array
resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-preview' = {
location: location
name: containerName
- zones: availabilityZones
properties: {
containers: [
{
@@ -90,11 +66,11 @@ resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-previ
}
{
name: 'KAFKA_USE_SASL'
- value: KAFKA_USE_SASL
+ value: 'true'
}
{
name: 'KAFKA_ENGINE_TOPIC'
- value: KAFKA_ENGINE_TOPIC
+ value: 'pwr_engine'
}
{
name: 'KAFKA_PRODUCER_USERNAME'
@@ -104,16 +80,7 @@ resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-previ
name: 'KAFKA_PRODUCER_PASSWORD'
secureValue: KAFKA_PRODUCER_PASSWORD
}
- {
- name: 'KAFKA_CONSUMER_USERNAME'
- value: KAFKA_CONSUMER_USERNAME
- }
- {
- name: 'KAFKA_CONSUMER_PASSWORD'
- secureValue: KAFKA_CONSUMER_PASSWORD
- }
]
- ports: ports
command: [
'uvicorn'
'app.main:app'
@@ -124,12 +91,13 @@ resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-previ
'--port'
'80'
]
+ ports: [{port: 80, protocol: 'TCP'}, {port: 3000, protocol: 'TCP'}]
}
}
]
- restartPolicy: restartPolicy
- osType: osType
- sku: sku
+ restartPolicy: 'OnFailure'
+ osType: 'Linux'
+ sku: 'Standard'
imageRegistryCredentials: [
{
server: imageRegistryLoginServer
@@ -137,16 +105,14 @@ resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-previ
password: imagePassword
}
]
- ipAddress: {
- type: ipAddressType
- ports: ports
- }
subnetIds: [
- {
- // generate dynamically instead of hardcoding
- id: 'sss'
- }
+ {id: subnetId}
]
}
tags: {}
}
+
+
+// output the private IP adress assigned to the container group from the subnet
+
+output containerIP string = container.properties.ipAddress.ip
diff --git a/deployments/bicep/modules/eventhub.bicep b/deployments/bicep/modules/eventhub.bicep
index 9ca866f..ac2ec0d 100644
--- a/deployments/bicep/modules/eventhub.bicep
+++ b/deployments/bicep/modules/eventhub.bicep
@@ -36,7 +36,7 @@ resource eventhubNamespace_sendlisten 'Microsoft.EventHub/namespaces/authorizati
resource eventhubNamespace_pwr 'Microsoft.EventHub/namespaces/eventhubs@2024-01-01' = {
parent: eventhubNamespace_resource
- name: 'pwr'
+ name: 'pwr_engine'
properties: {
retentionDescription: {
cleanupPolicy: 'Delete'
diff --git a/deployments/bicep/modules/storage.bicep b/deployments/bicep/modules/storage.bicep
index bd43e04..db6f0ed 100644
--- a/deployments/bicep/modules/storage.bicep
+++ b/deployments/bicep/modules/storage.bicep
@@ -50,9 +50,6 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
resource storageAccountName_default 'Microsoft.Storage/storageAccounts/blobServices@2023-05-01' = {
parent: storageAccount
name: 'default'
- sku: {
- name: 'Standard_LRS'
- }
properties: {
changeFeed: {
enabled: false
diff --git a/deployments/bicep/modules/vnet.bicep b/deployments/bicep/modules/vnet.bicep
new file mode 100644
index 0000000..ad1f0ce
--- /dev/null
+++ b/deployments/bicep/modules/vnet.bicep
@@ -0,0 +1,47 @@
+@description('The name of the virtual network.')
+param vnetName string
+
+
+// create a virtual network with two subnets
+resource pwrStudioVnet 'Microsoft.Network/virtualNetworks@2023-11-01' = {
+ name: vnetName
+ location: 'centralindia'
+ properties: {
+ addressSpace: {
+ addressPrefixes: [
+ '10.0.0.0/16'
+ ]
+ }
+ subnets: [
+ {
+ name: 'default'
+ properties: {
+ addressPrefix: '10.0.0.0/24'
+ delegations: [
+ {
+ name: 'Microsoft.ContainerInstance/containerGroups'
+ properties: {
+ serviceName: 'Microsoft.ContainerInstance/containerGroups'
+ }
+ }
+ ]
+ }
+ }
+ {
+ name: 'gateway'
+ properties: {
+ addressPrefix: '10.0.1.0/24'
+ }
+ }
+ ]
+ }
+}
+
+
+// output the subnets as well as network info
+
+output defaultSubnetId string = pwrStudioVnet.properties.subnets[0].id
+output gatewaySubnetId string = pwrStudioVnet.properties.subnets[1].id
+
+// output network info too
+output vnetId string = pwrStudioVnet.id
From 2e1a1c968fe27833dffe2951fb348f3d1ad6bff2 Mon Sep 17 00:00:00 2001
From: Atharv Kirtikar
Date: Fri, 30 Aug 2024 19:52:46 +0530
Subject: [PATCH 4/4] Gateway not working yet
---
deployments/bicep/README.md | 2 +-
deployments/bicep/main.bicep | 29 +++-
.../bicep/modules/containers/engine.bicep | 4 -
deployments/bicep/modules/gateway.bicep | 162 ++++++++++++++++++
4 files changed, 191 insertions(+), 6 deletions(-)
create mode 100644 deployments/bicep/modules/gateway.bicep
diff --git a/deployments/bicep/README.md b/deployments/bicep/README.md
index 519a325..00f073f 100644
--- a/deployments/bicep/README.md
+++ b/deployments/bicep/README.md
@@ -1,5 +1,5 @@
```bash
az deployment group create --name ExampleDeployment --resource-group jb-studio-test --parameters storage.bicepparam
-az deployment group create --resource-group jbstudiotest --template-file ./main.bicep --parameters main.bicepparam
+az deployment group create --resource-group jbstudiotest1 --template-file ./main.bicep --parameters main.bicepparam
```
\ No newline at end of file
diff --git a/deployments/bicep/main.bicep b/deployments/bicep/main.bicep
index 043f706..7d37c7a 100644
--- a/deployments/bicep/main.bicep
+++ b/deployments/bicep/main.bicep
@@ -31,6 +31,11 @@ param ISSUER string
param SERVER_HOST string
+param keyVaultName string
+
+@description('The secret url for the certificate in Azure Key Vault.')
+@secure()
+param keyVaultSecretId string
// deploy ./vnet.bicep
@@ -71,6 +76,16 @@ module storage './modules/storage.bicep' = {
}
+// create a public ip that will later be used for a load balancer
+
+resource publicIp 'Microsoft.Network/publicIPAddresses@2020-11-01' = {
+ name: '${resourceNamePrefix}-public-ip'
+ location: location
+ properties: {
+ publicIPAllocationMethod: 'Dynamic'
+ }
+}
+
// deploy the files ./server.bicep and ./engine.bicep
module engine './modules/containers/engine.bicep' = {
@@ -93,7 +108,6 @@ module engine './modules/containers/engine.bicep' = {
KAFKA_CONSUMER_USERNAME: eventhub.outputs.kafkaConnectionUsername
memory: memory
numberCpuCores: cpu
- subnetId: vnet.outputs.defaultSubnetId
}
}
@@ -127,6 +141,19 @@ module server './modules/containers/server.bicep' = {
}
+// create a load balancer that will be used to route traffic to the containers
+// module gateway './modules/gateway.bicep' = {
+// name: '${resourceNamePrefix}-gateway'
+// params: {
+// resourceNamePrefix: resourceNamePrefix
+// location: location
+// subnetId: vnet.outputs.gatewaySubnetId
+// publicIpId: publicIp.id
+// backendIPAddress: server.outputs.containerIP
+// keyVaultName: keyVaultName
+// keyVaultSecretId: keyVaultSecretId
+// }
+// }
output eventhubNamespace string = eventhub.outputs.kafkaBroker
output postgresqlServerName string = postgres.outputs.postgresqlServerIP
diff --git a/deployments/bicep/modules/containers/engine.bicep b/deployments/bicep/modules/containers/engine.bicep
index cb64a72..11b725e 100644
--- a/deployments/bicep/modules/containers/engine.bicep
+++ b/deployments/bicep/modules/containers/engine.bicep
@@ -1,6 +1,5 @@
param location string
param containerName string
-param subnetId string
param numberCpuCores string
param memory string
@@ -95,9 +94,6 @@ resource container 'Microsoft.ContainerInstance/containerGroups@2022-10-01-previ
password: imagePassword
}
]
- subnetIds: [
- {id: subnetId}
- ]
}
tags: {}
}
diff --git a/deployments/bicep/modules/gateway.bicep b/deployments/bicep/modules/gateway.bicep
new file mode 100644
index 0000000..494cf10
--- /dev/null
+++ b/deployments/bicep/modules/gateway.bicep
@@ -0,0 +1,162 @@
+@description('The resource ID of the subnet to which the Application Gateway should be connected.')
+param subnetId string
+
+@description('The private IP address of the backend server.')
+param backendIPAddress string
+
+@description('The secret url for the certificate in Azure Key Vault.')
+@secure()
+param keyVaultSecretId string
+
+param location string = resourceGroup().location
+param resourceNamePrefix string
+param publicIpId string
+
+param keyVaultName string
+
+var managedIdentityName = '${resourceNamePrefix}-gateway-identity'
+
+resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
+ name: managedIdentityName
+ location: location
+}
+
+// assign the identity to keyvault with name
+resource keyVaultAccess 'Microsoft.KeyVault/vaults/accessPolicies@2021-06-01-preview' = {
+ name: '${keyVaultName}/add'
+ properties: {
+ accessPolicies: [
+ {
+ tenantId: subscription().tenantId
+ objectId: managedIdentity.properties.principalId
+ permissions: {
+ keys: ['get', 'list']
+ secrets: ['get', 'list']
+ }
+ }
+ ]
+ }
+}
+
+
+resource appGateway 'Microsoft.Network/applicationGateways@2020-06-01' = {
+ name: '${resourceNamePrefix}-appGateway'
+ location: location
+ identity: {
+ type: 'UserAssigned'
+ userAssignedIdentities: {
+ // add the reference to the managed identity
+ '${managedIdentity.id}': {}
+ }
+
+ }
+ properties: {
+ sku: {
+ name: 'Standard_v2'
+ tier: 'Standard_v2'
+ capacity: 2
+ }
+ gatewayIPConfigurations: [
+ {
+ name: 'appGatewayIpConfig'
+ properties: {
+ subnet: {
+ id: subnetId
+ }
+ }
+ }
+ ]
+ frontendIPConfigurations: [
+ {
+ name: 'appGatewayFrontendIP'
+ properties: {
+ publicIPAddress: {
+ id: publicIpId
+ }
+ }
+ }
+ ]
+ frontendPorts: [
+ {
+ name: 'frontendPortHttps'
+ properties: {
+ port: 443
+ }
+ }
+ ]
+ backendAddressPools: [
+ {
+ name: 'backendPool'
+ properties: {
+ backendAddresses: [
+ {
+ ipAddress: backendIPAddress
+ }
+ ]
+ }
+ }
+ ]
+ backendHttpSettingsCollection: [
+ {
+ name: 'backendHttpSettings'
+ properties: {
+ port: 80
+ protocol: 'Http'
+ cookieBasedAffinity: 'Disabled'
+ pickHostNameFromBackendAddress: false
+ requestTimeout: 20
+ }
+ }
+ ]
+ httpListeners: [
+ {
+ name: 'httpsListener'
+ properties: {
+ frontendIPConfiguration: {
+ id: resourceId(
+ 'Microsoft.Network/applicationGateways/frontendIPConfigurations',
+ 'appGateway',
+ 'appGatewayFrontendIP'
+ )
+ }
+ frontendPort: {
+ id: resourceId('Microsoft.Network/applicationGateways/frontendPorts', 'appGateway', 'frontendPortHttps')
+ }
+ protocol: 'Https'
+ sslCertificate: {
+ id: resourceId('Microsoft.Network/applicationGateways/sslCertificates', 'appGateway', 'sslCertificate')
+ }
+ }
+ }
+ ]
+ requestRoutingRules: [
+ {
+ name: 'routingRule'
+ properties: {
+ ruleType: 'Basic'
+ httpListener: {
+ id: resourceId('Microsoft.Network/applicationGateways/httpListeners', 'appGateway', 'httpsListener')
+ }
+ backendAddressPool: {
+ id: resourceId('Microsoft.Network/applicationGateways/backendAddressPools', 'appGateway', 'backendPool')
+ }
+ backendHttpSettings: {
+ id: resourceId(
+ 'Microsoft.Network/applicationGateways/backendHttpSettingsCollection',
+ 'appGateway',
+ 'backendHttpSettings'
+ )
+ }
+ }
+ }
+ ]
+ sslCertificates: [
+ {
+ name: 'sslCertificate'
+ properties: {
+ keyVaultSecretId: keyVaultSecretId
+ }
+ }
+ ]
+ }
+}