Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion deploy/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ param engineAppSecret string
@description('Tags')
param tags object = {}

param private bool = false

@description('IPAM Resource Names')
param resourceNames object = {
functionName: '${namePrefix}-${uniqueString(guid)}'
Expand All @@ -51,6 +53,7 @@ param resourceNames object = {
resourceGroupName: '${namePrefix}-rg-${uniqueString(guid)}'
storageAccountName: '${namePrefix}stg${uniqueString(guid)}'
containerRegistryName: '${namePrefix}acr${uniqueString(guid)}'
virtualNetwork: '${namePrefix}vnet${uniqueString(guid)}'
}

// Resource Group
Expand All @@ -61,6 +64,16 @@ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
tags: tags
}

module virtualNetwork 'modules/virtualNetwork.bicep' = {
name: 'virtualNetworkModule'
scope: resourceGroup
params: {
private: private
location: location
virtualNetworkName: resourceNames.virtualNetwork
}
}

// Log Analytics Workspace
module logAnalyticsWorkspace './modules/logAnalyticsWorkspace.bicep' ={
name: 'logAnalyticsWorkspaceModule'
Expand Down Expand Up @@ -94,6 +107,8 @@ module keyVault './modules/keyVault.bicep' = {
engineAppId: engineAppId
engineAppSecret: engineAppSecret
workspaceId: logAnalyticsWorkspace.outputs.workspaceId
privateEndpointSubnetId: virtualNetwork.outputs.privateEndpointSubnetId
private: private
}
}

Expand All @@ -109,6 +124,8 @@ module cosmos './modules/cosmos.bicep' = {
keyVaultName: keyVault.outputs.keyVaultName
workspaceId: logAnalyticsWorkspace.outputs.workspaceId
principalId: managedIdentity.outputs.principalId
privateEndpointSubnetId: virtualNetwork.outputs.privateEndpointSubnetId
private: private
}
}

Expand All @@ -120,6 +137,8 @@ module storageAccount './modules/storageAccount.bicep' = if (deployAsFunc) {
location: location
storageAccountName: resourceNames.storageAccountName
workspaceId: logAnalyticsWorkspace.outputs.workspaceId
privateEndpointSubnetId: virtualNetwork.outputs.privateEndpointSubnetId
private: private
}
}

Expand All @@ -131,6 +150,8 @@ module containerRegistry './modules/containerRegistry.bicep' = if (privateAcr) {
location: location
containerRegistryName: resourceNames.containerRegistryName
principalId: managedIdentity.outputs.principalId
privateEndpointSubnetId: virtualNetwork.outputs.privateEndpointSubnetId
private: private
}
}

Expand All @@ -153,6 +174,9 @@ module appService './modules/appService.bicep' = if (!deployAsFunc) {
deployAsContainer: deployAsContainer
privateAcr: privateAcr
privateAcrUri: privateAcr ? containerRegistry.outputs.acrUri : ''
privateEndpointSubnetId: virtualNetwork.outputs.privateEndpointSubnetId
egressSubnetId: virtualNetwork.outputs.egressSubnetId
private: private
}
}

Expand All @@ -176,12 +200,14 @@ module functionApp './modules/functionApp.bicep' = if (deployAsFunc) {
deployAsContainer: deployAsContainer
privateAcr: privateAcr
privateAcrUri: privateAcr ? containerRegistry.outputs.acrUri : ''
privateEndpointSubnetId: virtualNetwork.outputs.privateEndpointSubnetId
egressSubnetId: virtualNetwork.outputs.egressSubnetId
private: private
}
}

// Outputs
output suffix string = uniqueString(guid)
output subscriptionId string = subscription().subscriptionId
output resourceGroupName string = resourceGroup.name
output appServiceName string = deployAsFunc ? resourceNames.functionName : resourceNames.appServiceName
output appServiceHostName string = deployAsFunc ? functionApp.outputs.functionAppHostName : appService.outputs.appServiceHostName
Expand Down
45 changes: 30 additions & 15 deletions deploy/modules/appService.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,13 @@ param privateAcr bool
@description('Uri for Private Container Registry')
param privateAcrUri string

param privateEndpointSubnetId string
param egressSubnetId string
param private bool

// ACR Uri Variable
var acrUri = privateAcr ? privateAcrUri : 'azureipam.azurecr.io'

// Disable Build Process Internet-Restricted Clouds
var runFromPackage = azureCloud == 'AZURE_US_GOV_SECRET' ? true : false

