Azure Instance Using Basic Authentication

  • Query id: 6797f581-0433-4768-ae3e-7ceb2f8b138e
  • Query name: Azure Instance Using Basic Authentication
  • Platform: AzureResourceManager
  • Severity: Medium
  • Category: Best Practices
  • CWE: 522
  • URL: Github

Description

Azure Instances should use SSH Key instead of basic authentication
Documentation

Code samples

Code samples with security vulnerabilities

Positive test num. 1 - bicep file
@description('Specifies a name for generating resource names.')
param projectName string

@description('Specifies the location for all resources.')
param location string = resourceGroup().location

@description('Specifies a username for the Virtual Machine.')
param adminUsername string

@description('description')
param vmSize string = 'Standard_D2s_v3'

var vmName = '${projectName}-vm'
var networkInterfaceName = '${projectName}-nic'

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      linuxConfiguration: {
        disablePasswordAuthentication: false
      }
    }
    storageProfile: {
      imageReference: {
        publisher: 'Canonical'
        offer: 'UbuntuServer'
        sku: '18.04-LTS'
        version: 'latest'
      }
      osDisk: {
        createOption: 'fromImage'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: resourceId(
            'Microsoft.Network/networkInterfaces',
            networkInterfaceName
          )
        }
      ]
    }
  }
  dependsOn: [
    resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
  ]
}
Positive test num. 2 - json file
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "projectName": {
      "type": "string",
      "metadata": {
        "description": "Specifies a name for generating resource names."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Specifies the location for all resources."
      }
    },
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Specifies a username for the Virtual Machine."
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_D2s_v3",
      "metadata": {
        "description": "description"
      }
    }
  },
  "variables": {
    "vmName": "[concat(parameters('projectName'), '-vm')]",
    "networkInterfaceName": "[concat(parameters('projectName'), '-nic')]"
  },
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2021-03-01",
      "name": "[variables('vmName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "osProfile": {
          "computerName": "[variables('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "linuxConfiguration": {
            "disablePasswordAuthentication": false
          }
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "Canonical",
            "offer": "UbuntuServer",
            "sku": "18.04-LTS",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "fromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
            }
          ]
        }
      }
    }
  ]
}
Positive test num. 3 - bicep file
@description('Specifies a name for generating resource names.')
param projectName string

@description('Specifies the location for all resources.')
param location string = resourceGroup().location

@description('Specifies a username for the Virtual Machine.')
param adminUsername string

@description('description')
param vmSize string = 'Standard_D2s_v3'

var vmName = '${projectName}-vm'
var networkInterfaceName = '${projectName}-nic'

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
    }
    storageProfile: {
      imageReference: {
        publisher: 'Canonical'
        offer: 'UbuntuServer'
        sku: '18.04-LTS'
        version: 'latest'
      }
      osDisk: {
        createOption: 'fromImage'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: resourceId(
            'Microsoft.Network/networkInterfaces',
            networkInterfaceName
          )
        }
      ]
    }
  }
  dependsOn: [
    resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
  ]
}

Positive test num. 4 - json file
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "projectName": {
      "type": "string",
      "metadata": {
        "description": "Specifies a name for generating resource names."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Specifies the location for all resources."
      }
    },
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Specifies a username for the Virtual Machine."
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_D2s_v3",
      "metadata": {
        "description": "description"
      }
    }
  },
  "variables": {
    "vmName": "[concat(parameters('projectName'), '-vm')]",
    "networkInterfaceName": "[concat(parameters('projectName'), '-nic')]"
  },
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2021-03-01",
      "name": "[variables('vmName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "osProfile": {
          "computerName": "[variables('vmName')]",
          "adminUsername": "[parameters('adminUsername')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "Canonical",
            "offer": "UbuntuServer",
            "sku": "18.04-LTS",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "fromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
            }
          ]
        }
      }
    }
  ]
}
Positive test num. 5 - bicep file
@description('Specifies a name for generating resource names.')
param projectName string

@description('Specifies the location for all resources.')
param location string = resourceGroup().location

@description('Specifies a username for the Virtual Machine.')
param adminUsername string

@description('description')
param vmSize string = 'Standard_D2s_v3'

var vmName = '${projectName}-vm'
var networkInterfaceName = '${projectName}-nic'

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      linuxConfiguration: {
        disablePasswordAuthentication: false
      }
    }
    storageProfile: {
      imageReference: {
        publisher: 'Canonical'
        offer: 'UbuntuServer'
        sku: '18.04-LTS'
        version: 'latest'
      }
      osDisk: {
        createOption: 'fromImage'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: resourceId(
            'Microsoft.Network/networkInterfaces',
            networkInterfaceName
          )
        }
      ]
    }
  }
  dependsOn: [
    resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
  ]
}
Positive test num. 6 - json file
{
  "properties": {
    "template": {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "projectName": {
          "type": "string",
          "metadata": {
            "description": "Specifies a name for generating resource names."
          }
        },
        "location": {
          "type": "string",
          "defaultValue": "[resourceGroup().location]",
          "metadata": {
            "description": "Specifies the location for all resources."
          }
        },
        "adminUsername": {
          "type": "string",
          "metadata": {
            "description": "Specifies a username for the Virtual Machine."
          }
        },
        "vmSize": {
          "type": "string",
          "defaultValue": "Standard_D2s_v3",
          "metadata": {
            "description": "description"
          }
        }
      },
      "variables": {
        "vmName": "[concat(parameters('projectName'), '-vm')]",
        "networkInterfaceName": "[concat(parameters('projectName'), '-nic')]"
      },
      "resources": [
        {
          "type": "Microsoft.Compute/virtualMachines",
          "apiVersion": "2021-03-01",
          "name": "[variables('vmName')]",
          "location": "[parameters('location')]",
          "dependsOn": [
            "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
          ],
          "properties": {
            "hardwareProfile": {
              "vmSize": "[parameters('vmSize')]"
            },
            "osProfile": {
              "computerName": "[variables('vmName')]",
              "adminUsername": "[parameters('adminUsername')]",
              "linuxConfiguration": {
                "disablePasswordAuthentication": false
              }
            },
            "storageProfile": {
              "imageReference": {
                "publisher": "Canonical",
                "offer": "UbuntuServer",
                "sku": "18.04-LTS",
                "version": "latest"
              },
              "osDisk": {
                "createOption": "fromImage"
              }
            },
            "networkProfile": {
              "networkInterfaces": [
                {
                  "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
                }
              ]
            }
          }
        }
      ],
      "outputs": {}
    },
    "parameters": {}
  },
  "kind": "template",
  "type": "Microsoft.Blueprint/blueprints/artifacts",
  "name": "myTemplate"
}
Positive test num. 7 - bicep file
@description('Specifies a name for generating resource names.')
param projectName string

