From 6c7e76408f67126113ce0639ffc9c0ecab2bd55e Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Wed, 18 Sep 2019 12:15:49 +1000 Subject: [PATCH 01/18] 161888 Add SSL to LANSA new DB template --- .../README.md | 2 + .../Scripts/Deploy-AzureResourceGroup.ps1 | 8 +- .../azuredeploy.json | 208 +++++++++++++++++- .../azuredeploy.parameters.json | 43 +++- .../metadata.json | 2 +- 5 files changed, 247 insertions(+), 16 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/README.md b/lansa-vmss-windows-autoscale-sql-database/README.md index 082f1d9ecdc6..9d7e34f5c0ec 100644 --- a/lansa-vmss-windows-autoscale-sql-database/README.md +++ b/lansa-vmss-windows-autoscale-sql-database/README.md @@ -40,6 +40,7 @@ The Autoscale rules are configured as follows + A Virtual Network + Six Storage Accounts for deploying up to 100 virtual machines + Two public ip addresses, one for each Load Balancer ++ One Application Gateway with SSL certificate + Two external Load Balancers + One Virtual Machine Scale Set to contain the single virtual machine which is responsible for configuring the database + One Virtual Machine Scale Set to contain the number of web servers requested by the deployer @@ -52,6 +53,7 @@ Before deploying this template you must: - Construct your LANSA application using [Visual LANSA for Web Development](https://azure.microsoft.com/en-us/marketplace/partners/lansa/visuallansa/) Version 14.1 with EPCs 141010, 141011 and 141013 applied, or later. - Construct a deployment image MSI using the LANSA Deployment Tool provided with [Visual LANSA for Web Development](https://azure.microsoft.com/en-us/marketplace/partners/lansa/visuallansa/). - Upload your LANSA Web Application MSI to Azure BLOB storage and obtain the URL of the MSI. Note that the template includes a demonstration application so it is not strictly necessary to create a LANSA MSI in order to use the template. +- Obtain an SSL certificate for your web site and convert it to a base64 encoded string. To get the certificate data from a pfx file in PowerShell you can use this: [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("path to pfx file")) - Its also highly recommended to follow the usage instructions below :) ## Usage Instructions diff --git a/lansa-vmss-windows-autoscale-sql-database/Scripts/Deploy-AzureResourceGroup.ps1 b/lansa-vmss-windows-autoscale-sql-database/Scripts/Deploy-AzureResourceGroup.ps1 index db3047355d9d..ea8d7d72ec89 100644 --- a/lansa-vmss-windows-autoscale-sql-database/Scripts/Deploy-AzureResourceGroup.ps1 +++ b/lansa-vmss-windows-autoscale-sql-database/Scripts/Deploy-AzureResourceGroup.ps1 @@ -1,6 +1,6 @@ #Requires -Version 3.0 -#Requires -Module AzureRM.Resources -#Requires -Module Azure.Storage +#Requires -Module Az.Resources +#Requires -Module Az.Storage Param( [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation, @@ -14,7 +14,7 @@ Param( [string] $DSCSourceFolder = '..\DSC' ) -Import-Module Azure -ErrorAction SilentlyContinue +Enable-AzureRmAlias try { [Microsoft.Azure.Common.Authentication.AzureSession]::ClientFactory.AddUserAgent("VSAzureTools-$UI$($host.name)".replace(" ","_"), "2.9") @@ -93,7 +93,7 @@ if ($UploadArtifacts) { } # Create or update the resource group using the specified template file and template parameters file -New-AzureRmResourceGroup -Name $ResourceGroupName -Location $ResourceGroupLocation -Verbose -Force -ErrorAction Stop +New-AzureRmResourceGroup -Name $ResourceGroupName -Location $ResourceGroupLocation -Verbose -Force -ErrorAction Stop New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $TemplateFile).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) ` -ResourceGroupName $ResourceGroupName ` diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index 6cc89939992d..c0a032e298bc 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -21,8 +21,40 @@ "metadata": { "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended." }, + "minLength" : 3, "maxLength": 61 }, + "applicationGatewaySkuName": { + "type": "string", + "allowedValues": [ + "Standard_Small", + "Standard_Medium", + "Standard_Large" + ], + "defaultValue": "Standard_Medium", + "metadata": { + "description": "Application Gateway SKU Name" + } + }, + "applicationGatewayCapacity": { + "type": "int", + "defaultValue": 2, + "metadata": { + "description": "Number of Application Gateway instances" + } + }, + "certificateBase64Encoded": { + "type": "string", + "metadata": { + "description": "Base 64 encoded String representing the SSL certificate" + } + }, + "certificatePassword": { + "type": "securestring", + "metadata": { + "description": "SSL certificate password" + } + }, "minInstanceCount": { "type": "int", "defaultValue": 1, @@ -94,7 +126,6 @@ }, "adminUsername": { "type": "string", - "defaultValue": "lansa", "metadata": { "description": "Admin username on all VMs." } @@ -107,7 +138,6 @@ }, "webUsername": { "type": "string", - "defaultValue": "Pcxuser2", "metadata": { "description": "Web Server username on all VMs." } @@ -120,7 +150,6 @@ }, "databaseLogin": { "type": "string", - "defaultValue": "lansa", "metadata": { "description": "The admin user of the Azure SQL Database" } @@ -183,7 +212,7 @@ "defaultValue": "support/L4W14000_scalable_azure", "metadata": { "description": "Git Branch" - } + } }, "trace": { "type": "string", @@ -204,10 +233,11 @@ } } }, - "variables": { + "variables": { "namingInfix": "[toLower(substring(concat(parameters('vmssName'), uniqueString(resourceGroup().id)), 0, 9))]", "longNamingInfix": "[toLower(parameters('vmssName'))]", "dblongNamingInfix": "[toLower(concat('db',parameters('vmssName')))]", + "aglongNamingInfix": "[toLower(concat('ag',parameters('vmssName')))]", "dbvmssName": "[toLower(substring(concat('db',parameters('vmssName'), uniqueString(resourceGroup().id)), 0, 9))]", "addressPrefix": "10.0.0.0/16", "subnetPrefix": "10.0.0.0/24", @@ -245,7 +275,15 @@ "gitRepo": "https://raw.githubusercontent.com/robe070/cookbooks/", "gitRefreshName": "git-pull.ps1", "gitRefreshUri": "[concat(variables('gitRepo'), parameters('gitBranch'), '/scripts/', variables('gitRefreshName'))]", - "q": "'" + "q": "'", + "agPublicIPAddressName": "[concat(variables('namingInfix'), '-agpip')]", + "agPublicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',variables('agPublicIPAddressName'))]", + "agSubnetPrefix": "10.0.1.0/24", + "agSubnetName": "[concat(variables('namingInfix'), '-agsubnet')]", + "agSubnetID": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('agsubnetName'))]", + "agName": "[concat(variables('namingInfix'), '-ag')]", + "agID": "[resourceId('Microsoft.Network/applicationgateways',variables('agName'))]", + "agBackendAddressPoolName": "[concat(variables('namingInfix'), '-agpool')]" }, "resources": [ { @@ -265,6 +303,12 @@ "properties": { "addressPrefix": "[variables('subnetPrefix')]" } + }, + { + "name": "[variables('agSubnetName')]", + "properties": { + "addressPrefix": "[variables('agSubnetPrefix')]" + } } ] } @@ -435,7 +479,8 @@ "[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", "[concat('Microsoft.Sql/servers/', variables('sqlserverName'))]", - "[concat('Microsoft.Sql/servers/', variables('sqlserverName'), '/databases/', parameters('databaseName'))]" + "[concat('Microsoft.Sql/servers/', variables('sqlserverName'), '/databases/', parameters('databaseName'))]", + "[concat('Microsoft.Network/applicationGateways/', variables('agName'))]" ], "sku": { "name": "[variables('dbvmSku')]", @@ -581,6 +626,11 @@ { "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('loadBalancerName'), '/inboundNatPools/', variables('natPoolName'))]" } + ], + "applicationGatewayBackendAddressPools": [ + { + "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/applicationGateways/', variables('agName'), '/backendAddressPools/', variables('agBackendAddressPoolName'))]" + } ] } } @@ -676,6 +726,147 @@ ] } }, + { + "type": "Microsoft.Insights/autoscaleSettings", + "apiVersion": "2015-04-01", + "name": "[variables('dbvmssName')]", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachineScaleSets/', variables('dbvmssName'))]" + ], + "properties": { + "name": "[variables('dbvmssName')]", + "targetResourceUri": "[concat('/subscriptions/',subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Compute/virtualMachineScaleSets/', variables('dbvmssName'))]", + "enabled": true, + "profiles": [ + { + "name": "Single Fixed Instance", + "capacity": { + "minimum": "1", + "maximum": "1", + "default": "1" + }, + "rules": [] + } + ] + } + }, + { + "apiVersion": "2015-05-01-preview", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[variables('agPublicIPAddressName')]", + "location": "[resourceGroup().location]", + "properties": { + "publicIPAllocationMethod": "Dynamic", + "dnsSettings": { + "domainNameLabel": "[variables('aglongNamingInfix')]" + } + } + }, + { + "apiVersion": "2017-06-01", + "name": "[variables('agName')]", + "type": "Microsoft.Network/applicationGateways", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', variables('agPublicIPAddressName'))]" + ], + "properties": { + "sku": { + "name": "[parameters('applicationGatewaySkuName')]", + "tier": "Standard", + "capacity": "[parameters('applicationGatewayCapacity')]" + }, + "sslCertificates": [ + { + "name": "appGatewaySslCert", + "properties": { + "data": "[parameters('certificateBase64Encoded')]", + "password": "[parameters('certificatePassword')]" + } + } + ], + "gatewayIPConfigurations": [ + { + "name": "appGatewayIpConfig", + "properties": { + "subnet": { + "id": "[variables('agSubnetID')]" + } + } + } + ], + "frontendIPConfigurations": [ + { + "name": "appGatewayFrontendIP", + "properties": { + "PublicIPAddress": { + "id": "[variables('agPublicIPAddressID')]" + } + } + } + ], + "frontendPorts": [ + { + "name": "appGatewayFrontendPort", + "properties": { + "Port": 443 + } + } + ], + "backendAddressPools": [ + { + "name": "[variables('agBackendAddressPoolName')]" + } + ], + "backendHttpSettingsCollection": [ + { + "name": "appGatewayBackendHttpSettings", + "properties": { + "Port": 80, + "Protocol": "Http", + "CookieBasedAffinity": "Enabled", + "RequestTimeout": 120 + } + } + ], + "httpListeners": [ + { + "name": "appGatewayHttpListener", + "properties": { + "FrontendIPConfiguration": { + "Id": "[concat(variables('agID'), '/frontendIPConfigurations/appGatewayFrontendIP')]" + }, + "FrontendPort": { + "Id": "[concat(variables('agID'), '/frontendPorts/appGatewayFrontendPort')]" + }, + "Protocol": "Https", + "SslCertificate": { + "Id": "[concat(variables('agID'), '/sslCertificates/appGatewaySslCert')]" + } + } + } + ], + "requestRoutingRules": [ + { + "Name": "rule1", + "properties": { + "RuleType": "Basic", + "httpListener": { + "id": "[concat(variables('agID'), '/httpListeners/appGatewayHttpListener')]" + }, + "backendAddressPool": { + "id": "[concat(variables('agID'), '/backendAddressPools/', variables('agBackendAddressPoolName'))]" + }, + "backendHttpSettings": { + "id": "[concat(variables('agID'), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]" + } + } + } + ] + } + }, { "name": "[variables('sqlserverName')]", "type": "Microsoft.Sql/servers", @@ -727,7 +918,6 @@ } ] } - ], "outputs": { "dbServerName": { @@ -740,7 +930,7 @@ }, "lbFqdn": { "type": "string", - "value": "[reference(variables('publicIPAddressName')).dnsSettings.fqdn]" + "value": "[concat('https://', reference(variables('agPublicIPAddressName')).dnsSettings.fqdn)]" }, "dbrdpAddress": { "type": "string", diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json index 744371a89443..0202a2f57e67 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json @@ -5,14 +5,53 @@ "vmssName": { "value": "GEN-UNIQUE-10" }, + "certificateBase64Encoded": { + "value" : "default" + }, + "certificatePassword": { + "value": "GEN-PASSWORD" + }, + "databaseName": { + "value": "lansa" + }, + "databaseLogin": { + "value": "GEN-UNIQUE-10" + }, + "databaseLoginPassword": { + "value": "GEN-PASSWORD" + }, + "adminUsername": { + "value": "GEN_UNIQUE-10" + }, "adminPassword": { "value": "GEN-PASSWORD" }, + "webUsername": { + "value": "GEN_UNIQUE-10" + }, "webPassword": { "value": "GEN-PASSWORD" }, - "databaseLoginPassword": { - "value": "GEN-PASSWORD" + "webServerMaxConnect": { + "value": "20" + }, + "triggerWebConfig": { + "value": "0" + }, + "installMSI": { + "value": "0" + }, + "updateMSI": { + "value": "0" + }, + "uninstallMSI": { + "value": "0" + }, + "trace": { + "value": "N" + }, + "fixLicense": { + "value": "0" } } } diff --git a/lansa-vmss-windows-autoscale-sql-database/metadata.json b/lansa-vmss-windows-autoscale-sql-database/metadata.json index 9bd82f320101..9623f0d0a742 100644 --- a/lansa-vmss-windows-autoscale-sql-database/metadata.json +++ b/lansa-vmss-windows-autoscale-sql-database/metadata.json @@ -5,7 +5,7 @@ "description": "The template deploys a Windows VMSS with a desired count of VMs in the scale set and a LANSA MSI to install into each VM. Once the VM Scale Set is deployed a custom script extension is used to install the LANSA MSI)", "summary": "This template deploys a VM Scale Set of Windows VMs behind a load balancer with NAT rules for RDP connections and Auto scale integrated", "githubUsername": "robe070", - "dateUpdated": "2018-08-30" + "dateUpdated": "2019-05-06" } From eea10e017431a0239aeb7035420e0d5cf695dbab Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Wed, 18 Sep 2019 16:41:25 +1000 Subject: [PATCH 02/18] 161888 Add in proper defaults for certificate parameters --- .../azuredeploy.parameters.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json index 0202a2f57e67..12edc87feffd 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json @@ -6,10 +6,10 @@ "value": "GEN-UNIQUE-10" }, "certificateBase64Encoded": { - "value" : "default" + "value" : "GEN-SELFSIGNED-CERT-PFXDATA" }, "certificatePassword": { - "value": "GEN-PASSWORD" + "value": "GEN-SELFSIGNED-CERT-PASSWORD" }, "databaseName": { "value": "lansa" From 3c887c902fde13d05aa749dcafbd3a399ec2170a Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Mon, 23 Sep 2019 16:18:29 +1000 Subject: [PATCH 03/18] 161888 v14.2.0.6 modernization --- .../azuredeploy.json | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index c0a032e298bc..21ae28fa1212 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -11,7 +11,7 @@ }, "vmSku": { "type": "string", - "defaultValue": "Standard_A2", + "defaultValue": "Standard_B4ms", "metadata": { "description": "Size of VMs in the VM Scale Set." } @@ -24,12 +24,26 @@ "minLength" : 3, "maxLength": 61 }, + "applicationGatewaySkuTier": { + "type": "string", + "allowedValues": [ + "Standard", + "WAF" + ], + "defaultValue": "Standard", + "metadata": { + "description": "Application Gateway SKU Tier" + } + }, "applicationGatewaySkuName": { "type": "string", "allowedValues": [ "Standard_Small", "Standard_Medium", - "Standard_Large" + "Standard_Large", + "WAF_Medium", + "WAF_Large", + "WAF_v2" ], "defaultValue": "Standard_Medium", "metadata": { @@ -106,6 +120,11 @@ "S1", "S2", "S3", + "S4", + "S6", + "S7", + "S9", + "S12", "P1", "P2", "P4", @@ -186,7 +205,7 @@ "type": "string", "defaultValue": "0", "metadata": { - "description": "Uninstall the MSI: Set this to 1 to uninstall the MSI. The MSI used to uninstall is the last one that was installed. It is called c:\\lansa\\MyApp.msi" + "description": "Uninstall the MSI: Set this to 1 to uninstall the MSI. The MSI used to uninstall, is the last one that was installed. It is called c:\\lansa\\MyApp.msi" } }, "triggerWebConfig": { @@ -201,7 +220,7 @@ "defaultValue": "lansa-scalable-license", "allowedValues": [ "lansa-scalable-license", - "visuallansa" + "lansa-scalable-license-preview" ], "metadata": { "description": "The offer of the image. Allowed values: lansa-scalable-license, lansa-scalable-license-preview" @@ -255,7 +274,7 @@ "dbnatPoolName": "[concat(variables('namingInfix'), 'dbnatpool')]", "bePoolName": "[concat(variables('namingInfix'), 'bepool')]", "dbbePoolName": "[concat(variables('namingInfix'), 'dbbepool')]", - "dbvmSku": "Standard_A1", + "dbvmSku": "Standard_B2ms", "natStartPort": 50000, "natEndPort": 50119, "natBackendPort": 3389, @@ -263,7 +282,7 @@ "ipConfigName": "[concat(variables('namingInfix'), 'ipconfig')]", "frontEndIPConfigID": "[concat(variables('lbID'),'/frontendIPConfigurations/loadBalancerFrontEnd')]", "imagePublisher": "lansa", - "imageSku": "lansa-scalable-license-14-1", + "imageSku": "lansa-scalable-license-14-2", "osType": { "publisher": "[variables('imagePublisher')]", "offer": "[parameters('imageOffer')]", From f06dc8dbbdd958913f786e5d31d39cba20c230fb Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Mon, 23 Sep 2019 16:20:40 +1000 Subject: [PATCH 04/18] 161888 Pull Request feedback --- .../azuredeploy.json | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index 21ae28fa1212..cfb7b663e6d4 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -687,11 +687,11 @@ "name": "autoscalehost", "location": "[resourceGroup().location]", "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachineScaleSets/', variables('namingInfix'))]" + "[ResourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]" ], "properties": { "name": "autoscalehost", - "targetResourceUri": "[concat('/subscriptions/',subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Compute/virtualMachineScaleSets/', variables('namingInfix'))]", + "targetResourceUri": "[ResourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]", "enabled": true, "profiles": [ { @@ -706,7 +706,7 @@ "metricTrigger": { "metricName": "Percentage CPU", "metricNamespace": "", - "metricResourceUri": "[concat('/subscriptions/',subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Compute/virtualMachineScaleSets/', variables('namingInfix'))]", + "metricResourceUri": "[ResourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]", "timeGrain": "PT1M", "statistic": "Average", "timeWindow": "PT5M", @@ -725,7 +725,7 @@ "metricTrigger": { "metricName": "Percentage CPU", "metricNamespace": "", - "metricResourceUri": "[concat('/subscriptions/',subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Compute/virtualMachineScaleSets/', variables('namingInfix'))]", + "metricResourceUri": "[ResourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]", "timeGrain": "PT1M", "statistic": "Average", "timeWindow": "PT5M", @@ -751,11 +751,11 @@ "name": "[variables('dbvmssName')]", "location": "[resourceGroup().location]", "dependsOn": [ - "[concat('Microsoft.Compute/virtualMachineScaleSets/', variables('dbvmssName'))]" + "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('dbvmssName'))]" ], "properties": { "name": "[variables('dbvmssName')]", - "targetResourceUri": "[concat('/subscriptions/',subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Compute/virtualMachineScaleSets/', variables('dbvmssName'))]", + "targetResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('dbvmssName'))]", "enabled": true, "profiles": [ { @@ -771,7 +771,7 @@ } }, { - "apiVersion": "2015-05-01-preview", + "apiVersion": "2019-08-01", "type": "Microsoft.Network/publicIPAddresses", "name": "[variables('agPublicIPAddressName')]", "location": "[resourceGroup().location]", @@ -783,7 +783,7 @@ } }, { - "apiVersion": "2017-06-01", + "apiVersion": "2019-04-01", "name": "[variables('agName')]", "type": "Microsoft.Network/applicationGateways", "location": "[resourceGroup().location]", @@ -793,9 +793,9 @@ ], "properties": { "sku": { - "name": "[parameters('applicationGatewaySkuName')]", - "tier": "Standard", - "capacity": "[parameters('applicationGatewayCapacity')]" + "tier": "[parameters('applicationGatewaySkuTier')]", + "name": "[parameters('applicationGatewaySkuName')]", + "capacity": "[parameters('applicationGatewayCapacity')]" }, "sslCertificates": [ { From d7148cb50d6f9bc41ea4692111c01b86ac7564eb Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Tue, 22 Oct 2019 16:30:52 +1100 Subject: [PATCH 05/18] 161888 Update CustomScriptExtension version number --- lansa-vmss-windows-autoscale-sql-database/azuredeploy.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index cfb7b663e6d4..8163a78a7156 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -564,7 +564,7 @@ "properties": { "publisher": "Microsoft.Compute", "type": "CustomScriptExtension", - "typeHandlerVersion": "1.8", + "typeHandlerVersion": "1.9", "autoUpgradeMinorVersion": true, "forceUpdateTag": "[concat( parameters('installMSI'),parameters('updateMSI'),parameters('triggerWebConfig'),parameters('UninstallMSI'),parameters('fixLicense'), parameters('trace'), parameters('gitBranch') )]", "settings": { @@ -665,7 +665,7 @@ "properties": { "publisher": "Microsoft.Compute", "type": "CustomScriptExtension", - "typeHandlerVersion": "1.8", + "typeHandlerVersion": "1.9", "autoUpgradeMinorVersion": true, "forceUpdateTag": "[concat( parameters('installMSI'),parameters('updateMSI'),parameters('triggerWebConfig'),parameters('UninstallMSI'),parameters('fixLicense'), parameters('trace'), parameters('gitBranch') )]", "settings": { From ecb7ffaefaa8e30d2d6d0d7e5bf309bf0d059636 Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Tue, 5 Nov 2019 10:17:43 +1100 Subject: [PATCH 06/18] 161888 set date updated --- lansa-vmss-windows-autoscale-sql-database/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/metadata.json b/lansa-vmss-windows-autoscale-sql-database/metadata.json index 9623f0d0a742..2d267c91a02a 100644 --- a/lansa-vmss-windows-autoscale-sql-database/metadata.json +++ b/lansa-vmss-windows-autoscale-sql-database/metadata.json @@ -5,7 +5,7 @@ "description": "The template deploys a Windows VMSS with a desired count of VMs in the scale set and a LANSA MSI to install into each VM. Once the VM Scale Set is deployed a custom script extension is used to install the LANSA MSI)", "summary": "This template deploys a VM Scale Set of Windows VMs behind a load balancer with NAT rules for RDP connections and Auto scale integrated", "githubUsername": "robe070", - "dateUpdated": "2019-05-06" + "dateUpdated": "2019-11-19" } From ff60ebebcf2c907e0f15d64161884cc08d043ed4 Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Tue, 5 Nov 2019 10:42:27 +1100 Subject: [PATCH 07/18] 161888 Update apiVersions --- .../azuredeploy.json | 20 +++++++++---------- .../metadata.json | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index 8163a78a7156..9e6df7875184 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -309,7 +309,7 @@ "type": "Microsoft.Network/virtualNetworks", "name": "[variables('virtualNetworkName')]", "location": "[resourceGroup().location]", - "apiVersion": "2016-03-30", + "apiVersion": "2019-09-01", "properties": { "addressSpace": { "addressPrefixes": [ @@ -336,7 +336,7 @@ "type": "Microsoft.Network/publicIPAddresses", "name": "[variables('publicIPAddressName')]", "location": "[resourceGroup().location]", - "apiVersion": "2016-03-30", + "apiVersion": "2019-09-01", "properties": { "publicIPAllocationMethod": "Dynamic", "dnsSettings": { @@ -348,7 +348,7 @@ "type": "Microsoft.Network/loadBalancers", "name": "[variables('loadBalancerName')]", "location": "[resourceGroup().location]", - "apiVersion": "2016-03-30", + "apiVersion": "2019-09-01", "dependsOn": [ "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]" ], @@ -422,7 +422,7 @@ "type": "Microsoft.Network/publicIPAddresses", "name": "[variables('dbpublicIPAddressName')]", "location": "[resourceGroup().location]", - "apiVersion": "2016-03-30", + "apiVersion": "2019-09-01", "properties": { "publicIPAllocationMethod": "Dynamic", "dnsSettings": { @@ -434,7 +434,7 @@ "type": "Microsoft.Network/loadBalancers", "name": "[variables('dbloadBalancerName')]", "location": "[resourceGroup().location]", - "apiVersion": "2016-03-30", + "apiVersion": "2019-09-01", "dependsOn": [ "[concat('Microsoft.Network/publicIPAddresses/', variables('dbpublicIPAddressName'))]" ], @@ -493,7 +493,7 @@ "type": "Microsoft.Compute/virtualMachineScaleSets", "name": "[variables('dbvmssName')]", "location": "[resourceGroup().location]", - "apiVersion": "2017-03-30", + "apiVersion": "2019-09-01", "dependsOn": [ "[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", @@ -584,7 +584,7 @@ "type": "Microsoft.Compute/virtualMachineScaleSets", "name": "[variables('namingInfix')]", "location": "[resourceGroup().location]", - "apiVersion": "2017-03-30", + "apiVersion": "2019-09-01", "dependsOn": [ "[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", @@ -897,7 +897,7 @@ "tags": { "displayName": "SqlServer" }, - "apiVersion": "2014-04-01", + "apiVersion": "2018-06-01-preview", "properties": { "administratorLogin": "[parameters('databaseLogin')]", "administratorLoginPassword": "[parameters('databaseLoginPassword')]", @@ -911,7 +911,7 @@ "tags": { "displayName": "Database" }, - "apiVersion": "2014-04-01", + "apiVersion": "2018-06-01-preview", "dependsOn": [ "[variables('sqlserverName')]" ], @@ -924,7 +924,7 @@ }, { "type": "firewallRules", - "apiVersion": "2014-04-01", + "apiVersion": "2018-06-01-preview", "dependsOn": [ "[variables('sqlserverName')]" ], diff --git a/lansa-vmss-windows-autoscale-sql-database/metadata.json b/lansa-vmss-windows-autoscale-sql-database/metadata.json index 2d267c91a02a..ab33a055ad90 100644 --- a/lansa-vmss-windows-autoscale-sql-database/metadata.json +++ b/lansa-vmss-windows-autoscale-sql-database/metadata.json @@ -5,7 +5,7 @@ "description": "The template deploys a Windows VMSS with a desired count of VMs in the scale set and a LANSA MSI to install into each VM. Once the VM Scale Set is deployed a custom script extension is used to install the LANSA MSI)", "summary": "This template deploys a VM Scale Set of Windows VMs behind a load balancer with NAT rules for RDP connections and Auto scale integrated", "githubUsername": "robe070", - "dateUpdated": "2019-11-19" + "dateUpdated": "2019-11-04" } From 0910660982d330066da0f1c15dbcec2574a5cf37 Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Tue, 5 Nov 2019 13:07:54 +1100 Subject: [PATCH 08/18] Location variable, go back a version because 2019-09-01 is not yet in the CI checks. Remove parameter no longer valid in new apiversion --- .../azuredeploy.json | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index 9e6df7875184..c02953db79b8 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -1,7 +1,14 @@ { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json", "contentVersion": "1.0.0.0", "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Resource Group Location." + } + }, "msiUri": { "type": "string", "defaultValue": "https://lansalpcmsdn.blob.core.windows.net/app/test/AWAMAPP_v14.1.2_en-us.msi", @@ -75,7 +82,8 @@ "metadata": { "description": "Minimum number of VM instances (1 or more)." }, - "minValue": 1 + "minValue": 1, + "maxValue": 100 }, "maxInstanceCount": { "type": "int", @@ -83,6 +91,7 @@ "metadata": { "description": "Maximum number of VM instances (100 or less)." }, + "minValue": 1, "maxValue": 100 }, "databaseName": { @@ -271,7 +280,6 @@ "lbID": "[resourceId('Microsoft.Network/loadBalancers',variables('loadBalancerName'))]", "dblbID": "[resourceId('Microsoft.Network/loadBalancers',variables('dbloadBalancerName'))]", "natPoolName": "[concat(variables('namingInfix'), 'natpool')]", - "dbnatPoolName": "[concat(variables('namingInfix'), 'dbnatpool')]", "bePoolName": "[concat(variables('namingInfix'), 'bepool')]", "dbbePoolName": "[concat(variables('namingInfix'), 'dbbepool')]", "dbvmSku": "Standard_B2ms", @@ -308,8 +316,8 @@ { "type": "Microsoft.Network/virtualNetworks", "name": "[variables('virtualNetworkName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2019-09-01", + "location": "[parameters('location')]", + "apiVersion": "2019-08-01", "properties": { "addressSpace": { "addressPrefixes": [ @@ -335,8 +343,8 @@ { "type": "Microsoft.Network/publicIPAddresses", "name": "[variables('publicIPAddressName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2019-09-01", + "location": "[parameters('location')]", + "apiVersion": "2019-08-01", "properties": { "publicIPAllocationMethod": "Dynamic", "dnsSettings": { @@ -347,8 +355,8 @@ { "type": "Microsoft.Network/loadBalancers", "name": "[variables('loadBalancerName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2019-09-01", + "location": "[parameters('location')]", + "apiVersion": "2019-08-01", "dependsOn": [ "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]" ], @@ -410,7 +418,6 @@ "protocol": "Http", "port": 80, "intervalInSeconds": 15, - "timeoutInSeconds": 31, "numberOfProbes": 2, "requestPath": "cgi-bin/probe" } @@ -421,8 +428,8 @@ { "type": "Microsoft.Network/publicIPAddresses", "name": "[variables('dbpublicIPAddressName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2019-09-01", + "location": "[parameters('location')]", + "apiVersion": "2019-08-01", "properties": { "publicIPAllocationMethod": "Dynamic", "dnsSettings": { @@ -433,8 +440,8 @@ { "type": "Microsoft.Network/loadBalancers", "name": "[variables('dbloadBalancerName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2019-09-01", + "location": "[parameters('location')]", + "apiVersion": "2019-08-01", "dependsOn": [ "[concat('Microsoft.Network/publicIPAddresses/', variables('dbpublicIPAddressName'))]" ], @@ -482,7 +489,6 @@ "protocol": "Tcp", "port": 3389, "intervalInSeconds": 15, - "timeoutInSeconds": 31, "numberOfProbes": 2 } } @@ -492,8 +498,8 @@ { "type": "Microsoft.Compute/virtualMachineScaleSets", "name": "[variables('dbvmssName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2019-09-01", + "location": "[parameters('location')]", + "apiVersion": "2019-07-01", "dependsOn": [ "[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", @@ -583,8 +589,8 @@ { "type": "Microsoft.Compute/virtualMachineScaleSets", "name": "[variables('namingInfix')]", - "location": "[resourceGroup().location]", - "apiVersion": "2019-09-01", + "location": "[parameters('location')]", + "apiVersion": "2019-07-01", "dependsOn": [ "[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", @@ -685,7 +691,7 @@ "type": "Microsoft.Insights/autoscaleSettings", "apiVersion": "2015-04-01", "name": "autoscalehost", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "dependsOn": [ "[ResourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]" ], @@ -705,7 +711,6 @@ { "metricTrigger": { "metricName": "Percentage CPU", - "metricNamespace": "", "metricResourceUri": "[ResourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]", "timeGrain": "PT1M", "statistic": "Average", @@ -724,7 +729,6 @@ { "metricTrigger": { "metricName": "Percentage CPU", - "metricNamespace": "", "metricResourceUri": "[ResourceId('Microsoft.Compute/virtualMachineScaleSets', variables('namingInfix'))]", "timeGrain": "PT1M", "statistic": "Average", @@ -749,7 +753,7 @@ "type": "Microsoft.Insights/autoscaleSettings", "apiVersion": "2015-04-01", "name": "[variables('dbvmssName')]", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "dependsOn": [ "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('dbvmssName'))]" ], @@ -764,8 +768,7 @@ "minimum": "1", "maximum": "1", "default": "1" - }, - "rules": [] + } } ] } @@ -774,7 +777,7 @@ "apiVersion": "2019-08-01", "type": "Microsoft.Network/publicIPAddresses", "name": "[variables('agPublicIPAddressName')]", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "properties": { "publicIPAllocationMethod": "Dynamic", "dnsSettings": { @@ -786,7 +789,7 @@ "apiVersion": "2019-04-01", "name": "[variables('agName')]", "type": "Microsoft.Network/applicationGateways", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "dependsOn": [ "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", "[concat('Microsoft.Network/publicIPAddresses/', variables('agPublicIPAddressName'))]" @@ -889,7 +892,7 @@ { "name": "[variables('sqlserverName')]", "type": "Microsoft.Sql/servers", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "dependsOn": [ "[concat('Microsoft.Network/loadBalancers/', variables('loadBalancerName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]" @@ -907,7 +910,7 @@ { "name": "[parameters('databaseName')]", "type": "databases", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "tags": { "displayName": "Database" }, @@ -928,7 +931,7 @@ "dependsOn": [ "[variables('sqlserverName')]" ], - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", "name": "AllowAllIps", "properties": { "endIpAddress": "0.0.0.0", From 99f2ce044071804d3a1f6af49e0826f45b5e98d5 Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Tue, 5 Nov 2019 15:05:38 +1100 Subject: [PATCH 09/18] 161888 Test that using variable() for resource id works if variable contains resourceid() --- lansa-vmss-windows-autoscale-sql-database/azuredeploy.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index c02953db79b8..2b183d180d81 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -274,6 +274,9 @@ "dbpublicIPAddressName": "[concat(variables('namingInfix'), 'dbpip')]", "subnetName": "[concat(variables('namingInfix'), 'subnet')]", "loadBalancerName": "[concat(variables('namingInfix'), 'lb')]", + "lbFrontEndName": "LoadBalancerFrontEnd", + "lbBackendPoolName": "LoadBalancerBackEndPool", + "lbProbeName": "loadBalancerHealthProbe", "dbloadBalancerName": "[concat(variables('namingInfix'), 'dblb')]", "publicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]", "dbpublicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',variables('dbpublicIPAddressName'))]", @@ -288,7 +291,7 @@ "natBackendPort": 3389, "nicName": "[concat(variables('namingInfix'), 'nic')]", "ipConfigName": "[concat(variables('namingInfix'), 'ipconfig')]", - "frontEndIPConfigID": "[concat(variables('lbID'),'/frontendIPConfigurations/loadBalancerFrontEnd')]", + "frontEndIPConfigID": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), variables('lbFrontEndName'))]", "imagePublisher": "lansa", "imageSku": "lansa-scalable-license-14-2", "osType": { @@ -363,7 +366,7 @@ "properties": { "frontendIPConfigurations": [ { - "name": "LoadBalancerFrontEnd", + "name": "[variables('lbFrontEndName')]", "properties": { "publicIPAddress": { "id": "[variables('publicIPAddressID')]" From 9916a053bd846ddaea9cf56f5cf2e3791307cb8a Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Tue, 5 Nov 2019 16:47:08 +1100 Subject: [PATCH 10/18] 161888 Fix up resource ids. --- .../azuredeploy.json | 61 +++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index 2b183d180d81..81873d06cb03 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -1,5 +1,5 @@ { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json", + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "location": { @@ -275,13 +275,12 @@ "subnetName": "[concat(variables('namingInfix'), 'subnet')]", "loadBalancerName": "[concat(variables('namingInfix'), 'lb')]", "lbFrontEndName": "LoadBalancerFrontEnd", - "lbBackendPoolName": "LoadBalancerBackEndPool", - "lbProbeName": "loadBalancerHealthProbe", + "lbProbeName": "LoadBalancerProbe", "dbloadBalancerName": "[concat(variables('namingInfix'), 'dblb')]", + "dblbFrontEndName": "dbLoadBalancerFrontEnd", + "dblbProbeName": "dbLoadBalancerProbe", "publicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]", "dbpublicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',variables('dbpublicIPAddressName'))]", - "lbID": "[resourceId('Microsoft.Network/loadBalancers',variables('loadBalancerName'))]", - "dblbID": "[resourceId('Microsoft.Network/loadBalancers',variables('dbloadBalancerName'))]", "natPoolName": "[concat(variables('namingInfix'), 'natpool')]", "bePoolName": "[concat(variables('namingInfix'), 'bepool')]", "dbbePoolName": "[concat(variables('namingInfix'), 'dbbepool')]", @@ -312,7 +311,6 @@ "agSubnetName": "[concat(variables('namingInfix'), '-agsubnet')]", "agSubnetID": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('agsubnetName'))]", "agName": "[concat(variables('namingInfix'), '-ag')]", - "agID": "[resourceId('Microsoft.Network/applicationgateways',variables('agName'))]", "agBackendAddressPoolName": "[concat(variables('namingInfix'), '-agpool')]" }, "resources": [ @@ -401,10 +399,10 @@ "id": "[variables('frontEndIPConfigID')]" }, "backendAddressPool": { - "id": "[concat(variables('lbID'), '/backendAddressPools/', variables('bePoolName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadbalancerName'), variables('bePoolName'))]" }, "probe": { - "id": "[concat(variables('lbID'), '/probes/lbprobe')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadbalancerName'), variables('lbProbeName'))]" }, "protocol": "Tcp", "loadDistribution": "SourceIP", @@ -416,7 +414,7 @@ ], "probes": [ { - "name": "lbprobe", + "name": "[variables('lbProbeName')]", "properties": { "protocol": "Http", "port": 80, @@ -451,7 +449,7 @@ "properties": { "frontendIPConfigurations": [ { - "name": "LoadBalancerFrontEnd", + "name": "[variables('dblbFrontEndName')]", "properties": { "publicIPAddress": { "id": "[variables('dbpublicIPAddressID')]" @@ -469,13 +467,13 @@ "name": "lbrule", "properties": { "frontendIPConfiguration": { - "id": "[concat(variables('dblbID'),'/frontendIPConfigurations/loadBalancerFrontEnd')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('dbloadBalancerName'), variables('dblbFrontEndName'))]" }, "backendAddressPool": { - "id": "[concat(variables('dblbID'), '/backendAddressPools/', variables('dbbePoolName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('dbloadBalancerName'), variables('dbbePoolName'))]" }, "probe": { - "id": "[concat(variables('dblbID'), '/probes/lbprobe')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('dbloadBalancerName'), variables('dblbProbeName'))]" }, "protocol": "Tcp", "loadDistribution": "SourceIP", @@ -487,7 +485,7 @@ ], "probes": [ { - "name": "lbprobe", + "name": "[variables('dblbProbeName')]", "properties": { "protocol": "Tcp", "port": 3389, @@ -552,11 +550,11 @@ "name": "[concat( 'db',variables('ipConfigName'))]", "properties": { "subnet": { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'), '/subnets/', variables('subnetName'))]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]" }, "loadBalancerBackendAddressPools": [ { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('dbloadBalancerName'), '/backendAddressPools/', variables('dbbePoolName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('dbloadBalancerName'), variables('dbbePoolName'))]" } ] } @@ -643,21 +641,21 @@ "name": "[variables('ipConfigName')]", "properties": { "subnet": { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'), '/subnets/', variables('subnetName'))]" - }, - "loadBalancerBackendAddressPools": [ - { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('loadBalancerName'), '/backendAddressPools/', variables('bePoolName'))]" - } - ], + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]" + }, + "loadBalancerBackendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('bePoolName'))]" + } + ], "loadBalancerInboundNatPools": [ { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('loadBalancerName'), '/inboundNatPools/', variables('natPoolName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('loadBalancerName'), variables('natPoolName'))]" } ], "applicationGatewayBackendAddressPools": [ { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/applicationGateways/', variables('agName'), '/backendAddressPools/', variables('agBackendAddressPoolName'))]" + "id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('agName'), variables('agBackendAddressPoolName'))]" } ] } @@ -861,14 +859,15 @@ "name": "appGatewayHttpListener", "properties": { "FrontendIPConfiguration": { - "Id": "[concat(variables('agID'), '/frontendIPConfigurations/appGatewayFrontendIP')]" + "Id": "[resourceId('Microsoft.Network/applicationgateways/frontendIPConfigurations',variables('agName'),'appGatewayFrontendIP')]" + }, "FrontendPort": { - "Id": "[concat(variables('agID'), '/frontendPorts/appGatewayFrontendPort')]" + "Id": "[resourceId('Microsoft.Network/applicationgateways/frontendPorts',variables('agName'),'appGatewayFrontendPort')]" }, "Protocol": "Https", "SslCertificate": { - "Id": "[concat(variables('agID'), '/sslCertificates/appGatewaySslCert')]" + "Id": "[resourceId('Microsoft.Network/applicationgateways/sslCertificates',variables('agName'),'appGatewaySslCert')]" } } } @@ -879,13 +878,13 @@ "properties": { "RuleType": "Basic", "httpListener": { - "id": "[concat(variables('agID'), '/httpListeners/appGatewayHttpListener')]" + "id": "[resourceId('Microsoft.Network/applicationgateways/httpListeners',variables('agName'),'appGatewayHttpListener')]" }, "backendAddressPool": { - "id": "[concat(variables('agID'), '/backendAddressPools/', variables('agBackendAddressPoolName'))]" + "id": "[resourceId('Microsoft.Network/applicationgateways/backendAddressPools',variables('agName'),variables('agBackendAddressPoolName'))]" }, "backendHttpSettings": { - "id": "[concat(variables('agID'), '/backendHttpSettingsCollection/appGatewayBackendHttpSettings')]" + "id": "[resourceId('Microsoft.Network/applicationgateways/backendHttpSettingsCollection',variables('agName'),'appGatewayBackendHttpSettings')]" } } } From a605c4d8e797085417ba4245ab27ac7c94bf8c13 Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Wed, 6 Nov 2019 16:16:26 +1100 Subject: [PATCH 11/18] 161888 use more variables --- .../azuredeploy.json | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index 81873d06cb03..67f2c316f539 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -311,6 +311,11 @@ "agSubnetName": "[concat(variables('namingInfix'), '-agsubnet')]", "agSubnetID": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('agsubnetName'))]", "agName": "[concat(variables('namingInfix'), '-ag')]", + "agHttpListenerName": "appGatewayHttpListener", + "agFrontendIPName": "appGatewayFrontendIP", + "agFrontendPortName": "appGatewayFrontendPort", + "agSslCertName": "appGatewaySslCert", + "agBackendHttpSettingsName": "appGatewayBackendHttpSettings", "agBackendAddressPoolName": "[concat(variables('namingInfix'), '-agpool')]" }, "resources": [ @@ -803,7 +808,7 @@ }, "sslCertificates": [ { - "name": "appGatewaySslCert", + "name": "[variables('agSslCertName')]", "properties": { "data": "[parameters('certificateBase64Encoded')]", "password": "[parameters('certificatePassword')]" @@ -822,7 +827,7 @@ ], "frontendIPConfigurations": [ { - "name": "appGatewayFrontendIP", + "name": "[variables('agFrontendIPName')]", "properties": { "PublicIPAddress": { "id": "[variables('agPublicIPAddressID')]" @@ -832,7 +837,7 @@ ], "frontendPorts": [ { - "name": "appGatewayFrontendPort", + "name": "[variables('agFrontendPortName')]", "properties": { "Port": 443 } @@ -845,7 +850,7 @@ ], "backendHttpSettingsCollection": [ { - "name": "appGatewayBackendHttpSettings", + "name": "[variables('agBackendHttpSettingsName')]", "properties": { "Port": 80, "Protocol": "Http", @@ -856,18 +861,18 @@ ], "httpListeners": [ { - "name": "appGatewayHttpListener", + "name": "[variables('agHttpListenerName')]", "properties": { "FrontendIPConfiguration": { - "Id": "[resourceId('Microsoft.Network/applicationgateways/frontendIPConfigurations',variables('agName'),'appGatewayFrontendIP')]" + "Id": "[resourceId('Microsoft.Network/applicationgateways/frontendIPConfigurations',variables('agName'),variables('agFrontendIPName'))]" }, "FrontendPort": { - "Id": "[resourceId('Microsoft.Network/applicationgateways/frontendPorts',variables('agName'),'appGatewayFrontendPort')]" + "Id": "[resourceId('Microsoft.Network/applicationgateways/frontendPorts',variables('agName'),variables('agFrontendPortName'))]" }, "Protocol": "Https", "SslCertificate": { - "Id": "[resourceId('Microsoft.Network/applicationgateways/sslCertificates',variables('agName'),'appGatewaySslCert')]" + "Id": "[resourceId('Microsoft.Network/applicationgateways/sslCertificates',variables('agName'),variables('agSslCertName'))]" } } } @@ -878,13 +883,13 @@ "properties": { "RuleType": "Basic", "httpListener": { - "id": "[resourceId('Microsoft.Network/applicationgateways/httpListeners',variables('agName'),'appGatewayHttpListener')]" + "id": "[resourceId('Microsoft.Network/applicationgateways/httpListeners',variables('agName'),variables('agHttpListenerName'))]" }, "backendAddressPool": { "id": "[resourceId('Microsoft.Network/applicationgateways/backendAddressPools',variables('agName'),variables('agBackendAddressPoolName'))]" }, "backendHttpSettings": { - "id": "[resourceId('Microsoft.Network/applicationgateways/backendHttpSettingsCollection',variables('agName'),'appGatewayBackendHttpSettings')]" + "id": "[resourceId('Microsoft.Network/applicationgateways/backendHttpSettingsCollection',variables('agName'),variables('agBackendHttpSettingsName'))]" } } } From 91d2fd2857409c9cefdb6df4b6ee7aa4897a4dbd Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Thu, 7 Nov 2019 17:58:11 +1100 Subject: [PATCH 12/18] 161888 Convert template to conditionally use either a new or existing SQL database --- .../azuredeploy.json | 116 +++++++++++------- .../azuredeploy.parameters.json | 6 + 2 files changed, 80 insertions(+), 42 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index 67f2c316f539..bc3868ff5f6e 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -9,24 +9,24 @@ "description": "Resource Group Location." } }, - "msiUri": { + "msiURL": { "type": "string", "defaultValue": "https://lansalpcmsdn.blob.core.windows.net/app/test/AWAMAPP_v14.1.2_en-us.msi", "metadata": { - "description": "URL of the LANSA MSI to install on each VM." + "description": "URL of the LANSA MSI which will be installed on each virtual machine." } }, - "vmSku": { + "virtualMachineSize": { "type": "string", "defaultValue": "Standard_B4ms", "metadata": { - "description": "Size of VMs in the VM Scale Set." + "description": "Size of the Virtual Machines in the Virtual Machine Scale Set." } }, - "vmssName": { + "stackName": { "type": "string", "metadata": { - "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended." + "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended. Some identifiers use precisely 9 characters from this name and so it can be useful to use exactly 9. The template pads it out or truncates it as necessary to make it 9 characters long where required." }, "minLength" : 3, "maxLength": 61 @@ -76,36 +76,79 @@ "description": "SSL certificate password" } }, - "minInstanceCount": { + "minimumInstanceCount": { "type": "int", "defaultValue": 1, "metadata": { - "description": "Minimum number of VM instances (1 or more)." + "description": "Minimum number of Virtual Machine instances (1 or more)." }, "minValue": 1, "maxValue": 100 }, - "maxInstanceCount": { + "maximumInstanceCount": { "type": "int", "defaultValue": 100, "metadata": { - "description": "Maximum number of VM instances (100 or less)." + "description": "Maximum number of Virtual Machine instances (100 or less)." }, "minValue": 1, "maxValue": 100 }, + "databaseNewOrExisting": { + "type": "string", + "defaultValue": "new", + "allowedValues": [ + "new", + "existing" + ], + "metadata": { + "description": "Determines whether a new SQL database should be provisioned or to use an existing database. Parameters which are relevant to choosing 'new' are prefixed 'New DB'. Parameters which are relevant to choosing 'existing' are prefixed 'Existing DB'." + } + }, + "databaseType": { + "type": "string", + "defaultValue": "SQLAZURE", + "allowedValues": [ + "MSSQLS", + "SQLAZURE", + "MYSQL" + ], + "metadata": { + "description": "Existing DB. Refer to LANSA documentation for an explanation of each Database Type and the supported versions of the database servers. DO NOT CHANGE THIS IF CREATING A NEW DATABASE. IT MUST BE SET TO SQLAZURE." + } + }, + "databaseServerName": { + "type": "string", + "defaultValue": "lansa", + "metadata": { + "description": "Existing DB. The name of the existing Database Server to connect to. If the name has /MSSQLSERVER appended, omit it." + } + }, "databaseName": { "type": "string", "defaultValue": "lansa", "metadata": { - "description": "The name of the new database to create." + "description": "The name of the new database to create or name of the existing database to connect to." + } + }, + "databaseLogin": { + "type": "string", + "metadata": { + "description": "The admin user of the Azure SQL Database" } }, + "databaseLoginPassword": { + "type": "securestring", + "metadata": { + "description": "The password of the admin user of the Azure SQL Database" + } + + }, "collation": { "type": "string", "defaultValue": "SQL_Latin1_General_CP1_CI_AS", "metadata": { - "description": "The database collation for governing the proper use of characters." + "description": "New DB. The new database collation for governing the proper use of characters." } }, "edition": { @@ -117,7 +160,7 @@ "Premium" ], "metadata": { - "description": "The type of database to create." + "description": "New DB. The type of database to create." } }, "requestedServiceObjectiveName": { @@ -142,14 +185,14 @@ "P15" ], "metadata": { - "description": "Describes the performance level for Edition" + "description": "New DB. Describes the performance level for Edition" } }, "maxSizeBytes": { "type": "string", "defaultValue": "1073741824", "metadata": { - "description": "The maximum size, in bytes, for the database" + "description": "New DB. The maximum size, in bytes, for the new database" } }, "adminUsername": { @@ -176,19 +219,6 @@ "description": "Web Server password on all VMs." } }, - "databaseLogin": { - "type": "string", - "metadata": { - "description": "The admin user of the Azure SQL Database" - } - }, - "databaseLoginPassword": { - "type": "securestring", - "metadata": { - "description": "The password of the admin user of the Azure SQL Database" - } - - }, "webServerMaxConnect": { "type": "string", "defaultValue": "20", @@ -257,16 +287,17 @@ "type": "string", "defaultValue": "0", "metadata": { - "description": "Re-run licensing" + "description": "Re-run licensing. It is unlikely that this parameter needs to be used" } } }, "variables": { - "namingInfix": "[toLower(substring(concat(parameters('vmssName'), uniqueString(resourceGroup().id)), 0, 9))]", - "longNamingInfix": "[toLower(parameters('vmssName'))]", - "dblongNamingInfix": "[toLower(concat('db',parameters('vmssName')))]", - "aglongNamingInfix": "[toLower(concat('ag',parameters('vmssName')))]", - "dbvmssName": "[toLower(substring(concat('db',parameters('vmssName'), uniqueString(resourceGroup().id)), 0, 9))]", + "isNewDatabase": "[equals(parameters('databaseNewOrExisting'), 'new')]", + "namingInfix": "[toLower(substring(concat(parameters('stackName'), uniqueString(resourceGroup().id)), 0, 9))]", + "longNamingInfix": "[toLower(parameters('stackName'))]", + "dblongNamingInfix": "[toLower(concat('db',parameters('stackName')))]", + "aglongNamingInfix": "[toLower(concat('ag',parameters('stackName')))]", + "dbvmssName": "[toLower(substring(concat('db',parameters('stackName'), uniqueString(resourceGroup().id)), 0, 9))]", "addressPrefix": "10.0.0.0/16", "subnetPrefix": "10.0.0.0/24", "virtualNetworkName": "[concat(variables('namingInfix'), 'vnet')]", @@ -583,7 +614,7 @@ "fileUris": [ "[variables('gitRefreshUri')]" ] }, "protectedSettings": { - "commandToExecute": "[concat('powershell -NoProfile -ExecutionPolicy unrestricted -command \"& {pushd;./',variables('gitRefreshName'), ' ', parameters('gitBranch'), ';popd;', 'pushd;c:\\lansa\\scripts\\azure-custom-script.ps1 ', '-server_name ',variables('Q'), reference(variables('sqlserverName')).fullyQualifiedDomainName, variables('Q'), ' -DBUT ', variables('Q'), 'SQLAZURE', variables('Q'), ' -dbname ', variables('Q'), parameters('databaseName'), variables('Q'), ' -dbuser ', variables('Q'), parameters('databaseLogin'), variables('Q'), ' -dbpassword ', variables('Q'), parameters('databaseLoginPassword'), variables('Q'), ' -webuser ', variables('Q'), parameters('webUsername'), variables('Q'), ' -webpassword ', variables('Q'), parameters('webPassword'), variables('Q'), ' -MSIuri ', variables('Q'), parameters('msiUri'), variables('Q'), ' -maxconnections ', variables('Q'), parameters('webServerMaxConnect'), variables('Q'), ' -trace ', variables('Q'), parameters('trace'), variables('Q'), ' -installMSI ', variables('Q'), parameters('installMSI'), variables('Q'), ' -updateMSI ', variables('Q'), parameters('updateMSI'), variables('Q'),' -triggerWebConfig ', variables('Q'), parameters('triggerWebConfig'), variables('Q'),' -UninstallMSI ', variables('Q'), parameters('UninstallMSI'), variables('Q'), ' -fixLicense ', variables('Q'), parameters('fixLicense'), variables('Q'), ';if ($LASTEXITCODE -ne 0) {Write-Error (\"MSI Install failed\");exit $LASTEXITCODE}; exit 0;popd;}\"')]" + "commandToExecute": "[concat('powershell -NoProfile -ExecutionPolicy unrestricted -command \"& {pushd;./',variables('gitRefreshName'), ' ', parameters('gitBranch'), ';popd;', 'pushd;c:\\lansa\\scripts\\azure-custom-script.ps1 ', '-server_name ',variables('Q'), if(variables('isNewDatabase'), reference(variables('sqlserverName')).fullyQualifiedDomainName, parameters('databaseServerName')), variables('Q'), ' -DBUT ', variables('Q'), parameters('databaseType'), variables('Q'), ' -dbname ', variables('Q'), parameters('databaseName'), variables('Q'), ' -dbuser ', variables('Q'), parameters('databaseLogin'), variables('Q'), ' -dbpassword ', variables('Q'), parameters('databaseLoginPassword'), variables('Q'), ' -webuser ', variables('Q'), parameters('webUsername'), variables('Q'), ' -webpassword ', variables('Q'), parameters('webPassword'), variables('Q'), ' -MSIuri ', variables('Q'), parameters('msiURL'), variables('Q'), ' -maxconnections ', variables('Q'), parameters('webServerMaxConnect'), variables('Q'), ' -trace ', variables('Q'), parameters('trace'), variables('Q'), ' -installMSI ', variables('Q'), parameters('installMSI'), variables('Q'), ' -updateMSI ', variables('Q'), parameters('updateMSI'), variables('Q'),' -triggerWebConfig ', variables('Q'), parameters('triggerWebConfig'), variables('Q'),' -UninstallMSI ', variables('Q'), parameters('UninstallMSI'), variables('Q'), ' -fixLicense ', variables('Q'), parameters('fixLicense'), variables('Q'), ';if ($LASTEXITCODE -ne 0) {Write-Error (\"MSI Install failed\");exit $LASTEXITCODE}; exit 0;popd;}\"')]" } } } @@ -605,9 +636,9 @@ "[concat('Microsoft.Compute/virtualMachineScaleSets/', variables('dbvmssName'))]" ], "sku": { - "name": "[parameters('vmSku')]", + "name": "[parameters('virtualMachineSize')]", "tier": "Standard", - "capacity": "[parameters('minInstanceCount')]" + "capacity": "[parameters('minimumInstanceCount')]" }, "plan": { "name": "[variables('imageSKU')]", @@ -684,7 +715,7 @@ "fileUris": [ "[variables('gitRefreshUri')]" ] }, "protectedSettings": { - "commandToExecute": "[concat('powershell -NoProfile -ExecutionPolicy unrestricted -command \"& {pushd;./',variables('gitRefreshName'), ' ', parameters('gitBranch'), ';popd;', 'pushd;c:\\lansa\\scripts\\azure-custom-script.ps1 ', '-SUDB \"0\" -server_name ', variables('Q'), reference(variables('sqlserverName')).fullyQualifiedDomainName, variables('Q'), ' -DBUT ', variables('Q'), 'SQLAZURE', variables('Q'), ' -dbname ', variables('Q'), parameters('databaseName'), variables('Q'), ' -dbuser ', variables('Q'), parameters('databaseLogin'), variables('Q'), ' -dbpassword ', variables('Q'), parameters('databaseLoginPassword'), variables('Q'), ' -webuser ', variables('Q'), parameters('webUsername'), variables('Q'), ' -webpassword ', variables('Q'), parameters('webPassword'), variables('Q'), ' -MSIuri ', variables('Q'), parameters('msiUri'), variables('Q'), ' -maxconnections ', variables('Q'), parameters('webServerMaxConnect'), variables('Q'), ' -trace ', variables('Q'), parameters('trace'), variables('Q'), ' -installMSI ', variables('Q'), parameters('installMSI'), variables('Q'), ' -updateMSI ', variables('Q'), parameters('updateMSI'), variables('Q'),' -triggerWebConfig ', variables('Q'), parameters('triggerWebConfig'), variables('Q'), ' -UninstallMSI ', variables('Q'), parameters('UninstallMSI'), variables('Q'), ' -fixLicense ', variables('Q'), parameters('fixLicense'), variables('Q'), ';if ($LASTEXITCODE -ne 0) {Write-Error (\"MSI Install failed\");exit $LASTEXITCODE}; exit 0;popd;}\"')]" + "commandToExecute": "[concat('powershell -NoProfile -ExecutionPolicy unrestricted -command \"& {pushd;./',variables('gitRefreshName'), ' ', parameters('gitBranch'), ';popd;', 'pushd;c:\\lansa\\scripts\\azure-custom-script.ps1 ', '-SUDB \"0\" -server_name ', variables('Q'), if(variables('isNewDatabase'), reference(variables('sqlserverName')).fullyQualifiedDomainName, parameters('databaseServerName')), variables('Q'), ' -DBUT ', variables('Q'), parameters('databaseType'), variables('Q'), ' -dbname ', variables('Q'), parameters('databaseName'), variables('Q'), ' -dbuser ', variables('Q'), parameters('databaseLogin'), variables('Q'), ' -dbpassword ', variables('Q'), parameters('databaseLoginPassword'), variables('Q'), ' -webuser ', variables('Q'), parameters('webUsername'), variables('Q'), ' -webpassword ', variables('Q'), parameters('webPassword'), variables('Q'), ' -MSIuri ', variables('Q'), parameters('msiURL'), variables('Q'), ' -maxconnections ', variables('Q'), parameters('webServerMaxConnect'), variables('Q'), ' -trace ', variables('Q'), parameters('trace'), variables('Q'), ' -installMSI ', variables('Q'), parameters('installMSI'), variables('Q'), ' -updateMSI ', variables('Q'), parameters('updateMSI'), variables('Q'),' -triggerWebConfig ', variables('Q'), parameters('triggerWebConfig'), variables('Q'), ' -UninstallMSI ', variables('Q'), parameters('UninstallMSI'), variables('Q'), ' -fixLicense ', variables('Q'), parameters('fixLicense'), variables('Q'), ';if ($LASTEXITCODE -ne 0) {Write-Error (\"MSI Install failed\");exit $LASTEXITCODE}; exit 0;popd;}\"')]" } } } @@ -709,9 +740,9 @@ { "name": "Profile1", "capacity": { - "minimum": "[parameters('minInstanceCount')]", - "maximum": "[parameters('maxInstanceCount')]", - "default": "[parameters('minInstanceCount')]" + "minimum": "[parameters('minimumInstanceCount')]", + "maximum": "[parameters('maximumInstanceCount')]", + "default": "[parameters('minimumInstanceCount')]" }, "rules": [ { @@ -897,6 +928,7 @@ } }, { + "condition": "[equals(parameters('databaseNewOrExisting'), 'new')]", "name": "[variables('sqlserverName')]", "type": "Microsoft.Sql/servers", "location": "[parameters('location')]", @@ -951,7 +983,7 @@ "outputs": { "dbServerName": { "type": "string", - "value": "[reference(variables('sqlserverName')).fullyQualifiedDomainName]" + "value": "[if(variables('isNewDatabase'), reference(variables('sqlserverName')).fullyQualifiedDomainName, parameters('databaseServerName'))]" }, "dbName": { "type": "string", diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json index 12edc87feffd..e4a39e32dac7 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json @@ -11,6 +11,12 @@ "certificatePassword": { "value": "GEN-SELFSIGNED-CERT-PASSWORD" }, + "databaseNewOrExisting": { + "value": "new" + }, + "databaseServerName": { + "value": "GEN-UNIQUE-10" + }, "databaseName": { "value": "lansa" }, From 66cfc76a5026ea9b82cd59cdc609513161d49709 Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Fri, 8 Nov 2019 09:55:48 +1100 Subject: [PATCH 13/18] 161888 Doco and initial commit to Pull Request --- lansa-vmss-windows-autoscale-sql-database/README.md | 8 ++++---- .../azuredeploy.json | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/README.md b/lansa-vmss-windows-autoscale-sql-database/README.md index 9d7e34f5c0ec..5b7f262733e2 100644 --- a/lansa-vmss-windows-autoscale-sql-database/README.md +++ b/lansa-vmss-windows-autoscale-sql-database/README.md @@ -45,13 +45,13 @@ The Autoscale rules are configured as follows + One Virtual Machine Scale Set to contain the single virtual machine which is responsible for configuring the database + One Virtual Machine Scale Set to contain the number of web servers requested by the deployer + The Virtual Machines are all instantiated from the Marketplace LANSA SKU lansa-scalable-license. There is a software cost for using this image. [Click here](https://azure.microsoft.com/en-us/marketplace/partners/lansa/lansa-scalable-license/) for details. -+ One Azure SQL Database server with one database, configured as per settings provided by the deployer ++ Optionally, one Azure SQL Database server with one database, configured as per settings provided by the deployer ## Prerequisites Before deploying this template you must: -- Construct your LANSA application using [Visual LANSA for Web Development](https://azure.microsoft.com/en-us/marketplace/partners/lansa/visuallansa/) Version 14.1 with EPCs 141010, 141011 and 141013 applied, or later. -- Construct a deployment image MSI using the LANSA Deployment Tool provided with [Visual LANSA for Web Development](https://azure.microsoft.com/en-us/marketplace/partners/lansa/visuallansa/). +- Construct your LANSA application using [Visual LANSA](https://www.lansa.com/products/visual-lansa.htm) Version 14.1 with EPCs 141010, 141011 and 141013 applied, or later. +- Construct a deployment image MSI using the LANSA Deployment Tool provided with [Visual LANSA](https://www.lansa.com/products/visual-lansa.htm). - Upload your LANSA Web Application MSI to Azure BLOB storage and obtain the URL of the MSI. Note that the template includes a demonstration application so it is not strictly necessary to create a LANSA MSI in order to use the template. - Obtain an SSL certificate for your web site and convert it to a base64 encoded string. To get the certificate data from a pfx file in PowerShell you can use this: [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("path to pfx file")) - Its also highly recommended to follow the usage instructions below :) @@ -63,7 +63,7 @@ For full instructions for using this template go to [Azure Deployment Tutorial]( ## Notes -1. Two VMSS. One to install the database; 1 to run the web site. OverProvision = false. This is so that extra VMs are not created which would put more load on the database which slows down provisioning. Failure to provision has not been seen. A second reason is that the database installer VMSS MUST NEVER have more than 1 instance installing at a time. Errors occur when publishing the weblets. As well as the database state not being matched to what the VM thinks the state of the database is in terms of table creation, etc. +1. Two VMSS. One to install the database; one to run the web site. OverProvision = false. This is so that extra VMs are not created which would put more load on the database which slows down provisioning. Failure to provision has not been seen. A second reason is that the database installer VMSS MUST NEVER have more than 1 instance installing at a time. Errors occur when publishing the weblets. As well as the database state not being matched to what the VM thinks the state of the database is in terms of table creation, etc. 1. Database VMSS 1. Only 1 instance ever. If instance dies another one is created. 2. This instance is not currently used by the web site as 1 load balancer may only be configured for a single VMSS. diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index bc3868ff5f6e..b07a3121c763 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -947,6 +947,7 @@ }, "resources": [ { + "condition": "[equals(parameters('databaseNewOrExisting'), 'new')]", "name": "[parameters('databaseName')]", "type": "databases", "location": "[parameters('location')]", @@ -965,6 +966,7 @@ } }, { + "condition": "[equals(parameters('databaseNewOrExisting'), 'new')]", "type": "firewallRules", "apiVersion": "2018-06-01-preview", "dependsOn": [ From 7c33710c5307fdb95409709328d25ed619de1f93 Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Fri, 8 Nov 2019 15:23:06 +1100 Subject: [PATCH 14/18] 161888 Change to new git branch --- lansa-vmss-windows-autoscale-sql-database/azuredeploy.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index b07a3121c763..b2d8b9ec3af6 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -251,7 +251,7 @@ "type": "string", "defaultValue": "0", "metadata": { - "description": "Update Stack: Set this to 1 to update the web configuration" + "description": "Update Stack: Set this to 1 to update the web configuration" } }, "imageOffer": { @@ -267,7 +267,7 @@ }, "gitBranch": { "type": "string", - "defaultValue": "support/L4W14000_scalable_azure", + "defaultValue": "support/L4W14200_scalable", "metadata": { "description": "Git Branch" } From c6297dcb9356857a456cec4b72fcc17a67364e3a Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Fri, 8 Nov 2019 15:35:31 +1100 Subject: [PATCH 15/18] 161888 Rename parameter in parameters file --- .../azuredeploy.parameters.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json index e4a39e32dac7..470e1a948770 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json @@ -2,7 +2,7 @@ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { - "vmssName": { + "stackName": { "value": "GEN-UNIQUE-10" }, "certificateBase64Encoded": { From ac372454882fe17e64914dcd561597071eb07db3 Mon Sep 17 00:00:00 2001 From: Brian Moore Date: Tue, 10 Dec 2019 10:02:14 -0600 Subject: [PATCH 16/18] Update metadata.json --- .../metadata.json | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/metadata.json b/lansa-vmss-windows-autoscale-sql-database/metadata.json index ab33a055ad90..4c15519656a7 100644 --- a/lansa-vmss-windows-autoscale-sql-database/metadata.json +++ b/lansa-vmss-windows-autoscale-sql-database/metadata.json @@ -1,11 +1,12 @@ { "$schema": "https://aka.ms/azure-quickstart-templates-metadata-schema#", "type": "QuickStart", - "itemDisplayName": "Autoscale LANSA Windows VM ScaleSet with Azure SQL Database", - "description": "The template deploys a Windows VMSS with a desired count of VMs in the scale set and a LANSA MSI to install into each VM. Once the VM Scale Set is deployed a custom script extension is used to install the LANSA MSI)", - "summary": "This template deploys a VM Scale Set of Windows VMs behind a load balancer with NAT rules for RDP connections and Auto scale integrated", - "githubUsername": "robe070", - "dateUpdated": "2019-11-04" + "environments": [ + "AzureCloud" + ], + "itemDisplayName": "Autoscale LANSA Windows VM ScaleSet with Azure SQL Database", + "description": "The template deploys a Windows VMSS with a desired count of VMs in the scale set and a LANSA MSI to install into each VM. Once the VM Scale Set is deployed a custom script extension is used to install the LANSA MSI)", + "summary": "This template deploys a VM Scale Set of Windows VMs behind a load balancer with NAT rules for RDP connections and Auto scale integrated", + "githubUsername": "robe070", + "dateUpdated": "2019-11-04" } - - From de67212f713d28705e9427f178bc2d7bef672c83 Mon Sep 17 00:00:00 2001 From: Rob Goodridge Date: Thu, 12 Dec 2019 09:41:05 +1100 Subject: [PATCH 17/18] 161888 Apply changes requested by reviewer --- .../azuredeploy.json | 10 +++++-- .../azuredeploy.parameters.json | 27 ------------------- 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json index b2d8b9ec3af6..2dfcc8dc5545 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.json @@ -23,6 +23,13 @@ "description": "Size of the Virtual Machines in the Virtual Machine Scale Set." } }, + "dbVirtualMachineSize": { + "type": "string", + "defaultValue": "Standard_B2ms", + "metadata": { + "description": "Size of the Virtual Machine which manages the database." + } + }, "stackName": { "type": "string", "metadata": { @@ -315,7 +322,6 @@ "natPoolName": "[concat(variables('namingInfix'), 'natpool')]", "bePoolName": "[concat(variables('namingInfix'), 'bepool')]", "dbbePoolName": "[concat(variables('namingInfix'), 'dbbepool')]", - "dbvmSku": "Standard_B2ms", "natStartPort": 50000, "natEndPort": 50119, "natBackendPort": 3389, @@ -545,7 +551,7 @@ "[concat('Microsoft.Network/applicationGateways/', variables('agName'))]" ], "sku": { - "name": "[variables('dbvmSku')]", + "name": "[parameters('dbVirtualMachineSize')]", "tier": "Standard", "capacity": 1 }, diff --git a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json index 470e1a948770..bf5528b669c3 100644 --- a/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json +++ b/lansa-vmss-windows-autoscale-sql-database/azuredeploy.parameters.json @@ -11,15 +11,9 @@ "certificatePassword": { "value": "GEN-SELFSIGNED-CERT-PASSWORD" }, - "databaseNewOrExisting": { - "value": "new" - }, "databaseServerName": { "value": "GEN-UNIQUE-10" }, - "databaseName": { - "value": "lansa" - }, "databaseLogin": { "value": "GEN-UNIQUE-10" }, @@ -38,26 +32,5 @@ "webPassword": { "value": "GEN-PASSWORD" }, - "webServerMaxConnect": { - "value": "20" - }, - "triggerWebConfig": { - "value": "0" - }, - "installMSI": { - "value": "0" - }, - "updateMSI": { - "value": "0" - }, - "uninstallMSI": { - "value": "0" - }, - "trace": { - "value": "N" - }, - "fixLicense": { - "value": "0" - } } } From 8bd4ab57db6dfe3c91d55fcb7d6de6ed7036918c Mon Sep 17 00:00:00 2001 From: Brian Moore Date: Mon, 6 Jan 2020 12:27:59 -0600 Subject: [PATCH 18/18] Delete Deploy-AzureResourceGroup.ps1 --- .../Scripts/Deploy-AzureResourceGroup.ps1 | 103 ------------------ 1 file changed, 103 deletions(-) delete mode 100644 lansa-vmss-windows-autoscale-sql-database/Scripts/Deploy-AzureResourceGroup.ps1 diff --git a/lansa-vmss-windows-autoscale-sql-database/Scripts/Deploy-AzureResourceGroup.ps1 b/lansa-vmss-windows-autoscale-sql-database/Scripts/Deploy-AzureResourceGroup.ps1 deleted file mode 100644 index ea8d7d72ec89..000000000000 --- a/lansa-vmss-windows-autoscale-sql-database/Scripts/Deploy-AzureResourceGroup.ps1 +++ /dev/null @@ -1,103 +0,0 @@ -#Requires -Version 3.0 -#Requires -Module Az.Resources -#Requires -Module Az.Storage - -Param( - [string] [Parameter(Mandatory=$true)] $ResourceGroupLocation, - [string] [Parameter(Mandatory=$true)] $ResourceGroupName, - [switch] $UploadArtifacts, - [string] $StorageAccountName, - [string] $StorageContainerName = $ResourceGroupName.ToLowerInvariant() + '-stageartifacts', - [string] $TemplateFile = '..\azuredeploy.json', - [string] $TemplateParametersFile = '..\azuredeploy.parameters.json', - [string] $ArtifactStagingDirectory = '..\bin\Debug\staging', - [string] $DSCSourceFolder = '..\DSC' -) - -Enable-AzureRmAlias - -try { - [Microsoft.Azure.Common.Authentication.AzureSession]::ClientFactory.AddUserAgent("VSAzureTools-$UI$($host.name)".replace(" ","_"), "2.9") -} catch { } - -Set-StrictMode -Version 3 - -$OptionalParameters = New-Object -TypeName Hashtable -$TemplateFile = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $TemplateFile)) -$TemplateParametersFile = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $TemplateParametersFile)) - -if ($UploadArtifacts) { - # Convert relative paths to absolute paths if needed - $ArtifactStagingDirectory = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $ArtifactStagingDirectory)) - $DSCSourceFolder = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, $DSCSourceFolder)) - - Set-Variable ArtifactsLocationName '_artifactsLocation' -Option ReadOnly -Force - Set-Variable ArtifactsLocationSasTokenName '_artifactsLocationSasToken' -Option ReadOnly -Force - - $OptionalParameters.Add($ArtifactsLocationName, $null) - $OptionalParameters.Add($ArtifactsLocationSasTokenName, $null) - - # Parse the parameter file and update the values of artifacts location and artifacts location SAS token if they are present - $JsonContent = Get-Content $TemplateParametersFile -Raw | ConvertFrom-Json - $JsonParameters = $JsonContent | Get-Member -Type NoteProperty | Where-Object {$_.Name -eq "parameters"} - - if ($JsonParameters -eq $null) { - $JsonParameters = $JsonContent - } - else { - $JsonParameters = $JsonContent.parameters - } - - $JsonParameters | Get-Member -Type NoteProperty | ForEach-Object { - $ParameterValue = $JsonParameters | Select-Object -ExpandProperty $_.Name - - if ($_.Name -eq $ArtifactsLocationName -or $_.Name -eq $ArtifactsLocationSasTokenName) { - $OptionalParameters[$_.Name] = $ParameterValue.value - } - } - - # Create DSC configuration archive - if (Test-Path $DSCSourceFolder) { - Add-Type -Assembly System.IO.Compression.FileSystem - $ArchiveFile = Join-Path $ArtifactStagingDirectory "dsc.zip" - Remove-Item -Path $ArchiveFile -ErrorAction SilentlyContinue - [System.IO.Compression.ZipFile]::CreateFromDirectory($DSCSourceFolder, $ArchiveFile) - } - - $StorageAccountContext = (Get-AzureRmStorageAccount | Where-Object{$_.StorageAccountName -eq $StorageAccountName}).Context - - # Generate the value for artifacts location if it is not provided in the parameter file - $ArtifactsLocation = $OptionalParameters[$ArtifactsLocationName] - if ($ArtifactsLocation -eq $null) { - $ArtifactsLocation = $StorageAccountContext.BlobEndPoint + $StorageContainerName - $OptionalParameters[$ArtifactsLocationName] = $ArtifactsLocation - } - - # Copy files from the local storage staging location to the storage account container - New-AzureStorageContainer -Name $StorageContainerName -Context $StorageAccountContext -Permission Container -ErrorAction SilentlyContinue *>&1 - - $ArtifactFilePaths = Get-ChildItem $ArtifactStagingDirectory -Recurse -File | ForEach-Object -Process {$_.FullName} - foreach ($SourcePath in $ArtifactFilePaths) { - $BlobName = $SourcePath.Substring($ArtifactStagingDirectory.length + 1) - Set-AzureStorageBlobContent -File $SourcePath -Blob $BlobName -Container $StorageContainerName -Context $StorageAccountContext -Force - } - - # Generate the value for artifacts location SAS token if it is not provided in the parameter file - $ArtifactsLocationSasToken = $OptionalParameters[$ArtifactsLocationSasTokenName] - if ($ArtifactsLocationSasToken -eq $null) { - # Create a SAS token for the storage container - this gives temporary read-only access to the container - $ArtifactsLocationSasToken = New-AzureStorageContainerSASToken -Container $StorageContainerName -Context $StorageAccountContext -Permission r -ExpiryTime (Get-Date).AddHours(4) - $ArtifactsLocationSasToken = ConvertTo-SecureString $ArtifactsLocationSasToken -AsPlainText -Force - $OptionalParameters[$ArtifactsLocationSasTokenName] = $ArtifactsLocationSasToken - } -} - -# Create or update the resource group using the specified template file and template parameters file -New-AzureRmResourceGroup -Name $ResourceGroupName -Location $ResourceGroupLocation -Verbose -Force -ErrorAction Stop - -New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $TemplateFile).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) ` - -ResourceGroupName $ResourceGroupName ` - -TemplateFile $TemplateFile ` - -TemplateParameterFile $TemplateParametersFile ` - @OptionalParameters ` - -Force -Verbose \ No newline at end of file