{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "location": { "type": "string", "defaultValue": "westus2", "metadata": { "description": "Azure region for all resources. Any valid Azure region is allowed (no allowedValues restriction)." } }, "vmName": { "type": "string", "defaultValue": "vm-openclaw", "metadata": { "description": "OpenClaw VM name." } }, "vmSize": { "type": "string", "defaultValue": "Standard_B2as_v2", "metadata": { "description": "Azure VM size for OpenClaw host." } }, "adminUsername": { "type": "string", "defaultValue": "openclaw", "minLength": 1, "maxLength": 32, "metadata": { "description": "Linux admin username." } }, "sshPublicKey": { "type": "string", "metadata": { "description": "SSH public key content (for example ssh-ed25519 ...)." } }, "vnetName": { "type": "string", "defaultValue": "vnet-openclaw", "metadata": { "description": "Virtual network name." } }, "vnetAddressPrefix": { "type": "string", "defaultValue": "10.40.0.0/16", "metadata": { "description": "Address space for the virtual network." } }, "vmSubnetName": { "type": "string", "defaultValue": "snet-openclaw-vm", "metadata": { "description": "Subnet name for OpenClaw VM." } }, "vmSubnetPrefix": { "type": "string", "defaultValue": "10.40.2.0/24", "metadata": { "description": "Address prefix for VM subnet." } }, "bastionSubnetPrefix": { "type": "string", "defaultValue": "10.40.1.0/26", "metadata": { "description": "Address prefix for AzureBastionSubnet (must be /26 or larger)." } }, "nsgName": { "type": "string", "defaultValue": "nsg-openclaw-vm", "metadata": { "description": "Network security group for VM subnet." } }, "nicName": { "type": "string", "defaultValue": "nic-openclaw-vm", "metadata": { "description": "NIC for OpenClaw VM." } }, "bastionName": { "type": "string", "defaultValue": "bas-openclaw", "metadata": { "description": "Azure Bastion host name." } }, "bastionPublicIpName": { "type": "string", "defaultValue": "pip-openclaw-bastion", "metadata": { "description": "Public IP used by Bastion." } }, "osDiskSizeGb": { "type": "int", "defaultValue": 64, "minValue": 30, "maxValue": 1024, "metadata": { "description": "OS disk size in GiB." } } }, "variables": { "bastionSubnetName": "AzureBastionSubnet" }, "resources": [ { "type": "Microsoft.Network/networkSecurityGroups", "apiVersion": "2023-11-01", "name": "[parameters('nsgName')]", "location": "[parameters('location')]", "properties": { "securityRules": [ { "name": "AllowSshFromAzureBastionSubnet", "properties": { "priority": 100, "access": "Allow", "direction": "Inbound", "protocol": "Tcp", "sourcePortRange": "*", "destinationPortRange": "22", "sourceAddressPrefix": "[parameters('bastionSubnetPrefix')]", "destinationAddressPrefix": "*" } }, { "name": "DenyInternetSsh", "properties": { "priority": 110, "access": "Deny", "direction": "Inbound", "protocol": "Tcp", "sourcePortRange": "*", "destinationPortRange": "22", "sourceAddressPrefix": "Internet", "destinationAddressPrefix": "*" } }, { "name": "DenyVnetSsh", "properties": { "priority": 120, "access": "Deny", "direction": "Inbound", "protocol": "Tcp", "sourcePortRange": "*", "destinationPortRange": "22", "sourceAddressPrefix": "VirtualNetwork", "destinationAddressPrefix": "*" } } ] } }, { "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2023-11-01", "name": "[parameters('vnetName')]", "location": "[parameters('location')]", "properties": { "addressSpace": { "addressPrefixes": ["[parameters('vnetAddressPrefix')]"] }, "subnets": [ { "name": "[variables('bastionSubnetName')]", "properties": { "addressPrefix": "[parameters('bastionSubnetPrefix')]" } }, { "name": "[parameters('vmSubnetName')]", "properties": { "addressPrefix": "[parameters('vmSubnetPrefix')]", "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]" } } } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]" ] }, { "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2023-11-01", "name": "[parameters('bastionPublicIpName')]", "location": "[parameters('location')]", "sku": { "name": "Standard" }, "properties": { "publicIPAllocationMethod": "Static" } }, { "type": "Microsoft.Network/bastionHosts", "apiVersion": "2023-11-01", "name": "[parameters('bastionName')]", "location": "[parameters('location')]", "sku": { "name": "Standard" }, "dependsOn": [ "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]", "[resourceId('Microsoft.Network/publicIPAddresses', parameters('bastionPublicIpName'))]" ], "properties": { "enableTunneling": true, "ipConfigurations": [ { "name": "bastionIpConfig", "properties": { "subnet": { "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), variables('bastionSubnetName'))]" }, "publicIPAddress": { "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('bastionPublicIpName'))]" } } } ] } }, { "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2023-11-01", "name": "[parameters('nicName')]", "location": "[parameters('location')]", "dependsOn": ["[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"], "properties": { "ipConfigurations": [ { "name": "ipconfig1", "properties": { "privateIPAllocationMethod": "Dynamic", "subnet": { "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), parameters('vmSubnetName'))]" } } } ] } }, { "type": "Microsoft.Compute/virtualMachines", "apiVersion": "2023-09-01", "name": "[parameters('vmName')]", "location": "[parameters('location')]", "dependsOn": ["[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]"], "properties": { "hardwareProfile": { "vmSize": "[parameters('vmSize')]" }, "osProfile": { "computerName": "[parameters('vmName')]", "adminUsername": "[parameters('adminUsername')]", "linuxConfiguration": { "disablePasswordAuthentication": true, "ssh": { "publicKeys": [ { "path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]", "keyData": "[parameters('sshPublicKey')]" } ] } } }, "storageProfile": { "imageReference": { "publisher": "Canonical", "offer": "ubuntu-24_04-lts", "sku": "server", "version": "latest" }, "osDisk": { "createOption": "FromImage", "diskSizeGB": "[parameters('osDiskSizeGb')]", "managedDisk": { "storageAccountType": "StandardSSD_LRS" } } }, "networkProfile": { "networkInterfaces": [ { "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('nicName'))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true } } } } ], "outputs": { "vmName": { "type": "string", "value": "[parameters('vmName')]" }, "vmPrivateIp": { "type": "string", "value": "[reference(resourceId('Microsoft.Network/networkInterfaces', parameters('nicName')), '2023-11-01').ipConfigurations[0].properties.privateIPAddress]" }, "vnetName": { "type": "string", "value": "[parameters('vnetName')]" }, "vmSubnetName": { "type": "string", "value": "[parameters('vmSubnetName')]" }, "bastionName": { "type": "string", "value": "[parameters('bastionName')]" }, "bastionResourceId": { "type": "string", "value": "[resourceId('Microsoft.Network/bastionHosts', parameters('bastionName'))]" } } }