@description('Specifies the location for all resources.')
param location string = resourceGroup().location

@description('Specifies a username for the Virtual Machine.')
param adminUsername string

@description('description')
param vmSize string = 'Standard_D2s_v3'

var vmName = '${projectName}-vm'
var networkInterfaceName = '${projectName}-nic'

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
    }
    storageProfile: {
      imageReference: {
        publisher: 'Canonical'
        offer: 'UbuntuServer'
        sku: '18.04-LTS'
        version: 'latest'
      }
      osDisk: {
        createOption: 'fromImage'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: resourceId(
            'Microsoft.Network/networkInterfaces',
            networkInterfaceName
          )
        }
      ]
    }
  }
  dependsOn: [
    resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
  ]
}
Positive test num. 8 - json file
{
  "properties": {
    "template": {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "projectName": {
          "type": "string",
          "metadata": {
            "description": "Specifies a name for generating resource names."
          }
        },
        "location": {
          "type": "string",
          "defaultValue": "[resourceGroup().location]",
          "metadata": {
            "description": "Specifies the location for all resources."
          }
        },
        "adminUsername": {
          "type": "string",
          "metadata": {
            "description": "Specifies a username for the Virtual Machine."
          }
        },
        "vmSize": {
          "type": "string",
          "defaultValue": "Standard_D2s_v3",
          "metadata": {
            "description": "description"
          }
        }
      },
      "variables": {
        "vmName": "[concat(parameters('projectName'), '-vm')]",
        "networkInterfaceName": "[concat(parameters('projectName'), '-nic')]"
      },
      "resources": [
        {
          "type": "Microsoft.Compute/virtualMachines",
          "apiVersion": "2021-03-01",
          "name": "[variables('vmName')]",
          "location": "[parameters('location')]",
          "dependsOn": [
            "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
          ],
          "properties": {
            "hardwareProfile": {
              "vmSize": "[parameters('vmSize')]"
            },
            "osProfile": {
              "computerName": "[variables('vmName')]",
              "adminUsername": "[parameters('adminUsername')]"
            },
            "storageProfile": {
              "imageReference": {
                "publisher": "Canonical",
                "offer": "UbuntuServer",
                "sku": "18.04-LTS",
                "version": "latest"
              },
              "osDisk": {
                "createOption": "fromImage"
              }
            },
            "networkProfile": {
              "networkInterfaces": [
                {
                  "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
                }
              ]
            }
          }
        }
      ],
      "outputs": {}
    },
    "parameters": {}
  },
  "kind": "template",
  "type": "Microsoft.Blueprint/blueprints/artifacts",
  "name": "myTemplate"
}

Code samples without security vulnerabilities

Negative test num. 1 - bicep file
@description('Specifies a name for generating resource names.')
param projectName string

@description('Specifies the location for all resources.')
param location string = resourceGroup().location

@description('Specifies a username for the Virtual Machine.')
param adminUsername string

@description(
  'Specifies the SSH rsa public key file as a string. Use "ssh-keygen -t rsa -b 2048" to generate your SSH key pairs.'
)
param adminPublicKey string

@description('description')
param vmSize string = 'Standard_D2s_v3'

var vmName = '${projectName}-vm'
var networkInterfaceName = '${projectName}-nic'

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      linuxConfiguration: {
        disablePasswordAuthentication: true
        ssh: {
          publicKeys: [
            {
              path: '/home/${adminUsername}/.ssh/authorized_keys'
              keyData: adminPublicKey
            }
          ]
        }
      }
    }
    storageProfile: {
      imageReference: {
        publisher: 'Canonical'
        offer: 'UbuntuServer'
        sku: '18.04-LTS'
        version: 'latest'
      }
      osDisk: {
        createOption: 'fromImage'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: resourceId(
            'Microsoft.Network/networkInterfaces',
            networkInterfaceName
          )
        }
      ]
    }
  }
  dependsOn: [
    resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
  ]
}
Negative test num. 2 - json file
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "projectName": {
      "type": "string",
      "metadata": {
        "description": "Specifies a name for generating resource names."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Specifies the location for all resources."
      }
    },
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Specifies a username for the Virtual Machine."
      }
    },
    "adminPublicKey": {
      "type": "string",
      "metadata": {
        "description": "Specifies the SSH rsa public key file as a string. Use \"ssh-keygen -t rsa -b 2048\" to generate your SSH key pairs."
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_D2s_v3",
      "metadata": {
        "description": "description"
      }
    }
  },
  "variables": {
    "vmName": "[concat(parameters('projectName'), '-vm')]",
    "networkInterfaceName": "[concat(parameters('projectName'), '-nic')]"
  },
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2021-03-01",
      "name": "[variables('vmName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "osProfile": {
          "computerName": "[variables('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "linuxConfiguration": {
            "disablePasswordAuthentication": true,
            "ssh": {
              "publicKeys": [
                {
                  "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]",
                  "keyData": "[parameters('adminPublicKey')]"
                }
              ]
            }
          }
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "Canonical",
            "offer": "UbuntuServer",
            "sku": "18.04-LTS",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "fromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
            }
          ]
        }
      }
    }
  ]
}
Negative test num. 3 - bicep file
@description('Username for the Virtual Machine.')
param adminUsername string

