Bicep: Deploy Virtual Machine Scale Set and put it behind ILB (Internal Load Balancer) as backend pool
@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)
param vmssName string
@description('Size of VMs in the VM Scale Set.')
param vmSku string = 'Standard_B2ms'
@description('The Windows version for the VM. This will pick a fully patched image of this given Windows version. Allowed values: 2008-R2-SP1, 2012-Datacenter, 2012-R2-Datacenter & 2016-Datacenter, 2019-Datacenter.')
@allowed([
'2008-R2-SP1'
'2012-Datacenter'
'2012-R2-Datacenter'
'2016-Datacenter'
'2019-Datacenter'
])
param windowsOSVersion string = '2019-Datacenter'
@description('Number of VM instances (100 or less).')
@minValue(1)
@maxValue(100)
param instanceCount int = 3
@description('When true this limits the scale set to a single placement group, of max size 100 virtual machines. NOTE: If singlePlacementGroup is true, it may be modified to false. However, if singlePlacementGroup is false, it may not be modified to true.')
param singlePlacementGroup bool = true
@description('Admin username on all VMs.')
param adminUsername string = 'azureuser'
@description('Admin password on all VMs.')
@minLength(12)
param adminPassword string
@description('Location for all resources.')
param location string = resourceGroup().location
@description('Fault Domain count for each placement group.')
param platformFaultDomainCount int = 1
param randomId string = substring(newGuid(), 0, 8)
var vmScaleSetName = toLower(vmssName)
var longvmScaleSet = '${toLower(vmssName)}${randomId}'
//var longvmScaleSet = toLower(vmssName)
var publicIPAddressName = '${vmScaleSetName}pip'
var loadBalancerName = '${vmScaleSetName}lb'
//var publicIPAddressID = publicIPAddress.id
var lbProbeID = resourceId('Microsoft.Network/loadBalancers/probes', loadBalancerName, 'tcpProbe')
var bePoolName = '${vmScaleSetName}bepool'
var lbPoolID = resourceId('Microsoft.Network/loadBalancers/backendAddressPools', loadBalancerName, bePoolName)
var nicName = '${vmScaleSetName}nic'
var ipConfigName = '${vmScaleSetName}ipconfig'
var frontEndIPConfigID = resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', loadBalancerName, 'loadBalancerFrontEnd')
var osType = {
publisher: 'MicrosoftWindowsServer'
offer: 'WindowsServer'
sku: windowsOSVersion
version: 'latest'
}
var imageReference = osType
@description('Your VNET name')
param vnetname string = 'EUN-Virtual-Network'
@description('Your Subnet name')
param subnetname string = 'SD-WAN'
@description('Your VNET RG name')
param vnetrg string = 'SD-WAN'
@description('DNS Server 1')
param DNS1 string = '192.168.1.210'
resource loadBalancer 'Microsoft.Network/loadBalancers@2021-05-01' = {
name: loadBalancerName
location: location
properties: {
frontendIPConfigurations: [
//Public IP
/* {
name: 'LoadBalancerFrontEnd'
properties: {
publicIPAddress: {
id: publicIPAddressID
}
}
}
*/
// Private IP
{
name: 'loadBalancerFrontEnd'
properties: {
privateIPAllocationMethod: 'Dynamic'
subnet: {
id: subnet.id
}
}
}
]
backendAddressPools: [
{
name: bePoolName
}
]
loadBalancingRules: [
{
name: 'LBRule'
properties: {
frontendIPConfiguration: {
id: frontEndIPConfigID
}
backendAddressPool: {
id: lbPoolID
}
protocol: 'Tcp'
frontendPort: 80
backendPort: 80
enableFloatingIP: false
idleTimeoutInMinutes: 5
probe: {
id: lbProbeID
}
}
}
]
probes: [
{
name: 'tcpProbe'
properties: {
protocol: 'Tcp'
port: 80
intervalInSeconds: 5
numberOfProbes: 2
}
}
]
}
}
resource vmScaleSet 'Microsoft.Compute/virtualMachineScaleSets@2021-11-01' = {
name: vmScaleSetName
location: location
dependsOn: [
loadBalancer
]
sku: {
name: vmSku
tier: 'Standard'
capacity: instanceCount
}
properties: {
overprovision: true
upgradePolicy: {
automaticOSUpgradePolicy: {
enableAutomaticOSUpgrade: true
}
mode: 'Automatic'
}
singlePlacementGroup: singlePlacementGroup
platformFaultDomainCount: platformFaultDomainCount
virtualMachineProfile: {
storageProfile: {
osDisk: {
caching: 'ReadWrite'
createOption: 'FromImage'
}
imageReference: imageReference
}
osProfile: {
computerNamePrefix: vmScaleSetName
adminUsername: adminUsername
adminPassword: adminPassword
windowsConfiguration: {
enableAutomaticUpdates: false
}
}
networkProfile: {
networkInterfaceConfigurations: [
{
name: nicName
properties: {
dnsSettings: {
dnsServers: [
DNS1
]
}
primary: true
ipConfigurations: [
{
name: ipConfigName
properties: {
subnet: {
id: ngfwvnet.properties.subnets[1].id
}
loadBalancerBackendAddressPools: [
{
id: lbPoolID
}
]
}
}
]
}
}
]
}
extensionProfile: {
extensions: [
{
name: 'confscaleset'
properties: {
publisher: 'Microsoft.Compute'
type: 'CustomScriptExtension'
typeHandlerVersion: '1.10'
autoUpgradeMinorVersion: true
settings: {}
protectedSettings: {
commandToExecute: 'powershell -ExecutionPolicy Unrestricted -File EnableAnsibleWinRM.ps1'
fileUris: [
'https://test.test.local/yoursript.ps1'
]
}
}
}
{
name: 'HealthExtension'
properties:{
publisher: 'Microsoft.ManagedServices'
type: 'ApplicationHealthWindows'
typeHandlerVersion: '1.0'
autoUpgradeMinorVersion: true
settings: {
protocol: 'http'
port: 80
requestPath: '/'
intervalInSeconds: 10
numberOfProbes: 2
}
}
}
]
}
}
}
}
/* Creation of Public IP
resource publicIPAddress 'Microsoft.Network/publicIPAddresses@2021-05-01' = {
name: publicIPAddressName
location: location
properties: {
publicIPAllocationMethod: 'Static'
dnsSettings: {
domainNameLabel: longvmScaleSet
}
}
}
*/
resource ngfwvnet 'Microsoft.Network/virtualnetworks@2021-02-01' existing = {
name: vnetname
scope: resourceGroup(vnetrg)
}
resource subnet 'Microsoft.Network/virtualNetworks/subnets@2021-02-01' existing = {
parent: ngfwvnet
name: subnetname
}
resource autoscalehost 'Microsoft.Insights/autoscalesettings@2021-05-01-preview' = {
name: 'autoscalehost'
location: location
properties: {
name: 'autoscalehost'
targetResourceUri: vmScaleSet.id
enabled: true
profiles: [
{
name: 'Profile1'
capacity: {
minimum: '1'
maximum: '10'
default: '1'
}
rules: [
{
metricTrigger: {
metricName: 'Percentage CPU'
metricResourceUri: vmScaleSet.id
timeGrain: 'PT1M'
statistic: 'Average'
timeWindow: 'PT5M'
timeAggregation: 'Average'
operator: 'GreaterThan'
threshold: 50
}
scaleAction: {
direction: 'Increase'
type: 'ChangeCount'
value: '1'
cooldown: 'PT5M'
}
}
{
metricTrigger: {
metricName: 'Percentage CPU'
metricResourceUri: vmScaleSet.id
timeGrain: 'PT1M'
statistic: 'Average'
timeWindow: 'PT5M'
timeAggregation: 'Average'
operator: 'LessThan'
threshold: 30
}
scaleAction: {
direction: 'Decrease'
type: 'ChangeCount'
value: '1'
cooldown: 'PT5M'
}
}
]
}
]
}
}
//output applicationUrl string = uri('http://${publicIPAddress.properties.dnsSettings.fqdn}', '/MyApp')