Merge pull request #472 from rakku-ms/bicep
Bicep samples for Azure Stack supported ARM Templates
This commit is contained in:
Коммит
92fb60aee7
|
@ -0,0 +1,19 @@
|
|||
# Multiple VM Availability Set
|
||||
|
||||
Deploys a set of Linux VM´s (centos ) as part of the same availability set. This template template also deploys an availability set, a virtual Network (with DNS), a load balancer with a front end Public IP address, and a Network Security Group.
|
||||
VM´s require the following Deployed Centos or Ubuntu Image:
|
||||
*osImagePublisher: Centos, Canonical
|
||||
*osImageOffer: Centos-7, UbuntuServer
|
||||
*osImageSKU: Centos-7.4, 16.04-LTS
|
||||
|
||||
# Deploy using Az CLI
|
||||
```Powershell
|
||||
# update parameters values in azuredeploy.parametrs.json file and run below commands
|
||||
# create resource group if it doesn't exist
|
||||
az group create --name testrg --location "local"
|
||||
# ARM template deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.json --parameters .\azuredeploy.parameters.json
|
||||
# Bicep deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.bicep --parameters .\azuredeploy.parameters.json
|
||||
```
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
@description('The name of the Administrator of the new VMs')
|
||||
param adminUsername string = 'vmadmin'
|
||||
|
||||
@description('The password for the Administrator account of the new VMs. Default value is subscription id')
|
||||
@secure()
|
||||
param adminPassword string = 'Subscription#${substring(resourceGroup().id, 15, 36)}'
|
||||
|
||||
@description('Number of VMs to deploy, limit 5 since this sample is using a single storage account')
|
||||
@allowed([
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
])
|
||||
param numberOfInstances int = 3
|
||||
|
||||
@description('Size of the Data Disk')
|
||||
@allowed([
|
||||
100
|
||||
500
|
||||
750
|
||||
1000
|
||||
])
|
||||
param dataDiskSize int = 1000
|
||||
|
||||
@description('VM name prefix')
|
||||
param vmNamePrefix string = 'vmset-'
|
||||
|
||||
@description('This is the size of your VM')
|
||||
@allowed([
|
||||
'Standard_A1'
|
||||
'Standard_A2'
|
||||
'Standard_A3'
|
||||
'Standard_A4'
|
||||
'Standard_D1'
|
||||
'Standard_D2'
|
||||
'Standard_D3'
|
||||
'Standard_D4'
|
||||
])
|
||||
param vmSize string = 'Standard_A1'
|
||||
|
||||
@description('dns name prefix')
|
||||
param dnsPrefix string = 'vmdns'
|
||||
|
||||
@description('Maps to the publisher in the Azure Stack Platform Image Repository manifest file.')
|
||||
param osImagePublisher string = 'Canonical'
|
||||
|
||||
@description('Maps to the Offer in the Azure Stack Platform Image Repository manifest file.')
|
||||
param osImageOffer string = 'UbuntuServer'
|
||||
|
||||
@description('The Linux version for the VM. This will pick a fully patched image of this given Centos')
|
||||
@allowed([
|
||||
'Centos-7.4'
|
||||
'16.04-LTS'
|
||||
])
|
||||
param osImageSKU string = '16.04-LTS'
|
||||
|
||||
var availabilitySetName = toLower('aSet-${resourceGroup().name}')
|
||||
var storageAccountType = 'Standard_LRS'
|
||||
var osImageVersion = 'latest'
|
||||
var addressPrefix = '10.0.0.0/16'
|
||||
var virtualNetworkName = toLower('vNet-${resourceGroup().name}')
|
||||
var NICPrefix = 'vnic-'
|
||||
var subnetPrefix = '10.0.0.0/24'
|
||||
var subnetName = 'vmstaticsubnet'
|
||||
var storageName = 'sa${uniqueString(resourceGroup().id)}'
|
||||
var publicLBName = toLower('external-lb-${resourceGroup().name}')
|
||||
var lbFE = toLower('external-lb-fe-${resourceGroup().name}')
|
||||
var publicIPAddressName = toLower('public-ip${resourceGroup().name}')
|
||||
var nsgName = toLower('vmnsg${resourceGroup().name}')
|
||||
var vmContainerName = 'vhds'
|
||||
|
||||
resource storage 'Microsoft.Storage/storageAccounts@2019-06-01' = {
|
||||
name: storageName
|
||||
location: resourceGroup().location
|
||||
sku: {
|
||||
name: storageAccountType
|
||||
}
|
||||
kind: 'Storage'
|
||||
dependsOn: [
|
||||
publicLB
|
||||
]
|
||||
}
|
||||
|
||||
resource nsg 'Microsoft.Network/networkSecurityGroups@2018-11-01' = {
|
||||
name: nsgName
|
||||
location: resourceGroup().location
|
||||
properties: {
|
||||
securityRules: [
|
||||
{
|
||||
name: 'rule1'
|
||||
properties: {
|
||||
protocol: '*'
|
||||
sourcePortRange: '*'
|
||||
destinationPortRange: '*'
|
||||
sourceAddressPrefix: '*'
|
||||
destinationAddressPrefix: '*'
|
||||
access: 'Allow'
|
||||
priority: 101
|
||||
direction: 'Inbound'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource availabilitySet 'Microsoft.Compute/availabilitySets@2020-06-01' = {
|
||||
name: availabilitySetName
|
||||
location: resourceGroup().location
|
||||
properties: {
|
||||
platformFaultDomainCount: 1
|
||||
platformUpdateDomainCount: 1
|
||||
}
|
||||
}
|
||||
|
||||
resource publicIPAddress 'Microsoft.Network/publicIPAddresses@2018-11-01' = {
|
||||
name: publicIPAddressName
|
||||
location: resourceGroup().location
|
||||
properties: {
|
||||
publicIPAllocationMethod: 'Dynamic'
|
||||
dnsSettings: {
|
||||
domainNameLabel: dnsPrefix
|
||||
}
|
||||
}
|
||||
dependsOn: [
|
||||
virtualNetwork
|
||||
]
|
||||
}
|
||||
|
||||
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2018-11-01' = {
|
||||
name: virtualNetworkName
|
||||
location: resourceGroup().location
|
||||
properties: {
|
||||
addressSpace: {
|
||||
addressPrefixes: [
|
||||
addressPrefix
|
||||
]
|
||||
}
|
||||
subnets: [
|
||||
{
|
||||
name: subnetName
|
||||
properties: {
|
||||
addressPrefix: subnetPrefix
|
||||
networkSecurityGroup: {
|
||||
id: nsg.id
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource publicLB 'Microsoft.Network/loadBalancers@2018-11-01' = {
|
||||
name: publicLBName
|
||||
location: resourceGroup().location
|
||||
properties: {
|
||||
frontendIPConfigurations: [
|
||||
{
|
||||
name: lbFE
|
||||
properties: {
|
||||
publicIPAddress: {
|
||||
id: publicIPAddress.id
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
backendAddressPools: [
|
||||
{
|
||||
name: 'LoadBalancerBackend'
|
||||
}
|
||||
]
|
||||
}
|
||||
dependsOn: [
|
||||
virtualNetwork
|
||||
]
|
||||
}
|
||||
|
||||
resource inboundNatRule 'Microsoft.Network/loadBalancers/inboundNatRules@2018-11-01' = [for i in range(0, numberOfInstances): {
|
||||
name: '${publicLBName}/ssh-VM${i}'
|
||||
properties: {
|
||||
frontendIPConfiguration: {
|
||||
id: publicLB.properties.frontendIPConfigurations[0].id
|
||||
}
|
||||
protocol: 'Tcp'
|
||||
frontendPort: (i + 2200)
|
||||
backendPort: 22
|
||||
enableFloatingIP: false
|
||||
}
|
||||
}]
|
||||
|
||||
resource networkInterface 'Microsoft.Network/networkInterfaces@2018-11-01' = [for i in range(0, numberOfInstances): {
|
||||
name: '${NICPrefix}${vmNamePrefix}${i}'
|
||||
location: resourceGroup().location
|
||||
properties: {
|
||||
ipConfigurations: [
|
||||
{
|
||||
name: 'ipconfig1'
|
||||
properties: {
|
||||
privateIPAllocationMethod: 'Dynamic'
|
||||
subnet: {
|
||||
id: virtualNetwork.properties.subnets[0].id
|
||||
}
|
||||
loadBalancerBackendAddressPools: [
|
||||
{
|
||||
id: publicLB.properties.backendAddressPools[0].id
|
||||
}
|
||||
]
|
||||
loadBalancerInboundNatRules: [
|
||||
{
|
||||
id: inboundNatRule[i].id
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}]
|
||||
|
||||
resource virtualMachine 'Microsoft.Compute/virtualMachines@2020-06-01' = [for i in range(0, numberOfInstances): {
|
||||
name: '${vmNamePrefix}${i}'
|
||||
location: resourceGroup().location
|
||||
properties: {
|
||||
availabilitySet: {
|
||||
id: availabilitySet.id
|
||||
}
|
||||
hardwareProfile: {
|
||||
vmSize: vmSize
|
||||
}
|
||||
osProfile: {
|
||||
computerName: '${vmNamePrefix}${i}'
|
||||
adminUsername: adminUsername
|
||||
adminPassword: adminPassword
|
||||
}
|
||||
storageProfile: {
|
||||
imageReference: {
|
||||
publisher: osImagePublisher
|
||||
offer: osImageOffer
|
||||
sku: osImageSKU
|
||||
version: osImageVersion
|
||||
}
|
||||
osDisk: {
|
||||
name: 'osdisk'
|
||||
vhd: {
|
||||
uri: '${reference('Microsoft.Storage/storageAccounts/${storageName}', providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob}${vmContainerName}/${vmNamePrefix}${i}-osdisk.vhd'
|
||||
}
|
||||
caching: 'ReadWrite'
|
||||
createOption: 'FromImage'
|
||||
}
|
||||
dataDisks: [
|
||||
{
|
||||
vhd: {
|
||||
uri: '${reference('Microsoft.Storage/storageAccounts/${storageName}', providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob}${vmContainerName}/${vmNamePrefix}${i}-data-1.vhd'
|
||||
}
|
||||
name: '${vmNamePrefix}${i}-data-disk1'
|
||||
createOption: 'Empty'
|
||||
caching: 'None'
|
||||
diskSizeGB: dataDiskSize
|
||||
lun: 0
|
||||
}
|
||||
{
|
||||
vhd: {
|
||||
uri: '${reference('Microsoft.Storage/storageAccounts/${storageName}', providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob}${vmContainerName}/${vmNamePrefix}${i}-data-2.vhd'
|
||||
}
|
||||
name: '${vmNamePrefix}${i}-data-disk2'
|
||||
createOption: 'Empty'
|
||||
caching: 'None'
|
||||
diskSizeGB: dataDiskSize
|
||||
lun: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
networkProfile: {
|
||||
networkInterfaces: [
|
||||
{
|
||||
id: networkInterface[i].id
|
||||
}
|
||||
]
|
||||
}
|
||||
diagnosticsProfile: {
|
||||
bootDiagnostics: {
|
||||
enabled: true
|
||||
storageUri: concat(reference('Microsoft.Storage/storageAccounts/${storageName}', providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob)
|
||||
}
|
||||
}
|
||||
}
|
||||
dependsOn: [
|
||||
storage
|
||||
]
|
||||
}]
|
|
@ -0,0 +1,387 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"apiProfile": "2020-09-01-hybrid",
|
||||
"parameters": {
|
||||
"adminUsername": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the Administrator of the new VMs"
|
||||
},
|
||||
"defaultValue": "vmadmin"
|
||||
},
|
||||
"adminPassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "The password for the Administrator account of the new VMs. Default value is subscription id"
|
||||
},
|
||||
"defaultValue": "[concat('Subscription#',substring(resourcegroup().id,15,36))]"
|
||||
},
|
||||
"numberOfInstances": {
|
||||
"type": "int",
|
||||
"defaultValue": 3,
|
||||
"allowedValues": [
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Number of VMs to deploy, limit 5 since this sample is using a single storage account"
|
||||
}
|
||||
},
|
||||
"dataDiskSize": {
|
||||
"type": "int",
|
||||
"defaultValue": 1000,
|
||||
"allowedValues": [
|
||||
100,
|
||||
500,
|
||||
750,
|
||||
1000
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Size of the Data Disk"
|
||||
}
|
||||
},
|
||||
"vmNamePrefix": {
|
||||
"type": "string",
|
||||
"defaultValue": "vmset-",
|
||||
"metadata": {
|
||||
"description": "VM name prefix"
|
||||
}
|
||||
},
|
||||
"vmSize": {
|
||||
"allowedValues": [
|
||||
"Standard_A1",
|
||||
"Standard_A2",
|
||||
"Standard_A3",
|
||||
"Standard_A4",
|
||||
"Standard_D1",
|
||||
"Standard_D2",
|
||||
"Standard_D3",
|
||||
"Standard_D4"
|
||||
],
|
||||
"defaultValue": "Standard_A1",
|
||||
"metadata": {
|
||||
"description": "This is the size of your VM"
|
||||
},
|
||||
"type": "string"
|
||||
},
|
||||
"dnsPrefix": {
|
||||
"type": "string",
|
||||
"defaultValue": "vmdns",
|
||||
"metadata": {
|
||||
"description": "dns name prefix"
|
||||
}
|
||||
},
|
||||
"osImagePublisher": {
|
||||
"type": "string",
|
||||
"defaultValue": "Canonical",
|
||||
"metadata": {
|
||||
"description": "Maps to the publisher in the Azure Stack Platform Image Repository manifest file."
|
||||
}
|
||||
},
|
||||
"osImageOffer": {
|
||||
"type": "string",
|
||||
"defaultValue": "UbuntuServer",
|
||||
"metadata": {
|
||||
"description": "Maps to the Offer in the Azure Stack Platform Image Repository manifest file."
|
||||
}
|
||||
},
|
||||
"osImageSKU": {
|
||||
"type": "string",
|
||||
"defaultValue": "16.04-LTS",
|
||||
"allowedValues": [
|
||||
"Centos-7.4",
|
||||
"16.04-LTS"
|
||||
],
|
||||
"metadata": {
|
||||
"description": "The Linux version for the VM. This will pick a fully patched image of this given Centos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"availabilitySetName": "[toLower(concat('aSet-', resourceGroup().name))]",
|
||||
"storageAccountType": "Standard_LRS",
|
||||
"vmSize": "[parameters('vmSize')]",
|
||||
"dnsPrefix": "[parameters('dnsPrefix')]",
|
||||
"osImageVersion": "latest",
|
||||
"dataDiskSize": "[parameters('dataDiskSize')]",
|
||||
"addressPrefix": "10.0.0.0/16",
|
||||
"virtualNetworkName": "[tolower(concat('vNet-',resourceGroup().name))]",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
|
||||
|
||||
"NICPrefix": "vnic-",
|
||||
"subnetPrefix": "10.0.0.0/24",
|
||||
"subnetName": "vmstaticsubnet",
|
||||
"subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets/', variables('virtualNetworkName'), variables('subnetName'))]",
|
||||
|
||||
"storageName": "[concat('sa', uniquestring(resourceGroup().id))]",
|
||||
|
||||
"publicLBName": "[tolower(concat('external-lb-', resourceGroup().name))]",
|
||||
"publicLBID": "[resourceId('Microsoft.Network/loadBalancers', variables('publicLBName'))]",
|
||||
"lbFE": "[tolower(concat('external-lb-fe-',resourceGroup().name))]",
|
||||
"publicLBFEConfigID": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('publicLBName'), variables('lbFE'))]",
|
||||
|
||||
"publicIPAddressName": "[tolower(concat('public-ip',resourceGroup().name))]",
|
||||
"nsgName": "[tolower(concat('vmnsg',resourceGroup().name))]",
|
||||
"nsgID": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]",
|
||||
"vmContainerName": "vhds"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[variables('storageName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"sku": {
|
||||
"name": "[variables('storageAccountType')]"
|
||||
},
|
||||
"kind": "Storage",
|
||||
"dependsOn": [
|
||||
"[variables('publicLBName')]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('nsgName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "rule1",
|
||||
"properties": {
|
||||
"protocol": "*",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "*",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 101,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/availabilitySets",
|
||||
"apiVersion": "2020-06-01",
|
||||
"name": "[variables('availabilitySetName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"platformFaultDomainCount": 1,
|
||||
"platformUpdateDomainCount": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('publicIPAddressName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('dnsPrefix')]"
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"[variables('vnetID')]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('virtualNetworkName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]",
|
||||
"networkSecurityGroup": {
|
||||
"id": "[variables('nsgID')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependsOn": [
|
||||
"[variables('nsgID')]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "[variables('publicLBName')]",
|
||||
"type": "Microsoft.Network/loadBalancers",
|
||||
"apiVersion": "2018-11-01",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[variables('vnetID')]",
|
||||
"[variables('publicIPAddressName')]"
|
||||
],
|
||||
"properties": {
|
||||
"frontendIPConfigurations": [
|
||||
{
|
||||
"name": "[variables('lbFE')]",
|
||||
"properties": {
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"backendAddressPools": [
|
||||
{
|
||||
"name": "LoadBalancerBackend"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/loadBalancers/inboundNatRules",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[concat(variables('publicLBName'), '/ssh-VM', copyIndex())]",
|
||||
"copy": {
|
||||
"name": "lbNatLoop",
|
||||
"count": "[parameters('numberOfInstances')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Network/loadBalancers', variables('publicLBName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[variables('publicLBFEConfigID')]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": "[copyIndex(2200)]",
|
||||
"backendPort": 22,
|
||||
"enableFloatingIP": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[concat(variables('NICPrefix'), parameters('vmNamePrefix'), copyIndex())]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "nicLoop",
|
||||
"count": "[parameters('numberOfInstances')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
|
||||
"[resourceId('Microsoft.Network/loadBalancers', variables('publicLBName'))]",
|
||||
"[concat('Microsoft.Network/loadBalancers/', variables('publicLBName'), '/inboundNatRules/', 'ssh-VM', copyIndex())]"
|
||||
],
|
||||
"properties": {
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
},
|
||||
"loadBalancerBackendAddressPools": [
|
||||
{
|
||||
"id": "[concat(variables('publicLBID'), '/backendAddressPools/LoadBalancerBackend')]"
|
||||
}
|
||||
],
|
||||
"loadBalancerInboundNatRules": [
|
||||
{
|
||||
"id": "[concat(variables('publicLBID'), '/inboundNatRules/ssh-VM', copyIndex())]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"apiVersion": "2020-06-01",
|
||||
"name": "[concat(parameters('vmNamePrefix'), copyIndex())]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"copy": {
|
||||
"name": "virtualMachineLoop",
|
||||
"count": "[parameters('numberOfInstances')]"
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts',variables('storageName'))]",
|
||||
"[resourceId('Microsoft.Network/networkInterfaces', concat(variables('NICPrefix'), parameters('vmNamePrefix'), copyIndex()))]",
|
||||
"[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"availabilitySet": {
|
||||
"id": "[resourceId('Microsoft.Compute/availabilitySets',variables('availabilitySetName'))]"
|
||||
},
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('vmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[concat(parameters('vmNamePrefix'), copyIndex())]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"adminPassword": "[parameters('adminPassword')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[parameters('osImagePublisher')]",
|
||||
"offer": "[parameters('osImageOffer')]",
|
||||
"sku": "[parameters('osImageSKU')]",
|
||||
"version": "[variables('osImageVersion')]"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "osdisk",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('vmContainerName'),'/', parameters('vmNamePrefix'), copyIndex(),'-osdisk.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
},
|
||||
"dataDisks": [
|
||||
{
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('vmContainerName'),'/', parameters('vmNamePrefix'), copyIndex(),'-data-1.vhd')]"
|
||||
},
|
||||
"name": "[concat(parameters('vmNamePrefix'), copyIndex(),'-data-disk1')]",
|
||||
"createOption": "Empty",
|
||||
"caching": "None",
|
||||
"diskSizeGB": "[variables('dataDiskSize')]",
|
||||
"lun": 0
|
||||
},
|
||||
{
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('vmContainerName'),'/', parameters('vmNamePrefix'), copyIndex(),'-data-2.vhd')]"
|
||||
},
|
||||
"name": "[concat(parameters('vmNamePrefix'), copyIndex(),'-data-disk2')]",
|
||||
"createOption": "Empty",
|
||||
"caching": "None",
|
||||
"diskSizeGB": "[variables('dataDiskSize')]",
|
||||
"lun": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('NICPrefix'), parameters('vmNamePrefix'), copyIndex()))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": true,
|
||||
"storageUri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageName')),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob)]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"adminUsername": {
|
||||
"value": "ecsadmin"
|
||||
},
|
||||
"adminPassword": {
|
||||
"value": "GEN-PASSWORD"
|
||||
},
|
||||
"vmNamePrefix": {
|
||||
"value": "ECS"
|
||||
},
|
||||
"osImagePublisher": {
|
||||
"value": "Centos"
|
||||
},
|
||||
"vmSize": {
|
||||
"value": "Standard_D3"
|
||||
},
|
||||
"dataDiskSIze": {
|
||||
"value": 500
|
||||
},
|
||||
"numberOfInstances": {
|
||||
"value": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"itemDisplayName": "Deploy a set of VMs in the same availability set",
|
||||
"description": "This template deploys a set of VMs (defaut 3) as part of the same availability group. This template template also deploys an availability group, a virtual Network (with DNS), a load balancer with a front end Public IP address, and a Network Security Group.",
|
||||
"summary": "This template takes a minimum amount of parameters and deploys 3 Linux VMs, with the appropriate DNS setting for the Azure Stack POC environment.",
|
||||
"githubUsername": "bottkars",
|
||||
"dateUpdated": "2018-11-06"
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
# IaaS Linux VM using managed disk from custom image
|
||||
|
||||
This template deploys a Linux VM from a Custom Image using Managed Disk
|
||||
|
||||
# Prerequisites
|
||||
Prepare or Download a Customized Linux Image Template
|
||||
|
||||
# Deploy using Az CLI
|
||||
```Powershell
|
||||
# update parameters values in azuredeploy.parametrs.json file and run below commands
|
||||
# create resource group if it doesn't exist
|
||||
az group create --name testrg --location "local"
|
||||
# ARM template deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.json --parameters .\azuredeploy.parameters.json
|
||||
# Bicep deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.bicep --parameters .\azuredeploy.parameters.json
|
||||
```
|
|
@ -0,0 +1,182 @@
|
|||
@description('Name of the VM')
|
||||
param vmName string
|
||||
|
||||
@description('Username for the Virtual Machine. Default value is localadmin')
|
||||
param adminUsername string = 'ubuntu'
|
||||
|
||||
@description('ssh key for vm')
|
||||
@secure()
|
||||
param sshkeyData string
|
||||
|
||||
@description('Maps to the Image Name')
|
||||
param imageName string = 'myimage'
|
||||
|
||||
@description('uri of the Image ')
|
||||
param imageUri string = ''
|
||||
|
||||
@description('The size of the Virtual Machine.')
|
||||
param vmSize string = 'Standard_A1'
|
||||
|
||||
var publicIPName = 'PublicIP_${vmName}'
|
||||
var location = resourceGroup().location
|
||||
var nicName = toLower('nic${uniqueString(resourceGroup().id)}')
|
||||
var addressPrefix = '10.0.0.0/24'
|
||||
var subnetName = toLower('subnet${uniqueString(resourceGroup().id)}')
|
||||
var subnetPrefix = '10.0.0.0/24'
|
||||
var diagnosticsStorageAccountName = toLower('diag${uniqueString(resourceGroup().id)}')
|
||||
var virtualNetworkName = toLower('vnet${uniqueString(resourceGroup().id)}')
|
||||
var vnetID = virtualNetwork.id
|
||||
var subnetRef = '${vnetID}/subnets/${subnetName}'
|
||||
var networkSecurityGroupName = toLower('nsg${uniqueString(resourceGroup().id)}')
|
||||
var sshKeyPath = '/home/${adminUsername}/.ssh/authorized_keys'
|
||||
|
||||
resource image 'Microsoft.Compute/images@2017-03-30' = {
|
||||
name: imageName
|
||||
location: location
|
||||
tags: {
|
||||
provisioner: 'Image_Deploy'
|
||||
}
|
||||
properties: {
|
||||
storageProfile: {
|
||||
osDisk: {
|
||||
osType: 'Linux'
|
||||
osState: 'Generalized'
|
||||
blobUri: imageUri
|
||||
storageAccountType: 'Standard_LRS'
|
||||
caching: 'ReadWrite'
|
||||
diskSizeGB: 127
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource diagnosticsStorageAccount 'Microsoft.Storage/storageAccounts@2017-10-01' = {
|
||||
name: diagnosticsStorageAccountName
|
||||
location: location
|
||||
properties: {}
|
||||
sku: {
|
||||
name: 'Standard_LRS'
|
||||
}
|
||||
kind: 'Storage'
|
||||
}
|
||||
|
||||
resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2017-10-01' = {
|
||||
name: networkSecurityGroupName
|
||||
location: resourceGroup().location
|
||||
properties: {
|
||||
securityRules: [
|
||||
{
|
||||
name: 'ssh'
|
||||
properties: {
|
||||
description: 'Allow ssh'
|
||||
protocol: 'Tcp'
|
||||
sourcePortRange: '*'
|
||||
destinationPortRange: '22'
|
||||
sourceAddressPrefix: '*'
|
||||
destinationAddressPrefix: '*'
|
||||
access: 'Allow'
|
||||
priority: 200
|
||||
direction: 'Inbound'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2017-10-01' = {
|
||||
name: virtualNetworkName
|
||||
location: location
|
||||
properties: {
|
||||
addressSpace: {
|
||||
addressPrefixes: [
|
||||
addressPrefix
|
||||
]
|
||||
}
|
||||
subnets: [
|
||||
{
|
||||
name: subnetName
|
||||
properties: {
|
||||
addressPrefix: subnetPrefix
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource publicIP 'Microsoft.Network/publicIPAddresses@2017-10-01' = {
|
||||
name: publicIPName
|
||||
location: location
|
||||
tags: {
|
||||
provisioner: 'image_deploy'
|
||||
}
|
||||
properties: {
|
||||
publicIPAllocationMethod: 'Static'
|
||||
}
|
||||
}
|
||||
|
||||
resource nic 'Microsoft.Network/networkInterfaces@2017-10-01' = {
|
||||
name: nicName
|
||||
location: location
|
||||
properties: {
|
||||
networkSecurityGroup: {
|
||||
id: networkSecurityGroup.id
|
||||
}
|
||||
ipConfigurations: [
|
||||
{
|
||||
name: 'ipconfig1'
|
||||
properties: {
|
||||
privateIPAllocationMethod: 'Dynamic'
|
||||
subnet: {
|
||||
id: subnetRef
|
||||
}
|
||||
publicIPAddress: {
|
||||
id: publicIP.id
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource vm 'Microsoft.Compute/virtualMachines@2017-03-30' = {
|
||||
name: vmName
|
||||
location: location
|
||||
properties: {
|
||||
hardwareProfile: {
|
||||
vmSize: vmSize
|
||||
}
|
||||
osProfile: {
|
||||
computerName: vmName
|
||||
adminUsername: adminUsername
|
||||
linuxConfiguration: {
|
||||
disablePasswordAuthentication: true
|
||||
ssh: {
|
||||
publicKeys: [
|
||||
{
|
||||
path: sshKeyPath
|
||||
keyData: sshkeyData
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
storageProfile: {
|
||||
imageReference: {
|
||||
id: image.id
|
||||
}
|
||||
}
|
||||
networkProfile: {
|
||||
networkInterfaces: [
|
||||
{
|
||||
id: nic.id
|
||||
}
|
||||
]
|
||||
}
|
||||
diagnosticsProfile: {
|
||||
bootDiagnostics: {
|
||||
enabled: true
|
||||
storageUri: reference(diagnosticsStorageAccount.id, providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"apiProfile": "2018-03-01-hybrid",
|
||||
"parameters": {
|
||||
"vmName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Name of the VM"
|
||||
}
|
||||
},
|
||||
"adminUsername": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Username for the Virtual Machine. Default value is localadmin"
|
||||
},
|
||||
"defaultValue": "ubuntu"
|
||||
},
|
||||
"sshkeyData": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "ssh key for vm"
|
||||
}
|
||||
},
|
||||
"imageName": {
|
||||
"type": "string",
|
||||
"defaultValue": "myimage",
|
||||
"metadata": {
|
||||
"description": "Maps to the Image Name"
|
||||
}
|
||||
},
|
||||
"imageUri": {
|
||||
"type": "string",
|
||||
"defaultValue": "",
|
||||
"metadata": {
|
||||
"description": "uri of the Image "
|
||||
}
|
||||
},
|
||||
"vmSize": {
|
||||
"type": "string",
|
||||
"defaultValue": "Standard_A1",
|
||||
"metadata": {
|
||||
"description": "The size of the Virtual Machine."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"PublicIPName": "[concat('PublicIP_', parameters('vmName'))]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"nicName": "[tolower(concat('nic',uniquestring(resourceGroup().id)))]",
|
||||
"addressPrefix": "10.0.0.0/24",
|
||||
"subnetName": "[tolower(concat('subnet',uniquestring(resourceGroup().id)))]",
|
||||
"subnetPrefix": "10.0.0.0/24",
|
||||
"diagnosticsStorageAccountName": "[toLower(concat('diag', uniquestring(resourceGroup().id)))]",
|
||||
"virtualNetworkName": "[tolower(concat('vnet',uniquestring(resourceGroup().id)))]",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
|
||||
"subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]",
|
||||
"networkSecurityGroupName": "[tolower(concat('nsg',uniquestring(resourceGroup().id)))]",
|
||||
"sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Compute/images",
|
||||
"apiVersion": "2017-03-30",
|
||||
"name": "[parameters('ImageName')]",
|
||||
"location": "[variables('location')]",
|
||||
"tags": {
|
||||
"provisioner": "Image_Deploy"
|
||||
},
|
||||
"properties": {
|
||||
"storageProfile": {
|
||||
"osDisk": {
|
||||
"osType": "Linux",
|
||||
"osState": "Generalized",
|
||||
"blobUri": "[parameters('ImageUri')]",
|
||||
"storageAccountType": "Standard_LRS",
|
||||
"caching": "ReadWrite",
|
||||
"diskSizeGB": 127
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-10-01",
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"name": "[variables('diagnosticsStorageAccountName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {},
|
||||
"sku": {
|
||||
"name": "Standard_LRS"
|
||||
},
|
||||
"kind": "Storage"
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-10-01",
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('networkSecurityGroupName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "ssh",
|
||||
"properties": {
|
||||
"description": "Allow ssh",
|
||||
"protocol": "Tcp",
|
||||
"sourcePortRange": "*",
|
||||
"destinationPortRange": "22",
|
||||
"sourceAddressPrefix": "*",
|
||||
"destinationAddressPrefix": "*",
|
||||
"access": "Allow",
|
||||
"priority": 200,
|
||||
"direction": "Inbound"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-10-01",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[variables('virtualNetworkName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[variables('addressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[variables('subnetPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-10-01",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('PublicIPName')]",
|
||||
"location": "[variables('location')]",
|
||||
"tags": {
|
||||
"provisioner": "image_deploy"
|
||||
},
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Static"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-10-01",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"name": "[variables('nicName')]",
|
||||
"location": "[variables('location')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
|
||||
"[variables('networkSecurityGroupName')]"
|
||||
],
|
||||
"properties": {
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
|
||||
},
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
},
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceID('Microsoft.Network/publicIPAddresses/',variables('PublicIPName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "2017-03-30",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"name": "[parameters('vmName')]",
|
||||
"location": "[variables('location')]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName'))]",
|
||||
"[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]",
|
||||
"[concat('Microsoft.Compute/images/', parameters('imageName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[parameters('vmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[parameters('vmName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"linuxConfiguration": {
|
||||
"disablePasswordAuthentication": true,
|
||||
"ssh": {
|
||||
"publicKeys": [
|
||||
{
|
||||
"path": "[variables('sshKeyPath')]",
|
||||
"keyData": "[parameters('sshKeyData')]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"id": "[resourceId('Microsoft.Compute/images', Parameters('imageName'))]"
|
||||
}
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": true,
|
||||
"storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('diagnosticsStorageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"vmName": {
|
||||
"value": "linuxvm"
|
||||
},
|
||||
"adminUsername": {
|
||||
"value": "ubuntu"
|
||||
},
|
||||
"sshkeyData": {
|
||||
"value": null
|
||||
},
|
||||
"imageName": {
|
||||
"value": null
|
||||
},
|
||||
"imageUri": {
|
||||
"value": null
|
||||
},
|
||||
"vmSize": {
|
||||
"value": "Standard_A1"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateScript({
|
||||
if(-Not ($_ | Test-Path) ){
|
||||
throw "File or folder does not exist"
|
||||
}
|
||||
if(-Not ($_ | Test-Path -PathType Leaf) ){
|
||||
throw "The Path argument must be a file. Folder paths are not allowed."
|
||||
}
|
||||
if($_ -notmatch "(\.vhd)"){
|
||||
throw "The file specified in the path argument must be of type 'vhd'"
|
||||
}
|
||||
return $true
|
||||
})]
|
||||
[System.IO.FileInfo]
|
||||
$Image,
|
||||
$resourceGroup = "image_test",
|
||||
$ImageName,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateScript({
|
||||
if(-Not ($_ | Test-Path) ){
|
||||
throw "File or folder does not exist"
|
||||
}
|
||||
if(-Not ($_ | Test-Path -PathType Leaf) ){
|
||||
throw "The Path argument must be a file. Folder paths are not allowed."
|
||||
}
|
||||
if($_ -notmatch "(\.pub)"){
|
||||
throw "The file specified in the path argument must be of type 'vhd'"
|
||||
}
|
||||
return $true
|
||||
})]
|
||||
[System.IO.FileInfo]
|
||||
$sshKeyFile,
|
||||
$blobbaseuri = "local.azurestack.external",
|
||||
$location = "local",
|
||||
$adminUsername = "ubuntu",
|
||||
$VMName = "linuxvm1",
|
||||
$ImageStorageAccount = "images",
|
||||
$ImageRG = "images",
|
||||
[switch]$testOnly
|
||||
|
||||
)
|
||||
|
||||
$ImageContainername = "vhds"
|
||||
$sshKey = Get-Content $sshKeyFile
|
||||
if (!$ImageName){
|
||||
$ImageName = (Split-Path -Leaf $Image) -replace ".vhd"
|
||||
}
|
||||
|
||||
$storageType = 'Standard_LRS'
|
||||
|
||||
Write-Host "==>Creating ResourceGroups $resourceGroup" -nonewline
|
||||
New-AzureRmResourceGroup -Name $resourceGroup -Location $location -Force -ErrorAction SilentlyContinue | out-null
|
||||
Write-Host -ForegroundColor green "[done]"
|
||||
$account_available = Get-AzureRmStorageAccountNameAvailability -Name $ImageStorageAccount -ErrorAction SilentlyContinue
|
||||
$account_free = $account_available.NameAvailable
|
||||
if ($account_free -eq $true) {
|
||||
try {
|
||||
Write-Host -ForegroundColor White -NoNewline "Checking for RG $ImageRG "
|
||||
$RG = Get-AzureRmResourceGroup -Name $ImageRG -Location local -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Host -ForegroundColor yellow [need to create]
|
||||
Write-Host -ForegroundColor White -NoNewline "Creating Image RG $ImageRG"
|
||||
$RG = New-AzureRmResourceGroup -Name $ImageRG -Location $location
|
||||
Write-Host -ForegroundColor Green [Done]
|
||||
}
|
||||
$newAcsaccount = New-AzureRmStorageAccount -ResourceGroupName $ImageRG `
|
||||
-Name $ImageStorageAccount -Location $location `
|
||||
-Type $storageType # -ErrorAction SilentlyContinue
|
||||
if (!$newAcsaccount) {
|
||||
$newAcsaccount = Get-AzureRmStorageAccount -ResourceGroupName $ImageRG | Where-Object StorageAccountName -match $ImageStorageAccount
|
||||
}
|
||||
$newAcsaccount | Set-AzureRmCurrentStorageAccount
|
||||
Write-Host "Creating Container `"$ImageContainername`" in $($newAcsaccount.StorageAccountName)"
|
||||
New-AzureStorageContainer -Name $ImageContainername -Permission blob | out-null
|
||||
}
|
||||
else {
|
||||
Write-Host "$ImageStorageAccount already exists, operations might fail if not owner in same location"
|
||||
}
|
||||
|
||||
$ImageVHD = Split-Path -Leaf $Image
|
||||
$urlOfUploadedImageVhd = ('https://' + $ImageStorageAccount + '.blob.' + $blobbaseuri + '/' + $ImageContainername + '/' + $ImageVHD)
|
||||
Write-Host "Starting upload Procedure for $ImageVHD into storageaccount $ImageStorageAccount, this may take a while"
|
||||
try {
|
||||
Add-AzureRmVhd -ResourceGroupName $ImageRG -Destination $urlOfUploadedImageVhd `
|
||||
-LocalFilePath $Image -OverWrite:$false -ErrorAction SilentlyContinue -NumberOfUploaderThreads 32
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Image already exists for $ImageVHD, not overwriting"
|
||||
}
|
||||
|
||||
|
||||
$parameters = @{}
|
||||
$parameters.Add("sshkeyData", $sshKey)
|
||||
$parameters.Add("adminUsername", $adminUsername)
|
||||
$parameters.Add("imageName", $ImageName)
|
||||
$parameters.Add("imageURI", $urlOfUploadedImageVhd)
|
||||
$parameters.Add("vmName", $VMName)
|
||||
|
||||
write-Host "Start deployment"
|
||||
|
||||
if ($TESTONLY.IsPresent) {
|
||||
Test-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroup -Mode Incremental -TemplateFile $PSScriptRoot/azuredeploy.json -TemplateParameterObject $parameters
|
||||
}
|
||||
else {
|
||||
New-AzureRmResourceGroupDeployment -Name $resourceGroup -ResourceGroupName $resourceGroup -Mode Incremental -TemplateFile $PSScriptRoot/azuredeploy.json -TemplateParameterObject $parameters
|
||||
}
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.9 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 116 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 89 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 91 KiB |
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"itemDisplayName": "101-simple-linux-vm-custom-managed-disk",
|
||||
"description": "create linux vm using managed disk ad custom image",
|
||||
"summary": "this example creates a linux vm using custom image and managed disk",
|
||||
"githubUsername": "bottkars",
|
||||
"dateUpdated": "2019-02-18"
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
# Deploy a VM Scale Set of Windows VMs
|
||||
|
||||
This template allows you to deploy a VM Scale Set of Windows VMs. It uses the latest patched version of several Windows versions. To connect from the load balancer to a VM in the scale set, you would go to the AzureStack Portal, find the load balancer of your scale set, examine the NAT rules, then connect using the NAT rule you want. For example, if there is a NAT rule on port 50000, you could RDP on port 50000 of the public IP to connect to that VM. Similarly if something is listening on port 80 we can connect to it using port 80.
|
||||
|
||||
# Parameter Restriction
|
||||
|
||||
vmssName must be 3-10 characters in length. It should also be globally unique across all of AzureStack. If it isn't globally unique, it is possible that this template will still deploy properly, but we don't recommend relying on this pseudo-probabilistic behavior.
|
||||
InstanceCount must be 20 or less. VM Scale Set supports upto 100 VMs and one should add more storage accounts to support this number.
|
||||
|
||||
# Deploy using Az CLI
|
||||
```Powershell
|
||||
# update parameters values in azuredeploy.parametrs.json file and run below commands
|
||||
# create resource group if it doesn't exist
|
||||
az group create --name testrg --location "local"
|
||||
# ARM template deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.json
|
||||
# Bicep deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.bicep
|
||||
```
|
|
@ -0,0 +1,206 @@
|
|||
@description('Size of VMs in the VM Scale Set.')
|
||||
param vmSku string = 'Standard_A1'
|
||||
|
||||
@description('String used as a base for naming resources. Must be 3-10 characters in length and globally unique across Azure Stack. A hash is prepended to this string for some resources, and resource-specific information is appended.')
|
||||
param vmssName string = substring('vmss${uniqueString(replace(resourceGroup().id, '-', ''))}', 0, 8)
|
||||
|
||||
@description('Number of VM instances (20 or less).')
|
||||
@maxValue(20)
|
||||
param instanceCount int = 2
|
||||
|
||||
@description('Admin username on all VMs.')
|
||||
param adminUsername string = 'azureuser'
|
||||
|
||||
@description('Admin password on all VMs.')
|
||||
@secure()
|
||||
param adminPassword string = 'Subscription#${subscription().subscriptionId}'
|
||||
|
||||
@description('Maps to the publisher in the Azure Stack Platform Image Repository manifest file.')
|
||||
param osImagePublisher string = 'MicrosoftWindowsServer'
|
||||
|
||||
@description('Maps to the Offer in the Azure Stack Platform Image Repository manifest file.')
|
||||
param osImageOffer string = 'WindowsServer'
|
||||
|
||||
@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.')
|
||||
@allowed([
|
||||
'2012-R2-Datacenter'
|
||||
'2016-Datacenter-Server-Core'
|
||||
'2016-Datacenter'
|
||||
])
|
||||
param osImageSku string = '2016-Datacenter'
|
||||
|
||||
var location = resourceGroup().location
|
||||
var vnetName = toLower('vnet${uniqueString(resourceGroup().id)}')
|
||||
var subnetName = toLower('subnet${uniqueString(resourceGroup().id)}')
|
||||
var vnetID = vnet.id
|
||||
var subnetRef = '${vnetID}/subnets/${subnetName}'
|
||||
var publicIPAddressName = toLower('pip${uniqueString(resourceGroup().id)}')
|
||||
var vmssDomainName = toLower('pubdns${uniqueString(resourceGroup().id)}')
|
||||
var loadBalancerName = 'LB${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerFrontEndName = 'LBFrontEnd${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerBackEndName = 'LBBackEnd${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerProbeName = 'LBHttpProbe${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerNatPoolName = 'LBNatPool${uniqueString(resourceGroup().id)}'
|
||||
|
||||
resource vnet 'Microsoft.Network/virtualNetworks@2018-11-01' = {
|
||||
name: vnetName
|
||||
location: location
|
||||
properties: {
|
||||
addressSpace: {
|
||||
addressPrefixes: [
|
||||
'10.0.0.0/16'
|
||||
]
|
||||
}
|
||||
subnets: [
|
||||
{
|
||||
name: subnetName
|
||||
properties: {
|
||||
addressPrefix: '10.0.0.0/24'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource publicIPAddress 'Microsoft.Network/publicIPAddresses@2018-11-01' = {
|
||||
name: publicIPAddressName
|
||||
location: location
|
||||
properties: {
|
||||
publicIPAllocationMethod: 'Dynamic'
|
||||
dnsSettings: {
|
||||
domainNameLabel: vmssDomainName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource loadBalancer 'Microsoft.Network/loadBalancers@2018-11-01' = {
|
||||
name: loadBalancerName
|
||||
location: location
|
||||
properties: {
|
||||
frontendIPConfigurations: [
|
||||
{
|
||||
name: loadBalancerFrontEndName
|
||||
properties: {
|
||||
publicIPAddress: {
|
||||
id: publicIPAddress.id
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
backendAddressPools: [
|
||||
{
|
||||
name: loadBalancerBackEndName
|
||||
}
|
||||
]
|
||||
loadBalancingRules: [
|
||||
{
|
||||
name: 'roundRobinLBRule'
|
||||
properties: {
|
||||
frontendIPConfiguration: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', loadBalancerName, loadBalancerFrontEndName)
|
||||
}
|
||||
backendAddressPool: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/backendAddressPools', loadBalancerName, loadBalancerBackEndName)
|
||||
}
|
||||
protocol: 'Tcp'
|
||||
frontendPort: 80
|
||||
backendPort: 80
|
||||
enableFloatingIP: false
|
||||
idleTimeoutInMinutes: 5
|
||||
probe: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/probes', loadBalancerName, loadBalancerProbeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
probes: [
|
||||
{
|
||||
name: loadBalancerProbeName
|
||||
properties: {
|
||||
protocol: 'Tcp'
|
||||
port: 80
|
||||
intervalInSeconds: 5
|
||||
numberOfProbes: 2
|
||||
}
|
||||
}
|
||||
]
|
||||
inboundNatPools: [
|
||||
{
|
||||
name: loadBalancerNatPoolName
|
||||
properties: {
|
||||
frontendIPConfiguration: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', loadBalancerName, loadBalancerFrontEndName)
|
||||
}
|
||||
protocol: 'Tcp'
|
||||
frontendPortRangeStart: 50000
|
||||
frontendPortRangeEnd: 50019
|
||||
backendPort: 3389
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2020-06-01' = {
|
||||
sku: {
|
||||
name: vmSku
|
||||
tier: 'Standard'
|
||||
capacity: instanceCount
|
||||
}
|
||||
name: vmssName
|
||||
location: location
|
||||
properties: {
|
||||
upgradePolicy: {
|
||||
mode: 'Manual'
|
||||
}
|
||||
virtualMachineProfile: {
|
||||
storageProfile: {
|
||||
osDisk: {
|
||||
caching: 'ReadOnly'
|
||||
createOption: 'FromImage'
|
||||
}
|
||||
imageReference: {
|
||||
publisher: osImagePublisher
|
||||
offer: osImageOffer
|
||||
sku: osImageSku
|
||||
version: 'latest'
|
||||
}
|
||||
}
|
||||
osProfile: {
|
||||
computerNamePrefix: vmssName
|
||||
adminUsername: adminUsername
|
||||
adminPassword: adminPassword
|
||||
}
|
||||
networkProfile: {
|
||||
networkInterfaceConfigurations: [
|
||||
{
|
||||
name: 'nic'
|
||||
properties: {
|
||||
primary: true
|
||||
ipConfigurations: [
|
||||
{
|
||||
name: 'ipconfig'
|
||||
properties: {
|
||||
subnet: {
|
||||
id: subnetRef
|
||||
}
|
||||
loadBalancerBackendAddressPools: [
|
||||
{
|
||||
id: loadBalancer.properties.backendAddressPools[0].id
|
||||
}
|
||||
]
|
||||
loadBalancerInboundNatPools: [
|
||||
{
|
||||
id: loadBalancer.properties.inboundNatPools[0].id
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,258 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"vmSku": {
|
||||
"defaultValue": "Standard_A1",
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "Size of VMs in the VM Scale Set."
|
||||
}
|
||||
},
|
||||
"vmssName": {
|
||||
"type": "String",
|
||||
"defaultValue": "[substring(concat('vmss', uniquestring(replace(resourceGroup().Id,'-',''))), 0, 8)]",
|
||||
"metadata": {
|
||||
"description": "String used as a base for naming resources. Must be 3-10 characters in length and globally unique across Azure Stack. A hash is prepended to this string for some resources, and resource-specific information is appended."
|
||||
}
|
||||
},
|
||||
"instanceCount": {
|
||||
"defaultValue": 2,
|
||||
"maxValue": 20,
|
||||
"type": "Int",
|
||||
"metadata": {
|
||||
"description": "Number of VM instances (20 or less)."
|
||||
}
|
||||
},
|
||||
"adminUsername": {
|
||||
"type": "String",
|
||||
"defaultValue": "azureuser",
|
||||
"metadata": {
|
||||
"description": "Admin username on all VMs."
|
||||
}
|
||||
},
|
||||
"adminPassword": {
|
||||
"type": "SecureString",
|
||||
"defaultValue": "[concat('Subscription#', subscription().subscriptionId)]",
|
||||
"metadata": {
|
||||
"description": "Admin password on all VMs."
|
||||
}
|
||||
},
|
||||
"osImagePublisher": {
|
||||
"type": "string",
|
||||
"defaultValue": "MicrosoftWindowsServer",
|
||||
"metadata": {
|
||||
"description": "Maps to the publisher in the Azure Stack Platform Image Repository manifest file."
|
||||
}
|
||||
},
|
||||
"osImageOffer": {
|
||||
"type": "string",
|
||||
"defaultValue": "WindowsServer",
|
||||
"metadata": {
|
||||
"description": "Maps to the Offer in the Azure Stack Platform Image Repository manifest file."
|
||||
}
|
||||
},
|
||||
"osImageSku": {
|
||||
"type": "string",
|
||||
"defaultValue": "2016-Datacenter",
|
||||
"allowedValues": [
|
||||
"2012-R2-Datacenter",
|
||||
"2016-Datacenter-Server-Core",
|
||||
"2016-Datacenter"
|
||||
],
|
||||
"metadata": {
|
||||
"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."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"location": "[resourceGroup().location]",
|
||||
"vnetName": "[toLower(concat('vnet', uniqueString(resourceGroup().id)))]",
|
||||
"subnetName": "[toLower(concat('subnet', uniqueString(resourceGroup().id)))]",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
|
||||
"subnetRef": "[concat(variables('vnetID'),'/subnets/', variables('subnetName'))]",
|
||||
"publicIPAddressName": "[toLower(concat('pip', uniqueString(resourceGroup().id)))]",
|
||||
"vmssDomainName": "[toLower(concat('pubdns', uniqueString(resourceGroup().id)))]",
|
||||
"loadBalancerName": "[concat('LB', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerFrontEndName": "[concat('LBFrontEnd', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerBackEndName": "[concat('LBBackEnd', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerProbeName": "[concat('LBHttpProbe', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerNatPoolName": "[concat('LBNatPool', uniqueString(resourceGroup().id))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('vnetName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"10.0.0.0/16"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "10.0.0.0/24"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('publicIPAddressName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('vmssDomainName')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/loadBalancers",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('loadBalancerName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"frontendIPConfigurations": [
|
||||
{
|
||||
"name": "[variables('loadBalancerFrontEndName')]",
|
||||
"properties": {
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"backendAddressPools": [
|
||||
{
|
||||
"name": "[variables('loadBalancerBackendName')]"
|
||||
}
|
||||
],
|
||||
"loadBalancingRules": [
|
||||
{
|
||||
"name": "roundRobinLBRule",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), variables('loadBalancerFrontEndName'))]"
|
||||
},
|
||||
"backendAddressPool": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('loadBalancerBackendName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": 80,
|
||||
"backendPort": 80,
|
||||
"enableFloatingIP": false,
|
||||
"idleTimeoutInMinutes": 5,
|
||||
"probe": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadBalancerName'), variables('loadBalancerProbeName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"name": "[variables('loadBalancerProbeName')]",
|
||||
"properties": {
|
||||
"protocol": "tcp",
|
||||
"port": 80,
|
||||
"intervalInSeconds": 5,
|
||||
"numberOfProbes": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
"inboundNatPools": [
|
||||
{
|
||||
"name": "[variables('loadBalancerNatPoolName')]",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), variables('loadBalancerFrontEndName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPortRangeStart": 50000,
|
||||
"frontendPortRangeEnd": 50019,
|
||||
"backendPort": 3389
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachineScaleSets",
|
||||
"apiVersion": "2020-06-01",
|
||||
"sku": {
|
||||
"name": "[parameters('vmSku')]",
|
||||
"tier": "Standard",
|
||||
"capacity": "[parameters('instanceCount')]"
|
||||
},
|
||||
"name": "[parameters('vmssName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"upgradePolicy": {
|
||||
"mode": "Manual"
|
||||
},
|
||||
"virtualMachineProfile": {
|
||||
"storageProfile": {
|
||||
"osDisk": {
|
||||
"caching": "ReadOnly",
|
||||
"createOption": "FromImage"
|
||||
},
|
||||
"imageReference": {
|
||||
"publisher": "[parameters('osImagePublisher')]",
|
||||
"offer": "[parameters('osImageOffer')]",
|
||||
"sku": "[parameters('osImageSku')]",
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
"osProfile": {
|
||||
"computerNamePrefix": "[parameters('vmssName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"adminPassword": "[parameters('adminPassword')]"
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaceConfigurations": [
|
||||
{
|
||||
"name": "nic",
|
||||
"properties": {
|
||||
"primary": true,
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig",
|
||||
"properties": {
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
},
|
||||
"loadBalancerBackendAddressPools": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('loadBalancerBackendName'))]"
|
||||
}
|
||||
],
|
||||
"loadBalancerInboundNatPools": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('loadBalancerName'), variables('loadBalancerNatPoolName'))]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
|
||||
"[resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName'))]"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"itemDisplayName": "Deploy a Windows VM Scale Set",
|
||||
"description": "This template allows you to deploy a VM Scale Set of Windows VMs using the lastest patched version of various Windows Versions. These VMs are behind a load balancer with NAT rules for rdp connections.",
|
||||
"summary": "This template deploys a Windows VM Scale Set with custom script extension behind a load balancer with NAT rules for rdp connections. This template was taken from Azure GitHub repo and modified for Azure Stack.",
|
||||
"githubUsername": "azurestack",
|
||||
"dateUpdated": "2018-11-06"
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
# Deploy a VM Scale Set of Linux VMs with a custom script extension
|
||||
|
||||
This template allows you to deploy a VM Scale Set of Linux VMs with a custom script run on each VM. To connect from the load balancer to a VM in the scale set, you would go to the AzureStack Portal, find the load balancer of your scale set, examine the NAT rules, then connect using the NAT rule you want. For example, if there is a NAT rule on port 50000, you could RDP on port 50000 of the public IP to connect to that VM. Similarly if something is listening on port 80 we can connect to it using port 80.
|
||||
|
||||
# Parameter Restriction
|
||||
|
||||
vmssName must be 3-10 characters in length. It should also be globally unique across all of AzureStack. If it isn't globally unique, it is possible that this template will still deploy properly, but we don't recommend relying on this pseudo-probabilistic behavior.
|
||||
instanceCount must be 20 or less. VM Scale Set supports upto 100 VMs and one should add more storage accounts to support this number.
|
||||
|
||||
# Deploy using Az CLI
|
||||
```Powershell
|
||||
# update parameters values in azuredeploy.parametrs.json file and run below commands
|
||||
# create resource group if it doesn't exist
|
||||
az group create --name testrg --location "local"
|
||||
# ARM template deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.json
|
||||
# Bicep deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.bicep
|
||||
```
|
|
@ -0,0 +1,236 @@
|
|||
@description('Size of VMs in the VM Scale Set.')
|
||||
param vmSku string = 'Standard_D1'
|
||||
|
||||
@description('String used as a base for naming resources. Must be 3-10 characters in length and globally unique across Azure Stack. A hash is prepended to this string for some resources, and resource-specific information is appended.')
|
||||
param vmssName string = substring('vmss${uniqueString(replace(resourceGroup().id, '-', ''))}', 0, 8)
|
||||
|
||||
@description('Number of VM instances (20 or less).')
|
||||
@maxValue(20)
|
||||
param instanceCount int = 2
|
||||
|
||||
@description('Admin username on all VMs.')
|
||||
param adminUsername string = 'azureuser'
|
||||
|
||||
@description('Admin password on all VMs.')
|
||||
@secure()
|
||||
param adminPassword string = 'Subscription#${subscription().subscriptionId}'
|
||||
|
||||
@description('Maps to the publisher in the Azure Stack Platform Image Repository manifest file.')
|
||||
param osImagePublisher string = 'Canonical'
|
||||
|
||||
@description('Maps to the Offer in the Azure Stack Platform Image Repository manifest file.')
|
||||
param osImageOffer string = 'UbuntuServer'
|
||||
|
||||
@description('The Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version. Default value: 14.04.3-LTS')
|
||||
param osImageSku string = '16.04-LTS'
|
||||
|
||||
var location = resourceGroup().location
|
||||
var vnetName = toLower('vnet${uniqueString(resourceGroup().id)}')
|
||||
var subnetName = toLower('subnet${uniqueString(resourceGroup().id)}')
|
||||
var storageAccountName = toLower('SA${uniqueString(resourceGroup().id)}')
|
||||
var storageAccountContainerName = toLower('SC${uniqueString(resourceGroup().id)}')
|
||||
var storageAccountType = 'Standard_LRS'
|
||||
var OSDiskName = 'osdisk'
|
||||
var vnetID = vnet.id
|
||||
var subnetRef = '${vnetID}/subnets/${subnetName}'
|
||||
var publicIPAddressName = toLower('pip${uniqueString(resourceGroup().id)}')
|
||||
var vmssDomainName = toLower('pubdns${uniqueString(resourceGroup().id)}')
|
||||
var loadBalancerName = 'LB${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerFrontEndName = 'LBFrontEnd${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerBackEndName = 'LBBackEnd${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerProbeName = 'LBHttpProbe${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerNatPoolName = 'LBNatPool${uniqueString(resourceGroup().id)}'
|
||||
|
||||
resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
|
||||
name: storageAccountName
|
||||
location: location
|
||||
sku: {
|
||||
name: storageAccountType
|
||||
}
|
||||
kind: 'Storage'
|
||||
}
|
||||
|
||||
resource vnet 'Microsoft.Network/virtualNetworks@2018-11-01' = {
|
||||
name: vnetName
|
||||
location: location
|
||||
properties: {
|
||||
addressSpace: {
|
||||
addressPrefixes: [
|
||||
'10.0.0.0/16'
|
||||
]
|
||||
}
|
||||
subnets: [
|
||||
{
|
||||
name: subnetName
|
||||
properties: {
|
||||
addressPrefix: '10.0.0.0/24'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource publicIPAddress 'Microsoft.Network/publicIPAddresses@2018-11-01' = {
|
||||
name: publicIPAddressName
|
||||
location: location
|
||||
properties: {
|
||||
publicIPAllocationMethod: 'Dynamic'
|
||||
dnsSettings: {
|
||||
domainNameLabel: vmssDomainName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource loadBalancer 'Microsoft.Network/loadBalancers@2018-11-01' = {
|
||||
name: loadBalancerName
|
||||
location: location
|
||||
properties: {
|
||||
frontendIPConfigurations: [
|
||||
{
|
||||
name: loadBalancerFrontEndName
|
||||
properties: {
|
||||
publicIPAddress: {
|
||||
id: publicIPAddress.id
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
backendAddressPools: [
|
||||
{
|
||||
name: loadBalancerBackEndName
|
||||
}
|
||||
]
|
||||
loadBalancingRules: [
|
||||
{
|
||||
name: 'roundRobinLBRule'
|
||||
properties: {
|
||||
frontendIPConfiguration: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', loadBalancerName, loadBalancerFrontEndName)
|
||||
}
|
||||
backendAddressPool: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/backendAddressPools', loadBalancerName, loadBalancerBackEndName)
|
||||
}
|
||||
protocol: 'Tcp'
|
||||
frontendPort: 80
|
||||
backendPort: 80
|
||||
enableFloatingIP: false
|
||||
idleTimeoutInMinutes: 5
|
||||
probe: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/probes', loadBalancerName, loadBalancerProbeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
probes: [
|
||||
{
|
||||
name: loadBalancerProbeName
|
||||
properties: {
|
||||
protocol: 'Tcp'
|
||||
port: 80
|
||||
intervalInSeconds: 5
|
||||
numberOfProbes: 2
|
||||
}
|
||||
}
|
||||
]
|
||||
inboundNatPools: [
|
||||
{
|
||||
name: loadBalancerNatPoolName
|
||||
properties: {
|
||||
frontendIPConfiguration: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', loadBalancerName, loadBalancerFrontEndName)
|
||||
}
|
||||
protocol: 'Tcp'
|
||||
frontendPortRangeStart: 50000
|
||||
frontendPortRangeEnd: 50019
|
||||
backendPort: 3389
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2020-06-01' = {
|
||||
sku: {
|
||||
name: vmSku
|
||||
tier: 'Standard'
|
||||
capacity: instanceCount
|
||||
}
|
||||
name: vmssName
|
||||
location: location
|
||||
properties: {
|
||||
upgradePolicy: {
|
||||
mode: 'Manual'
|
||||
}
|
||||
virtualMachineProfile: {
|
||||
storageProfile: {
|
||||
osDisk: {
|
||||
vhdContainers: [
|
||||
concat(reference(storageAccount.id, providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, storageAccountContainerName)
|
||||
]
|
||||
name: OSDiskName
|
||||
caching: 'ReadOnly'
|
||||
createOption: 'FromImage'
|
||||
}
|
||||
imageReference: {
|
||||
publisher: osImagePublisher
|
||||
offer: osImageOffer
|
||||
sku: osImageSku
|
||||
version: 'latest'
|
||||
}
|
||||
}
|
||||
osProfile: {
|
||||
computerNamePrefix: vmssName
|
||||
adminUsername: adminUsername
|
||||
adminPassword: adminPassword
|
||||
}
|
||||
networkProfile: {
|
||||
networkInterfaceConfigurations: [
|
||||
{
|
||||
name: 'nic'
|
||||
properties: {
|
||||
primary: true
|
||||
ipConfigurations: [
|
||||
{
|
||||
name: 'ipconfig'
|
||||
properties: {
|
||||
subnet: {
|
||||
id: subnetRef
|
||||
}
|
||||
loadBalancerBackendAddressPools: [
|
||||
{
|
||||
id: loadBalancer.properties.backendAddressPools[0].id
|
||||
}
|
||||
]
|
||||
loadBalancerInboundNatPools: [
|
||||
{
|
||||
id: loadBalancer.properties.inboundNatPools[0].id
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
extensionProfile: {
|
||||
extensions: [
|
||||
{
|
||||
type: 'Microsoft.Compute/virtualMachines/extensions'
|
||||
name: '${vmssName}-LinuxCustomScriptExtension'
|
||||
properties: {
|
||||
publisher: 'Microsoft.OSTCExtensions'
|
||||
type: 'CustomScriptForLinux'
|
||||
typeHandlerVersion: '1.3'
|
||||
autoUpgradeMinorVersion: true
|
||||
settings: {
|
||||
commandToExecute: 'touch /test.txt'
|
||||
enableInternalDNSCheck: 'false'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,291 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"apiProfile": "2020-09-01-hybrid",
|
||||
"parameters": {
|
||||
"vmSku": {
|
||||
"defaultValue": "Standard_D1",
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "Size of VMs in the VM Scale Set."
|
||||
}
|
||||
},
|
||||
"vmssName": {
|
||||
"type": "String",
|
||||
"defaultValue": "[substring(concat('vmss', uniquestring(replace(resourceGroup().Id,'-',''))), 0, 8)]",
|
||||
"metadata": {
|
||||
"description": "String used as a base for naming resources. Must be 3-10 characters in length and globally unique across Azure Stack. A hash is prepended to this string for some resources, and resource-specific information is appended."
|
||||
}
|
||||
},
|
||||
"instanceCount": {
|
||||
"defaultValue": 2,
|
||||
"maxValue": 20,
|
||||
"type": "Int",
|
||||
"metadata": {
|
||||
"description": "Number of VM instances (20 or less)."
|
||||
}
|
||||
},
|
||||
"adminUsername": {
|
||||
"type": "String",
|
||||
"defaultValue": "azureuser",
|
||||
"metadata": {
|
||||
"description": "Admin username on all VMs."
|
||||
}
|
||||
},
|
||||
"adminPassword": {
|
||||
"type": "SecureString",
|
||||
"defaultValue": "[concat('Subscription#', subscription().subscriptionId)]",
|
||||
"metadata": {
|
||||
"description": "Admin password on all VMs."
|
||||
}
|
||||
},
|
||||
"osImagePublisher": {
|
||||
"type": "string",
|
||||
"defaultValue": "Canonical",
|
||||
"metadata": {
|
||||
"description": "Maps to the publisher in the Azure Stack Platform Image Repository manifest file."
|
||||
}
|
||||
},
|
||||
"osImageOffer": {
|
||||
"type": "string",
|
||||
"defaultValue": "UbuntuServer",
|
||||
"metadata": {
|
||||
"description": "Maps to the Offer in the Azure Stack Platform Image Repository manifest file."
|
||||
}
|
||||
},
|
||||
"osImageSku": {
|
||||
"type": "string",
|
||||
"defaultValue": "16.04-LTS",
|
||||
"metadata": {
|
||||
"description": "The Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version. Default value: 14.04.3-LTS"
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"location": "[resourceGroup().location]",
|
||||
"vnetName": "[toLower(concat('vnet', uniqueString(resourceGroup().id)))]",
|
||||
"subnetName": "[toLower(concat('subnet', uniqueString(resourceGroup().id)))]",
|
||||
"storageAccountName": "[toLower(concat('SA', uniqueString(resourceGroup().id)))]",
|
||||
"storageAccountContainerName": "[toLower(concat('SC', uniqueString(resourceGroup().id)))]",
|
||||
"storageAccountType": "Standard_LRS",
|
||||
"OSDiskName": "osdisk",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
|
||||
"subnetRef": "[concat(variables('vnetID'),'/subnets/', variables('subnetName'))]",
|
||||
"publicIPAddressName": "[toLower(concat('pip', uniqueString(resourceGroup().id)))]",
|
||||
"vmssDomainName": "[toLower(concat('pubdns', uniqueString(resourceGroup().id)))]",
|
||||
"loadBalancerName": "[concat('LB', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerFrontEndName": "[concat('LBFrontEnd', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerBackEndName": "[concat('LBBackEnd', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerProbeName": "[concat('LBHttpProbe', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerNatPoolName": "[concat('LBNatPool', uniqueString(resourceGroup().id))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[variables('storageAccountName')]",
|
||||
"location": "[variables('location')]",
|
||||
"sku": {
|
||||
"name": "[variables('storageAccountType')]"
|
||||
},
|
||||
"kind": "Storage"
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('vnetName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"10.0.0.0/16"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "10.0.0.0/24"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('publicIPAddressName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('vmssDomainName')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/loadBalancers",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('loadBalancerName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"frontendIPConfigurations": [
|
||||
{
|
||||
"name": "[variables('loadBalancerFrontEndName')]",
|
||||
"properties": {
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"backendAddressPools": [
|
||||
{
|
||||
"name": "[variables('loadBalancerBackendName')]"
|
||||
}
|
||||
],
|
||||
"loadBalancingRules": [
|
||||
{
|
||||
"name": "roundRobinLBRule",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), variables('loadBalancerFrontEndName'))]"
|
||||
},
|
||||
"backendAddressPool": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('loadBalancerBackendName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": 80,
|
||||
"backendPort": 80,
|
||||
"enableFloatingIP": false,
|
||||
"idleTimeoutInMinutes": 5,
|
||||
"probe": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadBalancerName'), variables('loadBalancerProbeName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"name": "[variables('loadBalancerProbeName')]",
|
||||
"properties": {
|
||||
"protocol": "tcp",
|
||||
"port": 80,
|
||||
"intervalInSeconds": 5,
|
||||
"numberOfProbes": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
"inboundNatPools": [
|
||||
{
|
||||
"name": "[variables('loadBalancerNatPoolName')]",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), variables('loadBalancerFrontEndName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPortRangeStart": 50000,
|
||||
"frontendPortRangeEnd": 50019,
|
||||
"backendPort": 3389
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachineScaleSets",
|
||||
"apiVersion": "2020-06-01",
|
||||
"sku": {
|
||||
"name": "[parameters('vmSku')]",
|
||||
"tier": "Standard",
|
||||
"capacity": "[parameters('instanceCount')]"
|
||||
},
|
||||
"name": "[parameters('vmssName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"upgradePolicy": {
|
||||
"mode": "Manual"
|
||||
},
|
||||
"virtualMachineProfile": {
|
||||
"storageProfile": {
|
||||
"osDisk": {
|
||||
"vhdContainers": [
|
||||
"[concat(reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('storageAccountContainerName'))]"
|
||||
],
|
||||
"name": "[variables('OSDiskName')]",
|
||||
"caching": "ReadOnly",
|
||||
"createOption": "FromImage"
|
||||
},
|
||||
"imageReference": {
|
||||
"publisher": "[parameters('osImagePublisher')]",
|
||||
"offer": "[parameters('osImageOffer')]",
|
||||
"sku": "[parameters('osImageSku')]",
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
"osProfile": {
|
||||
"computerNamePrefix": "[parameters('vmssName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"adminPassword": "[parameters('adminPassword')]"
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaceConfigurations": [
|
||||
{
|
||||
"name": "nic",
|
||||
"properties": {
|
||||
"primary": true,
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig",
|
||||
"properties": {
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
},
|
||||
"loadBalancerBackendAddressPools": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('loadBalancerBackendName'))]"
|
||||
}
|
||||
],
|
||||
"loadBalancerInboundNatPools": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('loadBalancerName'), variables('loadBalancerNatPoolName'))]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"extensionProfile": {
|
||||
"extensions": [
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines/extensions",
|
||||
"name": "[concat(parameters('vmssName'),'-LinuxCustomScriptExtension')]",
|
||||
"properties": {
|
||||
"publisher": "Microsoft.OSTCExtensions",
|
||||
"type": "CustomScriptForLinux",
|
||||
"typeHandlerVersion": "1.3",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"commandToExecute": "touch /test.txt",
|
||||
"enableInternalDNSCheck": "false"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
|
||||
"[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
|
||||
"[resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName'))]"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"vmSku": {
|
||||
"value": "Standard_D1"
|
||||
},
|
||||
"vmssName": {
|
||||
"value": "GEN-UNIQUE-vmssname"
|
||||
},
|
||||
"instanceCount": {
|
||||
"value": 2
|
||||
},
|
||||
"adminUsername": {
|
||||
"value": "GEN-UNIQUE-admin"
|
||||
},
|
||||
"adminPassword": {
|
||||
"value": "GEN-PASSWORD"
|
||||
},
|
||||
"osImagePublisher": {
|
||||
"value": "Canonical"
|
||||
},
|
||||
"osImageOffer": {
|
||||
"value": "UbuntuServer"
|
||||
},
|
||||
"osImageSku": {
|
||||
"value": "16.04-LTS"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"itemDisplayName": "Deploy a Linux VM Scale Set with a Custom Script Extension",
|
||||
"description": "This template allows you to deploy a VM Scale Set of Linux VMs. These VMs have a custom script extension for customization and are behind a load balancer with NAT rules for rdp connections. Please note that extention sequencing (one extension depending upon another) is not yet supported with VM Scale Sets.",
|
||||
"summary": "This template deploys a Linux VM Scale Set with custom script extension behind a load balancer with NAT rules for rdp connections. This template was taken from Azure GitHub repo and modified for Azure Stack.",
|
||||
"githubUsername": "azurestack",
|
||||
"dateUpdated": "2018-11-06"
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
# Deploy a VM Scale Set of Windows VMs with a custom script extension
|
||||
|
||||
This template allows you to deploy a VM Scale Set of Windows VMs with a custom script run on each VM. It uses the latest patched version of several Windows versions. To connect from the load balancer to a VM in the scale set, you would go to the AzureStack Portal, find the load balancer of your scale set, examine the NAT rules, then connect using the NAT rule you want. For example, if there is a NAT rule on port 50000, you could RDP on port 50000 of the public IP to connect to that VM. Similarly if something is listening on port 80 we can connect to it using port 80:
|
||||
|
||||
# Parameter Restriction
|
||||
|
||||
vmssName must be 3-10 characters in length. It should also be globally unique across all of AzureStack. If it isn't globally unique, it is possible that this template will still deploy properly, but we don't recommend relying on this pseudo-probabilistic behavior.
|
||||
instanceCount must be 20 or less. VM Scale Set supports upto 100 VMs and one should add more storage accounts to support this number.
|
||||
|
||||
# Deploy using Az CLI
|
||||
```Powershell
|
||||
# update parameters values in azuredeploy.parametrs.json file and run below commands
|
||||
# create resource group if it doesn't exist
|
||||
az group create --name testrg --location "local"
|
||||
# ARM template deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.json
|
||||
# Bicep deployment
|
||||
az deployment group create --resource-group testrg --template-file .\azuredeploy.bicep
|
||||
```
|
|
@ -0,0 +1,249 @@
|
|||
@description('Size of VMs in the VM Scale Set.')
|
||||
param vmSku string = 'Standard_D1'
|
||||
|
||||
@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.')
|
||||
@allowed([
|
||||
'2012-R2-Datacenter'
|
||||
'2016-Datacenter-Server-Core'
|
||||
'2016-Datacenter'
|
||||
])
|
||||
param osImageSku string = '2016-Datacenter'
|
||||
|
||||
@description('Maps to the publisher in the Azure Stack Platform Image Repository manifest file.')
|
||||
param osImagePublisher string = 'MicrosoftWindowsServer'
|
||||
|
||||
@description('Maps to the Offer in the Azure Stack Platform Image Repository manifest file.')
|
||||
param osImageOffer string = 'WindowsServer'
|
||||
|
||||
@description('String used as a base for naming resources. Must be 3-10 characters in length and globally unique across Azure Stack. A hash is prepended to this string for some resources, and resource-specific information is appended.')
|
||||
@minLength(3)
|
||||
@maxLength(10)
|
||||
param vmssName string = substring('vmss${uniqueString(replace(resourceGroup().id, '-', ''))}', 0, 8)
|
||||
|
||||
@description('Number of VM instances (20 or less).')
|
||||
@maxValue(20)
|
||||
param instanceCount int = 2
|
||||
|
||||
@description('Admin username on all VMs.')
|
||||
param adminUsername string = 'azureuser'
|
||||
|
||||
@description('Admin password on all VMs.')
|
||||
@secure()
|
||||
param adminPassword string = 'Subscription#${subscription().subscriptionId}'
|
||||
|
||||
@description('The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated.')
|
||||
param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/azurestack-quickstart-templates/master/201-vmss-windows-extension'
|
||||
|
||||
var location = resourceGroup().location
|
||||
var vnetName = toLower('vnet${uniqueString(resourceGroup().id)}')
|
||||
var subnetName = toLower('subnet${uniqueString(resourceGroup().id)}')
|
||||
var storageAccountName = toLower('SA${uniqueString(resourceGroup().id)}')
|
||||
var storageAccountContainerName = toLower('SC${uniqueString(resourceGroup().id)}')
|
||||
var storageAccountType = 'Standard_LRS'
|
||||
var OSDiskName = 'osdisk'
|
||||
var vnetID = vnet.id
|
||||
var subnetRef = '${vnetID}/subnets/${subnetName}'
|
||||
var publicIPAddressName = toLower('pip${uniqueString(resourceGroup().id)}')
|
||||
var vmssDomainName = toLower('pubdns${uniqueString(resourceGroup().id)}')
|
||||
var loadBalancerName = 'LB${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerFrontEndName = 'LBFrontEnd${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerBackEndName = 'LBBackEnd${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerProbeName = 'LBHttpProbe${uniqueString(resourceGroup().id)}'
|
||||
var loadBalancerNatPoolName = 'LBNatPool${uniqueString(resourceGroup().id)}'
|
||||
|
||||
resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
|
||||
name: storageAccountName
|
||||
location: location
|
||||
sku: {
|
||||
name: storageAccountType
|
||||
}
|
||||
kind: 'Storage'
|
||||
}
|
||||
|
||||
resource vnet 'Microsoft.Network/virtualNetworks@2018-11-01' = {
|
||||
name: vnetName
|
||||
location: location
|
||||
properties: {
|
||||
addressSpace: {
|
||||
addressPrefixes: [
|
||||
'10.0.0.0/16'
|
||||
]
|
||||
}
|
||||
subnets: [
|
||||
{
|
||||
name: subnetName
|
||||
properties: {
|
||||
addressPrefix: '10.0.0.0/24'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource publicIPAddress 'Microsoft.Network/publicIPAddresses@2018-11-01' = {
|
||||
name: publicIPAddressName
|
||||
location: location
|
||||
properties: {
|
||||
publicIPAllocationMethod: 'Dynamic'
|
||||
dnsSettings: {
|
||||
domainNameLabel: vmssDomainName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource loadBalancer 'Microsoft.Network/loadBalancers@2018-11-01' = {
|
||||
name: loadBalancerName
|
||||
location: location
|
||||
properties: {
|
||||
frontendIPConfigurations: [
|
||||
{
|
||||
name: loadBalancerFrontEndName
|
||||
properties: {
|
||||
publicIPAddress: {
|
||||
id: publicIPAddress.id
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
backendAddressPools: [
|
||||
{
|
||||
name: loadBalancerBackEndName
|
||||
}
|
||||
]
|
||||
loadBalancingRules: [
|
||||
{
|
||||
name: 'roundRobinLBRule'
|
||||
properties: {
|
||||
frontendIPConfiguration: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', loadBalancerName, loadBalancerFrontEndName)
|
||||
}
|
||||
backendAddressPool: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/backendAddressPools', loadBalancerName, loadBalancerBackEndName)
|
||||
}
|
||||
protocol: 'Tcp'
|
||||
frontendPort: 80
|
||||
backendPort: 80
|
||||
enableFloatingIP: false
|
||||
idleTimeoutInMinutes: 5
|
||||
probe: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/probes', loadBalancerName, loadBalancerProbeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
probes: [
|
||||
{
|
||||
name: loadBalancerProbeName
|
||||
properties: {
|
||||
protocol: 'Tcp'
|
||||
port: 80
|
||||
intervalInSeconds: 5
|
||||
numberOfProbes: 2
|
||||
}
|
||||
}
|
||||
]
|
||||
inboundNatPools: [
|
||||
{
|
||||
name: loadBalancerNatPoolName
|
||||
properties: {
|
||||
frontendIPConfiguration: {
|
||||
id: resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', loadBalancerName, loadBalancerFrontEndName)
|
||||
}
|
||||
protocol: 'Tcp'
|
||||
frontendPortRangeStart: 50000
|
||||
frontendPortRangeEnd: 50019
|
||||
backendPort: 3389
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2020-06-01' = {
|
||||
sku: {
|
||||
name: vmSku
|
||||
tier: 'Standard'
|
||||
capacity: instanceCount
|
||||
}
|
||||
name: vmssName
|
||||
location: location
|
||||
properties: {
|
||||
upgradePolicy: {
|
||||
mode: 'Manual'
|
||||
}
|
||||
virtualMachineProfile: {
|
||||
storageProfile: {
|
||||
osDisk: {
|
||||
vhdContainers: [
|
||||
'${reference(storageAccount.id, providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob}${storageAccountContainerName}'
|
||||
]
|
||||
name: OSDiskName
|
||||
caching: 'ReadOnly'
|
||||
createOption: 'FromImage'
|
||||
}
|
||||
imageReference: {
|
||||
publisher: osImagePublisher
|
||||
offer: osImageOffer
|
||||
sku: osImageSku
|
||||
version: 'latest'
|
||||
}
|
||||
}
|
||||
osProfile: {
|
||||
computerNamePrefix: vmssName
|
||||
adminUsername: adminUsername
|
||||
adminPassword: adminPassword
|
||||
}
|
||||
networkProfile: {
|
||||
networkInterfaceConfigurations: [
|
||||
{
|
||||
name: 'nic'
|
||||
properties: {
|
||||
primary: true
|
||||
ipConfigurations: [
|
||||
{
|
||||
name: 'ipconfig'
|
||||
properties: {
|
||||
subnet: {
|
||||
id: subnetRef
|
||||
}
|
||||
loadBalancerBackendAddressPools: [
|
||||
{
|
||||
id: loadBalancer.properties.backendAddressPools[0].id
|
||||
}
|
||||
]
|
||||
loadBalancerInboundNatPools: [
|
||||
{
|
||||
id: loadBalancer.properties.inboundNatPools[0].id
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
extensionProfile: {
|
||||
extensions: [
|
||||
{
|
||||
name: 'customScript'
|
||||
properties: {
|
||||
publisher: 'Microsoft.Compute'
|
||||
type: 'CustomScriptExtension'
|
||||
settings: {
|
||||
fileUris: [
|
||||
'${artifactsLocation}/scripts/helloWorld.ps1'
|
||||
]
|
||||
}
|
||||
typeHandlerVersion: '1.8'
|
||||
autoUpgradeMinorVersion: true
|
||||
protectedSettings: {
|
||||
commandToExecute: 'powershell -ExecutionPolicy Unrestricted -File helloWorld.ps1'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"apiProfile": "2020-09-01-hybrid",
|
||||
"parameters": {
|
||||
"vmSku": {
|
||||
"defaultValue": "Standard_D1",
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "Size of VMs in the VM Scale Set."
|
||||
}
|
||||
},
|
||||
"osImageSku": {
|
||||
"type": "string",
|
||||
"defaultValue": "2016-Datacenter",
|
||||
"allowedValues": [
|
||||
"2012-R2-Datacenter",
|
||||
"2016-Datacenter-Server-Core",
|
||||
"2016-Datacenter"
|
||||
],
|
||||
"metadata": {
|
||||
"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."
|
||||
}
|
||||
},
|
||||
"osImagePublisher": {
|
||||
"type": "string",
|
||||
"defaultValue": "MicrosoftWindowsServer",
|
||||
"metadata": {
|
||||
"description": "Maps to the publisher in the Azure Stack Platform Image Repository manifest file."
|
||||
}
|
||||
},
|
||||
"osImageOffer": {
|
||||
"type": "string",
|
||||
"defaultValue": "WindowsServer",
|
||||
"metadata": {
|
||||
"description": "Maps to the Offer in the Azure Stack Platform Image Repository manifest file."
|
||||
}
|
||||
},
|
||||
"vmssName": {
|
||||
"defaultValue": "[substring(concat('vmss', uniquestring(replace(resourceGroup().Id,'-',''))), 0, 8)]",
|
||||
"minLength": 3,
|
||||
"maxLength": 10,
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "String used as a base for naming resources. Must be 3-10 characters in length and globally unique across Azure Stack. A hash is prepended to this string for some resources, and resource-specific information is appended."
|
||||
}
|
||||
},
|
||||
"instanceCount": {
|
||||
"defaultValue": 2,
|
||||
"maxValue": 20,
|
||||
"type": "Int",
|
||||
"metadata": {
|
||||
"description": "Number of VM instances (20 or less)."
|
||||
}
|
||||
},
|
||||
"adminUsername": {
|
||||
"defaultValue": "azureuser",
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "Admin username on all VMs."
|
||||
}
|
||||
},
|
||||
"adminPassword": {
|
||||
"defaultValue": "[concat('Subscription#', subscription().subscriptionId)]",
|
||||
"type": "SecureString",
|
||||
"metadata": {
|
||||
"description": "Admin password on all VMs."
|
||||
}
|
||||
},
|
||||
"_artifactsLocation": {
|
||||
"defaultValue": "https://raw.githubusercontent.com/Azure/azurestack-quickstart-templates/master/201-vmss-windows-extension",
|
||||
"type": "String",
|
||||
"metadata": {
|
||||
"description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"location": "[resourceGroup().location]",
|
||||
"vnetName": "[toLower(concat('vnet', uniqueString(resourceGroup().id)))]",
|
||||
"subnetName": "[toLower(concat('subnet', uniqueString(resourceGroup().id)))]",
|
||||
"storageAccountName": "[toLower(concat('SA', uniqueString(resourceGroup().id)))]",
|
||||
"storageAccountContainerName": "[toLower(concat('SC', uniqueString(resourceGroup().id)))]",
|
||||
"storageAccountType": "Standard_LRS",
|
||||
"OSDiskName": "osdisk",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
|
||||
"subnetRef": "[concat(variables('vnetID'),'/subnets/', variables('subnetName'))]",
|
||||
"publicIPAddressName": "[toLower(concat('pip', uniqueString(resourceGroup().id)))]",
|
||||
"vmssDomainName": "[toLower(concat('pubdns', uniqueString(resourceGroup().id)))]",
|
||||
"loadBalancerName": "[concat('LB', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerFrontEndName": "[concat('LBFrontEnd', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerBackEndName": "[concat('LBBackEnd', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerProbeName": "[concat('LBHttpProbe', uniqueString(resourceGroup().id))]",
|
||||
"loadBalancerNatPoolName": "[concat('LBNatPool', uniqueString(resourceGroup().id))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"apiVersion": "2019-06-01",
|
||||
"name": "[variables('storageAccountName')]",
|
||||
"location": "[variables('location')]",
|
||||
"sku": {
|
||||
"name": "[variables('storageAccountType')]"
|
||||
},
|
||||
"kind": "Storage"
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('vnetName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"10.0.0.0/16"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "10.0.0.0/24"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('publicIPAddressName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[variables('vmssDomainName')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/loadBalancers",
|
||||
"apiVersion": "2018-11-01",
|
||||
"name": "[variables('loadBalancerName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"frontendIPConfigurations": [
|
||||
{
|
||||
"name": "[variables('loadBalancerFrontEndName')]",
|
||||
"properties": {
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"backendAddressPools": [
|
||||
{
|
||||
"name": "[variables('loadBalancerBackendName')]"
|
||||
}
|
||||
],
|
||||
"loadBalancingRules": [
|
||||
{
|
||||
"name": "roundRobinLBRule",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), variables('loadBalancerFrontEndName'))]"
|
||||
},
|
||||
"backendAddressPool": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('loadBalancerBackendName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPort": 80,
|
||||
"backendPort": 80,
|
||||
"enableFloatingIP": false,
|
||||
"idleTimeoutInMinutes": 5,
|
||||
"probe": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadBalancerName'), variables('loadBalancerProbeName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"name": "[variables('loadBalancerProbeName')]",
|
||||
"properties": {
|
||||
"protocol": "tcp",
|
||||
"port": 80,
|
||||
"intervalInSeconds": 5,
|
||||
"numberOfProbes": 2
|
||||
}
|
||||
}
|
||||
],
|
||||
"inboundNatPools": [
|
||||
{
|
||||
"name": "[variables('loadBalancerNatPoolName')]",
|
||||
"properties": {
|
||||
"frontendIPConfiguration": {
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), variables('loadBalancerFrontEndName'))]"
|
||||
},
|
||||
"protocol": "tcp",
|
||||
"frontendPortRangeStart": 50000,
|
||||
"frontendPortRangeEnd": 50019,
|
||||
"backendPort": 3389
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachineScaleSets",
|
||||
"apiVersion": "2020-06-01",
|
||||
"sku": {
|
||||
"name": "[parameters('vmSku')]",
|
||||
"tier": "Standard",
|
||||
"capacity": "[parameters('instanceCount')]"
|
||||
},
|
||||
"name": "[parameters('vmssName')]",
|
||||
"location": "[variables('location')]",
|
||||
"properties": {
|
||||
"upgradePolicy": {
|
||||
"mode": "Manual"
|
||||
},
|
||||
"virtualMachineProfile": {
|
||||
"storageProfile": {
|
||||
"osDisk": {
|
||||
"vhdContainers": [
|
||||
"[concat(reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).primaryEndpoints.blob, variables('storageAccountContainerName'))]"
|
||||
],
|
||||
"name": "[variables('OSDiskName')]",
|
||||
"caching": "ReadOnly",
|
||||
"createOption": "FromImage"
|
||||
},
|
||||
"imageReference": {
|
||||
"publisher": "[parameters('osImagePublisher')]",
|
||||
"offer": "[parameters('osImageOffer')]",
|
||||
"sku": "[parameters('osImageSku')]",
|
||||
"version": "latest"
|
||||
}
|
||||
},
|
||||
"osProfile": {
|
||||
"computerNamePrefix": "[parameters('vmssName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"adminPassword": "[parameters('adminPassword')]"
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaceConfigurations": [
|
||||
{
|
||||
"name": "nic",
|
||||
"properties": {
|
||||
"primary": true,
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig",
|
||||
"properties": {
|
||||
"subnet": {
|
||||
"id": "[variables('subnetRef')]"
|
||||
},
|
||||
"loadBalancerBackendAddressPools": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('loadBalancerBackendName'))]"
|
||||
}
|
||||
],
|
||||
"loadBalancerInboundNatPools": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('loadBalancerName'), variables('loadBalancerNatPoolName'))]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"extensionProfile": {
|
||||
"extensions": [
|
||||
{
|
||||
"name": "customScript",
|
||||
"properties": {
|
||||
"publisher": "Microsoft.Compute",
|
||||
"type": "CustomScriptExtension",
|
||||
"settings": {
|
||||
"fileUris": [
|
||||
"[concat(parameters('_artifactsLocation'), '/scripts/helloWorld.ps1')]"
|
||||
]
|
||||
},
|
||||
"typeHandlerVersion": "1.8",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"protectedSettings": {
|
||||
"commandToExecute": "powershell -ExecutionPolicy Unrestricted -File helloWorld.ps1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
|
||||
"[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]",
|
||||
"[resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName'))]"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"itemDisplayName": "Deploy a Windows VM Scale Set with a Custom Script Extension",
|
||||
"description": "This template allows you to deploy a VM Scale Set of Windows VMs using the lastest patched version of various Windows Versions. These VMs have a custom script extension for customization and are behind a load balancer with NAT rules for rdp connections.",
|
||||
"summary": "This template deploys a Windows VM Scale Set with custom script extension behind a load balancer with NAT rules for rdp connections. This template was taken from Azure GitHub repo and modified for Azure Stack.",
|
||||
"githubUsername": "gatneil",
|
||||
"dateUpdated": "2018-11-06"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Write-Host "Hello World!"
|
|
@ -0,0 +1,19 @@
|
|||
This directory contains Bicep samples for AzureStack
|
||||
|
||||
To convert any AzureStack ARM template to Bicep, add api version within each resource declaration. API profile is not yet supported in Bicep. Here is the [tracking feature request](https://github.com/Azure/bicep/issues/851).
|
||||
|
||||
Main categories of error during conversion:
|
||||
1. Error BCP079: This expression is referencing its own declaration, which is not allowed.
|
||||
* Workaround - [GitHub issue](https://github.com/Azure/bicep/issues/1860)
|
||||
2. Error BCP034: The enclosing array expected an item of type "module[] | (resource | module) | resource[]", but the provided item was of type "string".
|
||||
* This is when bicep decompile is not able to recognize the dependent resource and tries to convert the “dependsOn” defined in ARM template. The workaround is to modify the generated bicep template to either create implicit dependency or add the resource (not the resource id as used in ARM template) in dependsOn parameter. [Doc link](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/compare-template-syntax#resource-dependencies)
|
||||
|
||||
Az CLI Bicep commands
|
||||
```
|
||||
# Convert ARM template to Bicep template
|
||||
az bicep decompile --file .\azuredeploy.json
|
||||
# Generate ARM template from Bicep template
|
||||
az bicep build --file .\azuredeploy.bicep --outfile bicepgenerated.json
|
||||
# Deploy ARM/Bicep template
|
||||
az deployment group create --resource-group testrg --template-file <ARM/Bicep template> --parameters .\azuredeploy.parameters.json
|
||||
```
|
Загрузка…
Ссылка в новой задаче