@description('Password for the Virtual Machine.')
@minLength(12)
@secure()
param adminPassword string

@description(
  'The Windows version for the VM. This will pick a fully patched image of this given Windows version.'
)
@allowed(
  [
    '2008-R2-SP1'
    '2012-Datacenter'
    '2012-R2-Datacenter'
    '2016-Nano-Server'
    '2016-Datacenter-with-Containers'
    '2016-Datacenter'
    '2019-Datacenter'
    '2019-Datacenter-Core'
    '2019-Datacenter-Core-smalldisk'
    '2019-Datacenter-Core-with-Containers'
    '2019-Datacenter-Core-with-Containers-smalldisk'
    '2019-Datacenter-smalldisk'
    '2019-Datacenter-with-Containers'
    '2019-Datacenter-with-Containers-smalldisk'
  ]
)
param OSVersion string = '2019-Datacenter'

@description('Size of the virtual machine.')
param vmSize string = 'Standard_D2_v3'

@description('Location for all resources.')
param location string = resourceGroup().location

@description('Name of the virtual machine.')
param vmName string = 'simple-vm'

var storageAccountName = 'bootdiags${uniqueString(resourceGroup().id)}'
var nicName = 'myVMNic'

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      adminPassword: adminPassword
    }
    storageProfile: {
      imageReference: {
        publisher: 'MicrosoftWindowsServer'
        offer: 'WindowsServer'
        sku: OSVersion
        version: 'latest'
      }
      osDisk: {
        createOption: 'FromImage'
        managedDisk: {
          storageAccountType: 'StandardSSD_LRS'
        }
      }
      dataDisks: [
        {
          diskSizeGB: 1023
          lun: 0
          createOption: 'Empty'
        }
      ]
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: resourceId('Microsoft.Network/networkInterfaces', nicName)
        }
      ]
    }
    diagnosticsProfile: {
      bootDiagnostics: {
        enabled: true
        storageUri: reference(
          resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
        ).primaryEndpoints.blob
      }
    }
  }
  dependsOn: [
    resourceId('Microsoft.Network/networkInterfaces', nicName)
    resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
  ]
}

Negative test num. 4 - json file
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.4.1.14562",
      "templateHash": "8381960602397537918"
    }
  },
  "parameters": {
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Username for the Virtual Machine."
      }
    },
    "adminPassword": {
      "type": "secureString",
      "minLength": 12,
      "metadata": {
        "description": "Password for the Virtual Machine."
      }
    },
    "OSVersion": {
      "type": "string",
      "defaultValue": "2019-Datacenter",
      "allowedValues": [
        "2008-R2-SP1",
        "2012-Datacenter",
        "2012-R2-Datacenter",
        "2016-Nano-Server",
        "2016-Datacenter-with-Containers",
        "2016-Datacenter",
        "2019-Datacenter",
        "2019-Datacenter-Core",
        "2019-Datacenter-Core-smalldisk",
        "2019-Datacenter-Core-with-Containers",
        "2019-Datacenter-Core-with-Containers-smalldisk",
        "2019-Datacenter-smalldisk",
        "2019-Datacenter-with-Containers",
        "2019-Datacenter-with-Containers-smalldisk"
      ],
      "metadata": {
        "description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version."
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_D2_v3",
      "metadata": {
        "description": "Size of the virtual machine."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for all resources."
      }
    },
    "vmName": {
      "type": "string",
      "defaultValue": "simple-vm",
      "metadata": {
        "description": "Name of the virtual machine."
      }
    }
  },
  "functions": [],
  "variables": {
    "storageAccountName": "[format('bootdiags{0}', uniqueString(resourceGroup().id))]",
    "nicName": "myVMNic"
  },
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2021-03-01",
      "name": "[parameters('vmName')]",
      "location": "[parameters('location')]",
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "osProfile": {
          "computerName": "[parameters('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "[parameters('OSVersion')]",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "FromImage",
            "managedDisk": {
              "storageAccountType": "StandardSSD_LRS"
            }
          },
          "dataDisks": [
            {
              "diskSizeGB": 1023,
              "lun": 0,
              "createOption": "Empty"
            }
          ]
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
            }
          ]
        },
        "diagnosticsProfile": {
          "bootDiagnostics": {
            "enabled": true,
            "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))).primaryEndpoints.blob]"
          }
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]",
        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
      ]
    }
  ]
}
Negative test num. 5 - bicep file
@description('Specifies a name for generating resource names.')
param projectName string

@description('Specifies the location for all resources.')
param location string = resourceGroup().location

@description('Specifies a username for the Virtual Machine.')
param adminUsername string

@description(
  'Specifies the SSH rsa public key file as a string. Use "ssh-keygen -t rsa -b 2048" to generate your SSH key pairs.'
)
param adminPublicKey string

@description('description')
param vmSize string = 'Standard_D2s_v3'