// Current Python Version
var engineVersion = loadJsonContent('../../engine/app/version.json')
var pythonVersion = engineVersion.python

resource appServicePlan 'Microsoft.Web/serverfarms@2021-02-01' = {
name: appServicePlanName
location: location
Expand All @@ -65,7 +62,7 @@ resource appServicePlan 'Microsoft.Web/serverfarms@2021-02-01' = {
}
}

resource appService 'Microsoft.Web/sites@2021-02-01' = {
resource appService 'Microsoft.Web/sites@2023-01-01' = {
name: appServiceName
location: location
kind: deployAsContainer ? 'app,linux,container' : 'app,linux'
Expand All @@ -83,8 +80,8 @@ resource appService 'Microsoft.Web/sites@2021-02-01' = {
acrUseManagedIdentityCreds: privateAcr ? true : false
acrUserManagedIdentityID: privateAcr ? managedIdentityClientId : null
alwaysOn: true
linuxFxVersion: deployAsContainer ? 'DOCKER|${acrUri}/ipam:latest' : 'PYTHON|${pythonVersion}'
appCommandLine: !deployAsContainer ? 'bash ./init.sh 8000' : null
linuxFxVersion: deployAsContainer ? 'DOCKER|${acrUri}/ipam:latest' : 'PYTHON|3.9'
appCommandLine: !deployAsContainer ? 'init.sh 8000' : null
healthCheckPath: '/api/status'
appSettings: concat(
[
Expand Down Expand Up @@ -142,11 +139,6 @@ resource appService 'Microsoft.Web/sites@2021-02-01' = {
name: 'DOCKER_REGISTRY_SERVER_URL'
value: privateAcr ? 'https://${privateAcrUri}' : 'https://index.docker.io/v1'
}
] : runFromPackage ? [
{
name: 'WEBSITE_RUN_FROM_PACKAGE'
value: '1'
}
] : [
{
name: 'SCM_DO_BUILD_DURING_DEPLOYMENT'
Expand All @@ -155,6 +147,29 @@ resource appService 'Microsoft.Web/sites@2021-02-01' = {
]
)
}
virtualNetworkSubnetId: egressSubnetId
publicNetworkAccess: private ? 'Disabled' : 'Enabled'
}
}

resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-06-01' = if(private) {
name: '${appServiceName}-privateEndpoint'
location: location
properties: {
subnet: {
id: privateEndpointSubnetId
}
privateLinkServiceConnections: [
{
name: '${appServiceName}-privateEndpoint'
properties: {
privateLinkServiceId: appService.id
groupIds: [
'sites'
]
}
}
]
}
}

Expand Down
30 changes: 29 additions & 1 deletion deploy/modules/containerRegistry.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,43 @@ param principalId string
@description('Role Assignment GUID')
param roleAssignmentName string = newGuid()

param privateEndpointSubnetId string
param private bool

var acrPull = '7f951dda-4ed3-4680-a7ca-43fe172d538d'
var acrPullId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', acrPull)

resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-12-01-preview' = {
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-11-01-preview' = {
name: containerRegistryName
location: location
sku: {
name: 'Standard'
}
properties: {
adminUserEnabled: false
publicNetworkAccess: private ? 'Disabled' : 'Enabled'
}
}

resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-06-01' = if(private) {
name: '${containerRegistryName}-privateEndpoint'
location: location
properties: {
subnet: {
id: privateEndpointSubnetId
}
privateLinkServiceConnections: [
{
name: '${containerRegistryName}-privateLinkServiceConnection'
properties: {
privateLinkServiceId: containerRegistry.id
groupIds: [
'registry'
]
}
}
]
}
}

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
Expand Down
25 changes: 25 additions & 0 deletions deploy/modules/cosmos.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ param workspaceId string
@description('Managed Identity PrincipalId')
param principalId string

param privateEndpointSubnetId string
param private bool

var dbContributor = '00000000-0000-0000-0000-000000000002'
var dbContributorId = '${resourceGroup().id}/providers/Microsoft.DocumentDB/databaseAccounts/${cosmosAccount.name}/sqlRoleDefinitions/${dbContributor}'
var dbContributorRoleAssignmentId = guid(dbContributor, principalId, cosmosAccount.id)
Expand All @@ -40,6 +43,7 @@ resource cosmosAccount 'Microsoft.DocumentDB/databaseAccounts@2021-04-15' = {
databaseAccountOfferType: 'Standard'
enableAutomaticFailover: true
disableKeyBasedMetadataWriteAccess: true
publicNetworkAccess: private ? 'Disabled' : 'Enabled'
}
}

