Provide optional parameters to support AZ redundancy for MySQL and Web App and HA for MySQL (#89)
* Add MySQL High Availability support; AZ support for MySQL and App Svc * Add support for adding an NSG to all subnets * Default to P0v3 App Service tier. * Correct REDCap capitalization * Update API version of Microsoft.Web provider * Remove allowed values for environment param * Add support for specifying REDCap version downloaded from community * Set default MySQL SKU to B1ms
This commit is contained in:
Родитель
7434d50392
Коммит
2c53bebb26
|
@ -48,6 +48,8 @@ To deploy the REDCap source to Azure App Service, you must supply your REDCap Co
|
|||
|
||||
(1) Review <https://learn.microsoft.com/azure/mysql/flexible-server/concepts-service-tiers-storage> for details on available features, regions, and pricing models for Azure DB for MySQL.
|
||||
|
||||
Advanced deployments can enable high availability for the MySQL Flexible Server and availability zone redundancy for the MySQL Flexible Server and web app. These capabilities can be controlled using parameters for the Bicep deployment.
|
||||
|
||||
<!--(2) SendGrid is a paid service with a free tier offering 25k messages per month, with additional paid tiers offering more volume, whitelisting, custom domains, etc. There is a limit of two instances per subscription using the free tier. For more information see <https://docs.microsoft.com/en-us/azure/store-sendgrid-php-how-to-send-email#create-a-sendgrid-account>. The service will be accessed initially using the password you enter in the deployment template. You can click "Manage" on the SendGrid service after deployment to administrate the service in their portal, including options to create an API key that can be used for access instead of the password.
|
||||
|
||||
If after deployment, you would instead like to use a different SMTP relay, edit the values "smtp_fqdn_name", "smtp_port", "smtp_user_name", and "smtp_password" to point to your preferred endpoint. You can then delete the SendGrid service from this resource group.
|
||||
|
|
|
@ -18,8 +18,8 @@ param vnetAddressSpace = '10.0.0.0/24'
|
|||
// Do not specify a URL if you are using this option. The deployment script will download the zip file from the REDCap community.
|
||||
param redcapZipUrl = '<Valid Redcap Zip URL>'
|
||||
// -- OR --
|
||||
param redcapCommunityUsername = '<Valid Redcap Community Username>'
|
||||
param redcapCommunityPassword = '<Valid Redcap Community Password>'
|
||||
param redcapCommunityUsername = '<Valid REDCap Community Username>'
|
||||
param redcapCommunityPassword = '<Valid REDCap Community Password>'
|
||||
|
||||
// These values are used to configure the App Service Deployment Center.
|
||||
// The defaults below are the Microsoft-maintained Azure REDCap PaaS repository.
|
||||
|
@ -41,4 +41,26 @@ param smtpFromEmailAddress = '<Specify valid SMTP From Email Address>'
|
|||
// A new password is generated for each deployment and stored in Key Vault.
|
||||
param sqlPassword = ''
|
||||
|
||||
param appServiceTimeZone = 'UTC'
|
||||
// param existingVirtualNetworkId = '/subscriptions/c236b7b3-dec1-47a6-856c-8c1f45d88575/resourceGroups/redcap-networkexisting-test-rg-cnc-01/providers/Microsoft.Network/virtualNetworks/redcap-existing-demo-vnet-cnc-01'
|
||||
// param existingPrivateDnsZonesResourceGroupId = '/subscriptions/c236b7b3-dec1-47a6-856c-8c1f45d88575/resourceGroups/redcap-networkexisting-test-rg-cnc-01'
|
||||
|
||||
// param subnets = {
|
||||
// PrivateLinkSubnet: {
|
||||
// existingSubnetName: 'PlSubnet'
|
||||
// }
|
||||
// MySQLFlexSubnet: {
|
||||
// existingSubnetName: 'SqlSubnet'
|
||||
// }
|
||||
// IntegrationSubnet: {
|
||||
// existingSubnetName: 'WebAppSubnet'
|
||||
// }
|
||||
// }
|
||||
|
||||
// param mySqlSkuTier = 'GeneralPurpose'
|
||||
// param mySqlHighAvailability = 'Enabled'
|
||||
// param mySqlSkuName = 'Standard_D4ds_v4'
|
||||
// param availabilityZonesEnabled = true
|
||||
// param mySqlStorageSizeGB = 200
|
||||
// param mySqlStorageIops = 1200
|
||||
|
||||
// param appServiceTimeZone = 'UTC'
|
||||
|
|
51
main.bicep
51
main.bicep
|
@ -4,11 +4,11 @@ targetScope = 'subscription'
|
|||
param location string = 'eastus'
|
||||
|
||||
@description('The environment designator for the deployment. Replaces {env} in namingConvention.')
|
||||
@allowed([
|
||||
'test'
|
||||
'demo'
|
||||
'prod'
|
||||
])
|
||||
// @allowed([
|
||||
// 'test'
|
||||
// 'demo'
|
||||
// 'prod'
|
||||
// ])
|
||||
param environment string = 'demo'
|
||||
@description('The workload name. Replaces {workloadName} in namingConvention.')
|
||||
param workloadName string = 'redcap'
|
||||
|
@ -34,6 +34,8 @@ param redcapCommunityUsername string
|
|||
@description('REDCap Community site password for downloading the REDCap zip file.')
|
||||
@secure()
|
||||
param redcapCommunityPassword string
|
||||
@description('The version of REDCap to download from the REDCap Community. This is not used when specifying a ZIP URL.')
|
||||
param redcapVersion string = ''
|
||||
@description('Github Repo URL where build scripts are downloaded from')
|
||||
param scmRepoUrl string = 'https://github.com/microsoft/azure-redcap-paas'
|
||||
@description('Github Repo Branch where build scripts are downloaded from')
|
||||
|
@ -49,6 +51,25 @@ param enableAppServicePrivateEndpoint bool = true
|
|||
@secure()
|
||||
param sqlPassword string
|
||||
|
||||
@description('Whether High Availability is enabled for the MySQL Flexible Server. Zone redundant or same zone HA is determined by the value of availabilityZonesEnabled.')
|
||||
@allowed([
|
||||
'Enabled'
|
||||
'Disabled'
|
||||
])
|
||||
param mySqlHighAvailability string = 'Disabled'
|
||||
|
||||
param mySqlSkuName string = 'Standard_B1ms'
|
||||
|
||||
@allowed([
|
||||
'GeneralPurpose'
|
||||
'MemoryOptimized'
|
||||
'Burstable'
|
||||
])
|
||||
param mySqlSkuTier string = 'Burstable'
|
||||
@description('The size of the MySQL Flexible Server storage in GB. This cannot be scaled down after server creation.')
|
||||
param mySqlStorageSizeGB int = 20
|
||||
param mySqlStorageIops int = 396
|
||||
|
||||
@description('The MySQL Flexible Server admin user account name. Defaults to \'sqladmin\'.')
|
||||
param sqlAdmin string = 'sqladmin'
|
||||
|
||||
|
@ -59,6 +80,10 @@ param smtpPort string = ''
|
|||
@description('The email address to use as the sender for outgoing emails.')
|
||||
param smtpFromEmailAddress string = ''
|
||||
|
||||
param appServiceSkuName string = 'P0v3'
|
||||
|
||||
@description('Determines whether availability zone redundancy is enabled for the MySQL Flexible Server and the app service. The region must support availability zones.')
|
||||
param availabilityZonesEnabled bool = false
|
||||
param existingPrivateDnsZonesResourceGroupId string = ''
|
||||
param existingVirtualNetworkId string = ''
|
||||
|
||||
|
@ -358,10 +383,10 @@ module mySqlModule './modules/sql/main.bicep' = {
|
|||
customTags: {
|
||||
workloadType: 'mySqlFlexibleServer'
|
||||
}
|
||||
skuName: 'Standard_B1ms'
|
||||
SkuTier: 'Burstable'
|
||||
StorageSizeGB: 20
|
||||
StorageIops: 396
|
||||
skuName: mySqlSkuName
|
||||
SkuTier: mySqlSkuTier
|
||||
StorageSizeGB: mySqlStorageSizeGB
|
||||
StorageIops: mySqlStorageIops
|
||||
peSubnetId: empty(existingVirtualNetworkId)
|
||||
? virtualNetworkModule.outputs.subnets.MySQLFlexSubnet.id
|
||||
: '${existingVirtualNetworkId}/subnets/${subnets.MySQLFlexSubnet.existingSubnetName}'
|
||||
|
@ -373,6 +398,9 @@ module mySqlModule './modules/sql/main.bicep' = {
|
|||
// TODO: Consider using workloadname + 'db'
|
||||
databaseName: 'redcapdb'
|
||||
|
||||
highAvailability: mySqlHighAvailability
|
||||
availabilityZonesEnabled: availabilityZonesEnabled
|
||||
|
||||
roles: rolesModule.outputs.roles
|
||||
|
||||
uamiId: uamiModule.outputs.id
|
||||
|
@ -405,8 +433,7 @@ module webAppModule './modules/webapp/main.bicep' = {
|
|||
webAppName: webAppName
|
||||
appServicePlanName: planName
|
||||
location: location
|
||||
// Deploy as P0V3 to ensure the deployment runs on a scale unit that supports P_v3 for future upgrades. GH issue #50
|
||||
skuName: 'P0V3'
|
||||
skuName: appServiceSkuName
|
||||
peSubnetId: privateEndpointSubnetId
|
||||
appInsights_connectionString: monitoring.outputs.appInsightsResourceId
|
||||
appInsights_instrumentationKey: monitoring.outputs.appInsightsInstrumentationKey
|
||||
|
@ -429,6 +456,7 @@ module webAppModule './modules/webapp/main.bicep' = {
|
|||
|
||||
redcapCommunityUsernameSecretRef: kvSecretReferencesModule.outputs.keyVaultRefs[1]
|
||||
redcapCommunityPasswordSecretRef: kvSecretReferencesModule.outputs.keyVaultRefs[0]
|
||||
redcapVersion: redcapVersion
|
||||
|
||||
storageAccountKeySecretRef: kvSecretReferencesModule.outputs.keyVaultRefs[4]
|
||||
storageAccountContainerName: storageAccountModule.outputs.containerName
|
||||
|
@ -451,6 +479,7 @@ module webAppModule './modules/webapp/main.bicep' = {
|
|||
|
||||
uamiId: uamiModule.outputs.id
|
||||
|
||||
availabilityZonesEnabled: availabilityZonesEnabled
|
||||
enablePrivateEndpoint: enableAppServicePrivateEndpoint
|
||||
|
||||
timeZone: appServiceTimeZone
|
||||
|
|
|
@ -13,6 +13,7 @@ param subnets object
|
|||
param tags object
|
||||
|
||||
param customDnsIPs array
|
||||
param networkSecurityGroupId string = ''
|
||||
|
||||
var subnetDefsArray = items(subnets)
|
||||
|
||||
|
@ -30,6 +31,11 @@ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2021-05-01' = {
|
|||
name: subnet.key
|
||||
properties: {
|
||||
addressPrefix: subnet.value.addressPrefix
|
||||
networkSecurityGroup: !empty(networkSecurityGroupId)
|
||||
? {
|
||||
id: networkSecurityGroupId
|
||||
}
|
||||
: null
|
||||
serviceEndpoints: subnet.value.?serviceEndpoints
|
||||
delegations: contains(subnet.value, 'delegation') && !empty(subnet.value.delegation)
|
||||
? [
|
||||
|
|
|
@ -36,6 +36,14 @@ param skuName string = 'Standard_B1ms'
|
|||
])
|
||||
param SkuTier string
|
||||
|
||||
@allowed([
|
||||
'Enabled'
|
||||
'Disabled'
|
||||
])
|
||||
param highAvailability string = 'Disabled'
|
||||
|
||||
param availabilityZonesEnabled bool = false
|
||||
|
||||
@description('Azure database for MySQL storage Size ')
|
||||
param StorageSizeGB int = 20
|
||||
|
||||
|
@ -81,6 +89,9 @@ module mysqlDbserver './sql.bicep' = {
|
|||
database_charset: database_charset
|
||||
database_collation: database_collation
|
||||
|
||||
highAvailability: (highAvailability == 'Enabled') ? true : false
|
||||
availabilityZonesEnabled: availabilityZonesEnabled
|
||||
|
||||
roles: roles
|
||||
uamiId: uamiId
|
||||
uamiPrincipalId: uamiPrincipalId
|
||||
|
|
|
@ -6,7 +6,7 @@ param tags object
|
|||
|
||||
// TODO: skuName and SkuTier are related; should be specified as a single object param, IMHO
|
||||
@description('Azure database for MySQL sku name ')
|
||||
param skuName string = 'Standard_B1s'
|
||||
param skuName string = 'Standard_B1ms'
|
||||
|
||||
@description('Azure database for MySQL pricing tier')
|
||||
@allowed([
|
||||
|
@ -53,11 +53,9 @@ param geoRedundantBackup string = 'Disabled'
|
|||
|
||||
param backupRetentionDays int = 7
|
||||
|
||||
@allowed([
|
||||
'Enabled'
|
||||
'Disabled'
|
||||
])
|
||||
param highAvailability string = 'Disabled'
|
||||
param highAvailability bool = false
|
||||
|
||||
param availabilityZonesEnabled bool = false
|
||||
|
||||
@allowed([
|
||||
'Enabled'
|
||||
|
@ -90,7 +88,9 @@ resource server 'Microsoft.DBforMySQL/flexibleServers@2022-09-30-preview' = {
|
|||
geoRedundantBackup: geoRedundantBackup
|
||||
}
|
||||
highAvailability: {
|
||||
mode: highAvailability
|
||||
mode: (highAvailability && availabilityZonesEnabled)
|
||||
? 'ZoneRedundant'
|
||||
: (highAvailability) ? 'SameZone' : 'Disabled'
|
||||
}
|
||||
network: {
|
||||
delegatedSubnetResourceId: peSubnetId
|
||||
|
@ -143,7 +143,7 @@ resource dbConfigDeploymentScript 'Microsoft.Resources/deploymentScripts@2020-10
|
|||
scriptContent: 'az mysql flexible-server parameter set -g ${resourceGroup().name} --server-name ${server.name} --name sql_generate_invisible_primary_key --value OFF'
|
||||
}
|
||||
tags: tags
|
||||
dependsOn: [ uamiMySqlRoleAssignmentModule ]
|
||||
dependsOn: [uamiMySqlRoleAssignmentModule]
|
||||
}
|
||||
|
||||
output mySqlServerName string = server.name
|
||||
|
|
|
@ -15,6 +15,8 @@ param privateDnsZoneName string
|
|||
param virtualNetworkId string
|
||||
param integrationSubnetId string
|
||||
|
||||
param availabilityZonesEnabled bool = false
|
||||
|
||||
param smtpFQDN string = ''
|
||||
param smtpPort string = ''
|
||||
param smtpFromEmailAddress string = ''
|
||||
|
@ -33,6 +35,7 @@ param scmRepoUrl string
|
|||
param scmRepoBranch string
|
||||
@secure()
|
||||
param redcapZipUrl string
|
||||
param redcapVersion string = ''
|
||||
#disable-next-line secure-secrets-in-params
|
||||
param redcapCommunityUsernameSecretRef string
|
||||
#disable-next-line secure-secrets-in-params
|
||||
|
@ -78,6 +81,7 @@ module appService 'webapp.bicep' = {
|
|||
redcapZipUrl: redcapZipUrl
|
||||
redcapCommunityUsernameSecretRef: redcapCommunityUsernameSecretRef
|
||||
redcapCommunityPasswordSecretRef: redcapCommunityPasswordSecretRef
|
||||
redcapVersion: redcapVersion
|
||||
|
||||
scmRepoUrl: scmRepoUrl
|
||||
scmRepoBranch: scmRepoBranch
|
||||
|
@ -93,6 +97,7 @@ module appService 'webapp.bicep' = {
|
|||
|
||||
uamiId: uamiId
|
||||
|
||||
availabiltyZonesEnabled: availabilityZonesEnabled
|
||||
enablePrivateEndpoint: enablePrivateEndpoint
|
||||
|
||||
timeZone: timeZone
|
||||
|
|
|
@ -21,6 +21,7 @@ param redcapZipUrl string
|
|||
param redcapCommunityUsernameSecretRef string
|
||||
#disable-next-line secure-secrets-in-params
|
||||
param redcapCommunityPasswordSecretRef string
|
||||
param redcapVersion string = ''
|
||||
param scmRepoUrl string
|
||||
param scmRepoBranch string
|
||||
param prerequisiteCommand string
|
||||
|
@ -28,6 +29,7 @@ param prerequisiteCommand string
|
|||
param appInsights_connectionString string
|
||||
param appInsights_instrumentationKey string
|
||||
|
||||
param availabiltyZonesEnabled bool = false
|
||||
param enablePrivateEndpoint bool
|
||||
|
||||
param smtpFQDN string = ''
|
||||
|
@ -45,23 +47,23 @@ param minTlsVersion string = '1.2'
|
|||
|
||||
param uamiId string
|
||||
|
||||
resource appSrvcPlan 'Microsoft.Web/serverfarms@2022-03-01' = {
|
||||
resource appSrvcPlan 'Microsoft.Web/serverfarms@2023-12-01' = {
|
||||
name: appServicePlanName
|
||||
location: location
|
||||
tags: tags
|
||||
sku: {
|
||||
name: skuName
|
||||
//tier: skuTier
|
||||
}
|
||||
kind: 'linux'
|
||||
properties: {
|
||||
reserved: true
|
||||
zoneRedundant: availabiltyZonesEnabled
|
||||
}
|
||||
}
|
||||
|
||||
var DBSslCa = '/home/site/wwwroot/DigiCertGlobalRootCA.crt.pem'
|
||||
|
||||
resource webApp 'Microsoft.Web/sites@2022-03-01' = {
|
||||
resource webApp 'Microsoft.Web/sites@2023-12-01' = {
|
||||
name: webAppName
|
||||
location: location
|
||||
tags: tags
|
||||
|
@ -101,6 +103,10 @@ resource webApp 'Microsoft.Web/sites@2022-03-01' = {
|
|||
name: 'redcapAppZip'
|
||||
value: redcapZipUrl
|
||||
}
|
||||
{
|
||||
name: 'zipVersion'
|
||||
value: redcapVersion
|
||||
}
|
||||
{
|
||||
name: 'redcapCommunityUsername'
|
||||
value: redcapCommunityUsernameSecretRef
|
||||
|
@ -179,7 +185,7 @@ resource webApp 'Microsoft.Web/sites@2022-03-01' = {
|
|||
|
||||
// SCM Basic Authentication is required when using the App Service Build Service
|
||||
// Per https://learn.microsoft.com/en-us/azure/app-service/deploy-continuous-deployment?tabs=github%2Cappservice#what-are-the-build-providers
|
||||
resource basicScmCredentials 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2023-01-01' = {
|
||||
resource basicScmCredentials 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2023-12-01' = {
|
||||
parent: webApp
|
||||
name: 'scm'
|
||||
properties: {
|
||||
|
@ -187,7 +193,7 @@ resource basicScmCredentials 'Microsoft.Web/sites/basicPublishingCredentialsPoli
|
|||
}
|
||||
}
|
||||
|
||||
resource sourcecontrol 'Microsoft.Web/sites/sourcecontrols@2022-09-01' = {
|
||||
resource sourcecontrol 'Microsoft.Web/sites/sourcecontrols@2023-12-01' = {
|
||||
parent: webApp
|
||||
name: 'web'
|
||||
properties: {
|
||||
|
|
Загрузка…
Ссылка в новой задаче