var vmName = '${projectName}-vm'
var networkInterfaceName = '${projectName}-nic'

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      linuxConfiguration: {
        disablePasswordAuthentication: true
        ssh: {
          publicKeys: [
            {
              path: '/home/${adminUsername}/.ssh/authorized_keys'
              keyData: adminPublicKey
            }
          ]
        }
      }
    }
    storageProfile: {
      imageReference: {
        publisher: 'Canonical'
        offer: 'UbuntuServer'
        sku: '18.04-LTS'
        version: 'latest'
      }
      osDisk: {
        createOption: 'fromImage'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: resourceId(
            'Microsoft.Network/networkInterfaces',
            networkInterfaceName
          )
        }
      ]
    }
  }
  dependsOn: [
    resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
  ]
}
Negative test num. 6 - json file
{
  "properties": {
    "template": {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "projectName": {
          "type": "string",
          "metadata": {
            "description": "Specifies a name for generating resource names."
          }
        },
        "location": {
          "type": "string",
          "defaultValue": "[resourceGroup().location]",
          "metadata": {
            "description": "Specifies the location for all resources."
          }
        },
        "adminUsername": {
          "type": "string",
          "metadata": {
            "description": "Specifies a username for the Virtual Machine."
          }
        },
        "adminPublicKey": {
          "type": "string",
          "metadata": {
            "description": "Specifies the SSH rsa public key file as a string. Use \"ssh-keygen -t rsa -b 2048\" to generate your SSH key pairs."
          }
        },
        "vmSize": {
          "type": "string",
          "defaultValue": "Standard_D2s_v3",
          "metadata": {
            "description": "description"
          }
        }
      },
      "variables": {
        "vmName": "[concat(parameters('projectName'), '-vm')]",
        "networkInterfaceName": "[concat(parameters('projectName'), '-nic')]"
      },
      "resources": [
        {
          "type": "Microsoft.Compute/virtualMachines",
          "apiVersion": "2021-03-01",
          "name": "[variables('vmName')]",
          "location": "[parameters('location')]",
          "dependsOn": [
            "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
          ],
          "properties": {
            "hardwareProfile": {
              "vmSize": "[parameters('vmSize')]"
            },
            "osProfile": {
              "computerName": "[variables('vmName')]",
              "adminUsername": "[parameters('adminUsername')]",
              "linuxConfiguration": {
                "disablePasswordAuthentication": true,
                "ssh": {
                  "publicKeys": [
                    {
                      "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]",
                      "keyData": "[parameters('adminPublicKey')]"
                    }
                  ]
                }
              }
            },
            "storageProfile": {
              "imageReference": {
                "publisher": "Canonical",
                "offer": "UbuntuServer",
                "sku": "18.04-LTS",
                "version": "latest"
              },
              "osDisk": {
                "createOption": "fromImage"
              }
            },
            "networkProfile": {
              "networkInterfaces": [
                {
                  "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
                }
              ]
            }
          }
        }
      ],
      "outputs": {}
    },
    "parameters": {}
  },
  "kind": "template",
  "type": "Microsoft.Blueprint/blueprints/artifacts",
  "name": "myTemplate"
}
Negative test num. 7 - bicep file
@description('Username for the Virtual Machine.')
param adminUsername string

@description('Password for the Virtual Machine.')
@minLength(12)
@secure()
param adminPassword string

@description(
  'The Windows version for the VM. This will pick a fully patched image of this given Windows version.'
)
@allowed(
  [
    '2008-R2-SP1'
    '2012-Datacenter'
    '2012-R2-Datacenter'
    '2016-Nano-Server'
    '2016-Datacenter-with-Containers'
    '2016-Datacenter'
    '2019-Datacenter'
    '2019-Datacenter-Core'
    '2019-Datacenter-Core-smalldisk'
    '2019-Datacenter-Core-with-Containers'
    '2019-Datacenter-Core-with-Containers-smalldisk'
    '2019-Datacenter-smalldisk'
    '2019-Datacenter-with-Containers'
    '2019-Datacenter-with-Containers-smalldisk'
  ]
)
param OSVersion string = '2019-Datacenter'

@description('Size of the virtual machine.')
param vmSize string = 'Standard_D2_v3'

@description('Location for all resources.')
param location string = resourceGroup().location

@description('Name of the virtual machine.')
param vmName string = 'simple-vm'