Expand Down Expand Up @@ -168,4 +172,25 @@ resource sqlRoleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignm
}
}

resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-06-01' = if(private) {
name: '${cosmosAccountName}-privateEndpoint'
location: location
properties: {
subnet: {
id: privateEndpointSubnetId
}
privateLinkServiceConnections: [
{
name: '${cosmosAccountName}-privateLinkServiceConnection'
properties: {
privateLinkServiceId: cosmosAccount.id
groupIds: [
'sql'
]
}
}
]
}
}

output cosmosDocumentEndpoint string = cosmosAccount.properties.documentEndpoint
49 changes: 31 additions & 18 deletions deploy/modules/functionApp.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,13 @@ param privateAcr bool
@description('Uri for Private Container Registry')
param privateAcrUri string

param privateEndpointSubnetId string
param egressSubnetId string
param private bool

// ACR Uri Variable
var acrUri = privateAcr ? privateAcrUri : 'azureipam.azurecr.io'

// Disable Build Process Internet-Restricted Clouds
var runFromPackage = azureCloud == 'AZURE_US_GOV_SECRET' ? true : false

// Current Python Version
var engineVersion = loadJsonContent('../../engine/app/version.json')
var pythonVersion = engineVersion.python

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = {
name: storageAccountName
}
Expand Down Expand Up @@ -87,7 +84,7 @@ resource functionApp 'Microsoft.Web/sites@2021-03-01' = {
siteConfig: {
acrUseManagedIdentityCreds: privateAcr ? true : false
acrUserManagedIdentityID: privateAcr ? managedIdentityClientId : null
linuxFxVersion: deployAsContainer ? 'DOCKER|${acrUri}/ipamfunc:latest' : 'PYTHON|${pythonVersion}'
linuxFxVersion: deployAsContainer ? 'DOCKER|${acrUri}/ipamfunc:latest' : 'Python|3.9'
healthCheckPath: '/api/status'
appSettings: concat(
[
Expand Down Expand Up @@ -165,15 +162,6 @@ resource functionApp 'Microsoft.Web/sites@2021-03-01' = {
name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE'
value: 'false'
}
] : runFromPackage ? [
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'python'
}
{
name: 'WEBSITE_RUN_FROM_PACKAGE'
value: '1'
}
] : [
{
name: 'FUNCTIONS_WORKER_RUNTIME'
Expand All @@ -186,6 +174,31 @@ resource functionApp 'Microsoft.Web/sites@2021-03-01' = {
]
)
}
virtualNetworkSubnetId: egressSubnetId

}
}

resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-06-01' = if(private) {
name: '${functionAppName}-privateEndpoint'
location: location
properties: {
subnet: {
id: privateEndpointSubnetId
}
privateLinkServiceConnections: [
{
name: 'privateLinkServiceConnection'
properties: {
privateLinkServiceId: functionApp.id
groupIds: [
'blob'
'queue'
'table'
]
}
}
]
}
}

Expand Down Expand Up @@ -248,7 +261,7 @@ resource diagnosticSettingsApp 'Microsoft.Insights/diagnosticSettings@2021-05-01
enabled: true
retentionPolicy: {
days: 0
enabled: false
enabled: false
}
}
]
Expand Down
24 changes: 24 additions & 0 deletions deploy/modules/keyVault.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ param engineAppSecret string
@description('Log Analytics Worskpace ID')
param workspaceId string

param privateEndpointSubnetId string
param private bool

var keyVaultUser = '4633458b-17de-408a-b874-0445c86b69e6'
var keyVaultUserId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', keyVaultUser)
var keyVaultUserRoleAssignmentId = guid(keyVaultUser, identityPrincipalId, keyVault.id)
Expand Down Expand Up @@ -126,5 +129,26 @@ resource keyVaultUserAssignment 'Microsoft.Authorization/roleAssignments@2020-04
}
}

resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-06-01' = if(private) {
name: '${keyVaultName}-privateEndpoint'
location: location
properties: {
subnet: {
id: privateEndpointSubnetId
}
privateLinkServiceConnections: [
{
name: 'privateLinkServiceConnection'
properties: {
privateLinkServiceId: keyVault.id
groupIds: [
'vault'
]
}
}
]
}
}

output keyVaultName string = keyVault.name
output keyVaultUri string = keyVault.properties.vaultUri
Loading