@description('Name of the VM') param vmName string @description('Azure region') param location string = resourceGroup().location @description('VM size, e.g. Standard_D2s_v5') param vmSize string = 'Standard_D2s_v5' @description('Admin username') param adminUsername string @description('SSH public key contents') @secure() param adminPublicKey string @description('Address space for the new VNet') param vnetAddressPrefix string = '10.0.0.0/16' @description('Subnet prefix') param subnetAddressPrefix string = '10.0.0.0/24' @description('OS disk size in GB') param osDiskSizeGb int = 30 @description('OS disk storage type') param osDiskType string = 'Premium_LRS' @description('Availability zone (1, 2, or 3); empty for regional') param zone string = '' @description('Tags applied to all resources') param tags object = {} @description('Source address prefix allowed for SSH inbound (CIDR or IP). Required — supply your public IP (e.g. "203.0.113.42/32") or a trusted CIDR range. "*" exposes port 22 to the entire internet; only pass it explicitly when you have accepted that risk.') param sshSourceAddressPrefix string var vnetName = '${vmName}-vnet' var subnetName = 'default' var nsgName = '${vmName}-nsg' var publicIpName = '${vmName}-ip' var nicName = '${vmName}-nic' resource nsg 'Microsoft.Network/networkSecurityGroups@2024-05-01' = { name: nsgName location: location tags: tags properties: { securityRules: [ { name: 'AllowSSH' properties: { priority: 1000 access: 'Allow' direction: 'Inbound' protocol: 'Tcp' sourceAddressPrefix: sshSourceAddressPrefix sourcePortRange: '*' destinationAddressPrefix: '*' destinationPortRange: '22' } } ] } } resource vnet 'Microsoft.Network/virtualNetworks@2024-05-01' = { name: vnetName location: location tags: tags properties: { addressSpace: { addressPrefixes: [vnetAddressPrefix] } subnets: [ { name: subnetName properties: { addressPrefix: subnetAddressPrefix networkSecurityGroup: { id: nsg.id } } } ] } } resource publicIp 'Microsoft.Network/publicIPAddresses@2024-05-01' = { name: publicIpName location: location tags: tags sku: { name: 'Standard' } properties: { publicIPAllocationMethod: 'Static' } } resource nic 'Microsoft.Network/networkInterfaces@2024-05-01' = { name: nicName location: location tags: tags properties: { ipConfigurations: [ { name: 'ipconfig1' properties: { subnet: { id: '${vnet.id}/subnets/${subnetName}' } publicIPAddress: { id: publicIp.id } privateIPAllocationMethod: 'Dynamic' } } ] } } resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = { name: vmName location: location tags: tags zones: empty(zone) ? null : [zone] properties: { hardwareProfile: { vmSize: vmSize } storageProfile: { imageReference: { publisher: 'Canonical' offer: 'ubuntu-24_04-lts' sku: 'server' version: 'latest' } osDisk: { createOption: 'FromImage' diskSizeGB: osDiskSizeGb managedDisk: { storageAccountType: osDiskType } } } osProfile: { computerName: vmName adminUsername: adminUsername linuxConfiguration: { disablePasswordAuthentication: true ssh: { publicKeys: [ { path: '/home/${adminUsername}/.ssh/authorized_keys' keyData: adminPublicKey } ] } } } networkProfile: { networkInterfaces: [ { id: nic.id } ] } } } output vmId string = vm.id output publicIpAddress string = publicIp.properties.ipAddress