var storageAccountName = 'bootdiags${uniqueString(resourceGroup().id)}'
var nicName = 'myVMNic'

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      adminPassword: adminPassword
    }
    storageProfile: {
      imageReference: {
        publisher: 'MicrosoftWindowsServer'
        offer: 'WindowsServer'
        sku: OSVersion
        version: 'latest'
      }
      osDisk: {
        createOption: 'FromImage'
        managedDisk: {
          storageAccountType: 'StandardSSD_LRS'
        }
      }
      dataDisks: [
        {
          diskSizeGB: 1023
          lun: 0
          createOption: 'Empty'
        }
      ]
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: resourceId('Microsoft.Network/networkInterfaces', nicName)
        }
      ]
    }
    diagnosticsProfile: {
      bootDiagnostics: {
        enabled: true
        storageUri: reference(
          resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
        ).primaryEndpoints.blob
      }
    }
  }
  dependsOn: [
    resourceId('Microsoft.Network/networkInterfaces', nicName)
    resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
  ]
}
Negative test num. 8 - json file
{
  "properties": {
    "template": {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "metadata": {
        "_generator": {
          "name": "bicep",
          "version": "0.4.1.14562",
          "templateHash": "8381960602397537918"
        }
      },
      "parameters": {
        "adminUsername": {
          "type": "string",
          "metadata": {
            "description": "Username for the Virtual Machine."
          }
        },
        "adminPassword": {
          "type": "secureString",
          "minLength": 12,
          "metadata": {
            "description": "Password for the Virtual Machine."
          }
        },
        "OSVersion": {
          "type": "string",
          "defaultValue": "2019-Datacenter",
          "allowedValues": [
            "2008-R2-SP1",
            "2012-Datacenter",
            "2012-R2-Datacenter",
            "2016-Nano-Server",
            "2016-Datacenter-with-Containers",
            "2016-Datacenter",
            "2019-Datacenter",
            "2019-Datacenter-Core",
            "2019-Datacenter-Core-smalldisk",
            "2019-Datacenter-Core-with-Containers",
            "2019-Datacenter-Core-with-Containers-smalldisk",
            "2019-Datacenter-smalldisk",
            "2019-Datacenter-with-Containers",
            "2019-Datacenter-with-Containers-smalldisk"
          ],
          "metadata": {
            "description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version."
          }
        },
        "vmSize": {
          "type": "string",
          "defaultValue": "Standard_D2_v3",
          "metadata": {
            "description": "Size of the virtual machine."
          }
        },
        "location": {
          "type": "string",
          "defaultValue": "[resourceGroup().location]",
          "metadata": {
            "description": "Location for all resources."
          }
        },
        "vmName": {
          "type": "string",
          "defaultValue": "simple-vm",
          "metadata": {
            "description": "Name of the virtual machine."
          }
        }
      },
      "functions": [],
      "variables": {
        "storageAccountName": "[format('bootdiags{0}', uniqueString(resourceGroup().id))]",
        "nicName": "myVMNic"
      },
      "resources": [
        {
          "type": "Microsoft.Compute/virtualMachines",
          "apiVersion": "2021-03-01",
          "name": "[parameters('vmName')]",
          "location": "[parameters('location')]",
          "properties": {
            "hardwareProfile": {
              "vmSize": "[parameters('vmSize')]"
            },
            "osProfile": {
              "computerName": "[parameters('vmName')]",
              "adminUsername": "[parameters('adminUsername')]",
              "adminPassword": "[parameters('adminPassword')]"
            },
            "storageProfile": {
              "imageReference": {
                "publisher": "MicrosoftWindowsServer",
                "offer": "WindowsServer",
                "sku": "[parameters('OSVersion')]",
                "version": "latest"
              },
              "osDisk": {
                "createOption": "FromImage",
                "managedDisk": {
                  "storageAccountType": "StandardSSD_LRS"
                }
              },
              "dataDisks": [
                {
                  "diskSizeGB": 1023,
                  "lun": 0,
                  "createOption": "Empty"
                }
              ]
            },
            "networkProfile": {
              "networkInterfaces": [
                {
                  "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
                }
              ]
            },
            "diagnosticsProfile": {
              "bootDiagnostics": {
                "enabled": true,
                "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))).primaryEndpoints.blob]"
              }
            }
          },
          "dependsOn": [
            "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]",
            "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
          ]
        }
      ],
      "outputs": {}
    },
    "parameters": {}
  },
  "kind": "template",
  "type": "Microsoft.Blueprint/blueprints/artifacts",
  "name": "myTemplate"
}
Negative test num. 9 - bicep file
@description('The name of the VM')
param virtualMachineName string = 'myVM'

@description('The virtual machine size.')
param virtualMachineSize string = 'Standard_D8s_v3'

@description('Specify the name of an existing VNet in the same resource group')
param existingVirtualNetworkName string

@description('Specify the resrouce group of the existing VNet')
param existingVnetResourceGroup string = resourceGroup().name

@description('Specify the name of the Subnet Name')
param existingSubnetName string

@description('Windows Server and SQL Offer')
@allowed(
  [
    'sql2019-ws2019'
    'sql2017-ws2019'
    'SQL2017-WS2016'
    'SQL2016SP1-WS2016'
    'SQL2016SP2-WS2016'
    'SQL2014SP3-WS2012R2'
    'SQL2014SP2-WS2012R2'
  ]
)
param imageOffer string = 'sql2019-ws2019'

@description('SQL Server Sku')
@allowed(['Standard', 'Enterprise', 'SQLDEV', 'Web', 'Express'])
param sqlSku string = 'Standard'

@description('Zone to deploy to')
@allowed([1, 2, 3])
param zone int = 1

@description('The admin user name of the VM')
param adminUsername string

@description('The admin password of the VM')
@secure()
param adminPassword string

@description('SQL Server Workload Type')
@allowed(['General', 'OLTP', 'DW'])
param storageWorkloadType string = 'General'

@description('Amount of data disks (1TB each) for SQL Data files')
@minValue(1)
@maxValue(8)
param sqlDataDisksCount int = 1

@description(
  'Path for SQL Data files. Please choose drive letter from F to Z, and other drives from A to E are reserved for system'
)
param dataPath string = 'F:\\SQLData'

@description('SQL Log UltraSSD Disk size in GiB.')
param sqlLogUltraSSDDiskSizeInGB int = 512

@description(
  'SQL Log UltraSSD Disk IOPS value representing the maximum IOPS that the disk can achieve.'
)
param sqlLogUltraSSDdiskIOPSReadWrite int = 20000

@description(
  'SQL Log UltraSSD Disk MBps value representing the maximum throughput that the disk can achieve.'
)
param sqlLogUltraSSDdiskMbpsReadWrite int = 500

@description(
  'Path for SQL Log files. Please choose drive letter from F to Z and different than the one used for SQL data. Drive letter from A to E are reserved for system'
)
param logPath string = 'G:\\SQLLog'

@description('Location for all resources.')
@allowed(['East US 2', 'SouthEast Asia', 'North Europe'])
param location string

var networkInterfaceName = '${virtualMachineName}-nic'
var networkSecurityGroupName = '${virtualMachineName}-nsg'
var networkSecurityGroupRules = [
  {
    name: 'RDP'
    properties: {
      priority: 300
      protocol: 'TCP'
      access: 'Allow'
      direction: 'Inbound'
      sourceAddressPrefix: '*'
      sourcePortRange: '*'
      destinationAddressPrefix: '*'
      destinationPortRange: '3389'
    }
  }
]
var publicIpAddressName = '${virtualMachineName}-publicip-${uniqueString(virtualMachineName)}'
var publicIpAddressType = 'Dynamic'
var publicIpAddressSku = 'Basic'
var diskConfigurationType = 'NEW'
var nsgId = networkSecurityGroup.id
var subnetRef = resourceId(
  existingVnetResourceGroup,
  'Microsoft.Network/virtualNetWorks/subnets',
  existingVirtualNetworkName,
  existingSubnetName
)
var dataDisksLuns = array(range(0, sqlDataDisksCount))
var logDisksLuns = array(range(sqlDataDisksCount, 1))
var dataDisks = {
  createOption: 'empty'
  caching: 'ReadOnly'
  writeAcceleratorEnabled: false
  storageAccountType: 'Premium_LRS'
  diskSizeGB: 1023
}
var tempDbPath = 'D:\\SQLTempdb'

resource virtualMachineName_dataDisk_UltraSSD 'Microsoft.Compute/disks@2019-11-01' = [
  for i in range(0, 1): {
    name: '${virtualMachineName}-dataDisk-UltraSSD-${i}'
    location: location
    sku: {
      name: 'UltraSSD_LRS'
    }
    zones: [zone]
    properties: {
      creationData: {
        createOption: 'Empty'
      }
      encryptionSettingsCollection: {
        enabled: false
        encryptionSettings: [
          {
            diskEncryptionKey: {
              sourceVault: {
                id: '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault'
              }
              secretUrl: 'https://myvmvault.vault-int.azure-int.net/secrets/{secret}'
            }
            keyEncryptionKey: {
              sourceVault: {
                id: '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault'
              }
              keyUrl: 'https://myvmvault.vault-int.azure-int.net/keys/{key}'
            }
          }
        ]
      }
      diskSizeGB: sqlLogUltraSSDDiskSizeInGB
      diskIOPSReadWrite: sqlLogUltraSSDdiskIOPSReadWrite
      diskMBpsReadWrite: sqlLogUltraSSDdiskMbpsReadWrite
    }
  }
]

resource publicIpAddress 'Microsoft.Network/publicIpAddresses@2020-05-01' = {
  name: publicIpAddressName
  location: location
  sku: {
    name: publicIpAddressSku
  }
  zones: [zone]
  properties: {
    publicIPAllocationMethod: publicIpAddressType
  }
}

resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2020-05-01' = {
  name: networkSecurityGroupName
  location: location
  properties: {
    securityRules: networkSecurityGroupRules
  }
}

resource networkInterface 'Microsoft.Network/networkInterfaces@2020-05-01' = {
  name: networkInterfaceName
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          subnet: {
            id: subnetRef
          }
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: {
            id: publicIpAddress.id
          }
        }
      }
    ]
    enableAcceleratedNetworking: true
    networkSecurityGroup: {
      id: nsgId
    }
  }
}

resource virtualMachine 'Microsoft.Compute/virtualMachines@2019-12-01' = {
  name: virtualMachineName
  location: location
  zones: [zone]
  properties: {
    hardwareProfile: {
      vmSize: virtualMachineSize
    }
    additionalCapabilities: {
      ultraSSDEnabled: 'true'
    }
    storageProfile: {
      osDisk: {
        createOption: 'fromImage'
        managedDisk: {
          storageAccountType: 'Premium_LRS'
        }
      }
      imageReference: {
        publisher: 'MicrosoftSQLServer'
        offer: imageOffer
        sku: sqlSku
        version: 'latest'
      }
      dataDisks: [
        for j in range(0, (sqlDataDisksCount + 1)): {
          lun: j
          createOption: 'attach'
          caching: ((j >= sqlDataDisksCount) ? 'None' : dataDisks.caching)
          managedDisk: {
            id: ((j >= sqlDataDisksCount)
              ? resourceId(
                  'Microsoft.Compute/disks/',
                  '${virtualMachineName}-dataDisk-UltraSSD-0'
                )
              : resourceId(
                  'Microsoft.Compute/disks/',
                  '${virtualMachineName}-dataDisk-${j}'
                ))
          }
        }
      ]
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: networkInterface.id
        }
      ]
    }
    osProfile: {
      computerName: virtualMachineName
      adminUsername: adminUsername
      adminPassword: adminPassword
      windowsConfiguration: {
        enableAutomaticUpdates: true
        provisionVMAgent: true
      }
    }
  }
  dependsOn: [virtualMachineName_dataDisk_UltraSSD, 'PremiumSSDLoop']
}

resource Microsoft_SqlVirtualMachine_SqlVirtualMachines_virtualMachine 'Microsoft.SqlVirtualMachine/SqlVirtualMachines@2017-03-01-preview' = {
  name: virtualMachineName
  location: location
  properties: {
    virtualMachineResourceId: virtualMachine.id
    sqlManagement: 'Full'
    sqlServerLicenseType: 'PAYG'
    storageConfigurationSettings: {
      diskConfigurationType: diskConfigurationType
      storageWorkloadType: storageWorkloadType
      sqlDataSettings: {
        luns: dataDisksLuns
        defaultFilePath: dataPath
      }
      sqlLogSettings: {
        luns: logDisksLuns
        defaultFilePath: logPath
      }
      sqlTempDbSettings: {
        defaultFilePath: tempDbPath
      }
    }
  }
}
Negative test num. 10 - json file
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "virtualMachineName": {
        "type": "String",
        "defaultValue": "myVM",
        "metadata": {
          "description": "The name of the VM"
        }
      },
      "virtualMachineSize": {
        "type": "String",
        "defaultValue": "Standard_D8s_v3",
        "metadata": {
          "description": "The virtual machine size."
        }
      },
      "existingVirtualNetworkName": {
        "type": "String",
        "metadata": {
          "description": "Specify the name of an existing VNet in the same resource group"
        }
      },
      "existingVnetResourceGroup": {
        "type": "String",
        "metadata": {
          "description": "Specify the resrouce group of the existing VNet"
        },
        "defaultValue": "[resourceGroup().name]"
      },
      "existingSubnetName": {
        "type": "String",
        "metadata": {
          "description": "Specify the name of the Subnet Name"
        }
      },
      "imageOffer": {
        "type": "String",
        "allowedValues": [
          "sql2019-ws2019",
          "sql2017-ws2019",
          "SQL2017-WS2016",
          "SQL2016SP1-WS2016",
          "SQL2016SP2-WS2016",
          "SQL2014SP3-WS2012R2",
          "SQL2014SP2-WS2012R2"
        ],
        "defaultValue": "sql2019-ws2019",
        "metadata": {
          "description": "Windows Server and SQL Offer"
        }
      },
      "sqlSku": {
        "type": "String",
        "allowedValues": [
          "Standard",
          "Enterprise",
          "SQLDEV",
          "Web",
          "Express"
        ],
        "defaultValue": "Standard",
        "metadata": {
          "description": "SQL Server Sku"
        }
      },
      "zone": {
        "defaultValue": 1,
        "allowedValues": [
          1,
          2,
          3
        ],
        "type": "Int",
        "metadata": {
          "description": "Zone to deploy to"
        }
      },
      "adminUsername": {
        "type": "String",
        "metadata": {
          "description": "The admin user name of the VM"
        }
      },
      "adminPassword": {
        "type": "SecureString",
        "metadata": {
          "description": "The admin password of the VM"
        }
      },
      "storageWorkloadType": {
        "type": "String",
        "allowedValues": [
          "General",
          "OLTP",
          "DW"
        ],
        "defaultValue": "General",
        "metadata": {
          "description": "SQL Server Workload Type"
        }
      },
      "sqlDataDisksCount": {
        "type": "int",
        "defaultValue": 1,
        "minValue": 1,
        "maxValue": 8,
        "metadata": {
          "description": "Amount of data disks (1TB each) for SQL Data files"
        }
      },
      "dataPath": {
        "type": "String",
        "defaultValue": "F:\\SQLData",
        "metadata": {
          "description": "Path for SQL Data files. Please choose drive letter from F to Z, and other drives from A to E are reserved for system"
        }
      },
      "sqlLogUltraSSDDiskSizeInGB": {
        "defaultValue": 512,
        "type": "int",
        "metadata": {
          "description": "SQL Log UltraSSD Disk size in GiB."
        }
      },
      "sqlLogUltraSSDdiskIOPSReadWrite": {
        "defaultValue": 20000,
        "type": "int",
        "metadata": {
          "description": "SQL Log UltraSSD Disk IOPS value representing the maximum IOPS that the disk can achieve."
        }
      },
      "sqlLogUltraSSDdiskMbpsReadWrite": {
        "defaultValue": 500,
        "type": "int",
        "metadata": {
          "description": "SQL Log UltraSSD Disk MBps value representing the maximum throughput that the disk can achieve."
        }
      },
      "logPath": {
        "type": "String",
        "defaultValue": "G:\\SQLLog",
        "metadata": {
          "description": "Path for SQL Log files. Please choose drive letter from F to Z and different than the one used for SQL data. Drive letter from A to E are reserved for system"
        }
      },
      "location": {
        "type": "string",
        "metadata": {
          "description": "Location for all resources."
        },
        "allowedValues": [
          "East US 2",
          "SouthEast Asia",
          "North Europe"
        ]
      }
    },
    "variables": {
      "networkInterfaceName": "[concat(parameters('virtualMachineName'), '-nic')]",
      "networkSecurityGroupName": "[concat(parameters('virtualMachineName'), '-nsg')]",
      "networkSecurityGroupRules": [
        {
          "name": "RDP",
          "properties": {
            "priority": 300,
            "protocol": "TCP",
            "access": "Allow",
            "direction": "Inbound",
            "sourceAddressPrefix": "*",
            "sourcePortRange": "*",
            "destinationAddressPrefix": "*",
            "destinationPortRange": "3389"
          }
        }
      ],
      "publicIpAddressName": "[concat(parameters('virtualMachineName'), '-publicip-', uniqueString(parameters('virtualMachineName')))]",
      "publicIpAddressType": "Dynamic",
      "publicIpAddressSku": "Basic",
      "diskConfigurationType": "NEW",
      "nsgId": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]",
      "subnetRef": "[resourceID(parameters('existingVNetResourceGroup'), 'Microsoft.Network/virtualNetWorks/subnets', parameters('existingVirtualNetworkName'), parameters('existingSubNetName'))]",
      "dataDisksLuns": "[array(range(0 ,parameters('sqlDataDisksCount')))]",
      "logDisksLuns": "[array(range(parameters('sqlDataDisksCount'), 1))]",
      "dataDisks": {
        "createOption": "empty",
        "caching": "ReadOnly",
        "writeAcceleratorEnabled": false,
        "storageAccountType": "Premium_LRS",
        "diskSizeGB": 1023
      },
      "tempDbPath": "D:\\SQLTempdb"
    },
    "resources": [
      {
        "type": "Microsoft.Compute/disks",
        "apiVersion": "2019-11-01",
        "name": "[concat(parameters('virtualMachineName'),'-dataDisk-UltraSSD-',copyIndex())]",
        "location": "[parameters('location')]",
        "sku": {
          "name": "UltraSSD_LRS"
        },
        "zones": [
          "[parameters('zone')]"
        ],
        "properties": {
          "creationData": {
            "createOption": "Empty"
          },
      "encryptionSettingsCollection": {
                  "enabled": false,
                  "encryptionSettings": [
                    {
                      "diskEncryptionKey": {
                        "sourceVault": {
                          "id": "/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault"
                        },
                        "secretUrl": "https://myvmvault.vault-int.azure-int.net/secrets/{secret}"
                      },
                      "keyEncryptionKey": {
                        "sourceVault": {
                          "id": "/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault"
                        },
                        "keyUrl": "https://myvmvault.vault-int.azure-int.net/keys/{key}"
                      }
                    }
                  ]
                },
          "diskSizeGB": "[parameters('sqlLogUltraSSDDiskSizeInGB')]",
          "diskIOPSReadWrite": "[parameters('sqlLogUltraSSDdiskIOPSReadWrite')]",
          "diskMBpsReadWrite": "[parameters('sqlLogUltraSSDdiskMbpsReadWrite')]"
        },
        "copy": {
          "name": "UltraSSDLoop",
          "count": 1
        }
      },
      {
        "type": "Microsoft.Network/publicIpAddresses",
        "apiVersion": "2020-05-01",
        "name": "[variables('publicIpAddressName')]",
        "location": "[parameters('location')]",
        "sku": {
          "name": "[variables('publicIpAddressSku')]"
        },
        "zones": [
          "[parameters('zone')]"
        ],
        "properties": {
          "publicIpAllocationMethod": "[variables('publicIpAddressType')]"
        }
      },
      {
        "type": "Microsoft.Network/networkSecurityGroups",
        "apiVersion": "2020-05-01",
        "name": "[variables('networkSecurityGroupName')]",
        "location": "[parameters('location')]",
        "properties": {
          "securityRules": "[variables('networkSecurityGroupRules')]"
        }
      },
      {
        "type": "Microsoft.Network/networkInterfaces",
        "apiVersion": "2020-05-01",
        "name": "[variables('networkInterfaceName')]",
        "location": "[parameters('location')]",
        "dependsOn": [
          "[resourceId('Microsoft.Network/networkSecurityGroups/', variables('networkSecurityGroupName'))]",
          "[resourceId('Microsoft.Network/publicIpAddresses/', variables('publicIpAddressName'))]"
        ],
        "properties": {
          "ipConfigurations": [
            {
              "name": "ipconfig1",
              "properties": {
                "subnet": {
                  "id": "[variables('subnetRef')]"
                },
                "privateIPAllocationMethod": "Dynamic",
                "publicIpAddress": {
                  "id": "[resourceId('Microsoft.Network/publicIpAddresses', variables('publicIpAddressName'))]"
                }
              }
            }
          ],
          "enableAcceleratedNetworking": true,
          "networkSecurityGroup": {
            "id": "[variables('nsgId')]"
          }
        }
      },
      {
        "type": "Microsoft.Compute/virtualMachines",
        "apiVersion": "2019-12-01",
        "name": "[parameters('virtualMachineName')]",
        "location": "[parameters('location')]",
        "dependsOn": [
          "[resourceId('Microsoft.Network/networkInterfaces/', variables('networkInterfaceName'))]",
          "UltraSSDLoop",
          "PremiumSSDLoop"
        ],
        "zones": [
          "[parameters('zone')]"
        ],
        "properties": {
          "hardwareProfile": {
            "vmSize": "[parameters('virtualMachineSize')]"
          },
          "additionalCapabilities": {
            "ultraSSDEnabled": "true"
          },
          "storageProfile": {
            "osDisk": {
              "createOption": "fromImage",
              "managedDisk": {
                "storageAccountType": "Premium_LRS"
              }
            },
            "imageReference": {
              "publisher": "MicrosoftSQLServer",
              "offer": "[parameters('imageOffer')]",
              "sku": "[parameters('sqlSku')]",
              "version": "latest"
            },
            "copy": [
              {
                "name": "dataDisks",
                "count": "[add(parameters('sqlDataDisksCount'), 1)]",
                "input": {
                  "lun": "[copyIndex('dataDisks')]",
                  "createOption": "attach",
                  "caching": "[if(greaterOrEquals(copyIndex('dataDisks'), parameters('sqlDataDisksCount')), 'None', variables('dataDisks').caching)]",
                  "managedDisk": {
                    "id": "[if(greaterOrEquals(copyIndex('dataDisks'), parameters('sqlDataDisksCount')), resourceId('Microsoft.Compute/disks/', concat(parameters('virtualMachineName'),'-dataDisk-UltraSSD-0')), resourceId('Microsoft.Compute/disks/', concat(parameters('virtualMachineName'),'-dataDisk-',copyIndex('dataDisks'))))]"
                  }
                }
              }
            ]
          },
          "networkProfile": {
            "networkInterfaces": [
              {
                "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
              }
            ]
          },
          "osProfile": {
            "computerName": "[parameters('virtualMachineName')]",
            "adminUsername": "[parameters('adminUsername')]",
            "adminPassword": "[parameters('adminPassword')]",
            "windowsConfiguration": {
              "enableAutomaticUpdates": true,
              "provisionVmAgent": true
            }
          }
        }
      },
      {
        "type": "Microsoft.SqlVirtualMachine/SqlVirtualMachines",
        "apiVersion": "2017-03-01-preview",
        "name": "[parameters('virtualMachineName')]",
        "location": "[parameters('location')]",
        "dependsOn": [
          "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]"
        ],
        "properties": {
          "virtualMachineResourceId": "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]",
          "sqlManagement": "Full",
          "SqlServerLicenseType": "PAYG",
          "StorageConfigurationSettings": {
            "DiskConfigurationType": "[variables('diskConfigurationType')]",
            "StorageWorkloadType": "[parameters('storageWorkloadType')]",
            "SQLDataSettings": {
              "LUNs": "[variables('dataDisksLUNs')]",
              "DefaultFilePath": "[parameters('dataPath')]"
            },
            "SQLLogSettings": {
              "Luns": "[variables('logDisksLUNs')]",
              "DefaultFilePath": "[parameters('logPath')]"
            },
            "SQLTempDbSettings": {
              "DefaultFilePath": "[variables('tempDbPath')]"
            }
          }
        }
      }
    ]
  }