Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

Quickstart: Create an Ubuntu Linux virtual machine using a Bicep file

Applies to: ✔️ Linux VMs

This quickstart shows you how to use a Bicep file to deploy an Ubuntu Linux virtual machine (VM) in Azure.

Bicep is a domain-specific language (DSL) that uses declarative syntax to deploy Azure resources. It provides concise syntax, reliable type safety, and support for code reuse. Bicep offers the best authoring experience for your infrastructure-as-code solutions in Azure.

Prerequisites

If you don't have an Azure subscription, create a free account before you begin.

Review the Bicep file

The Bicep file used in this quickstart is from Azure Quickstart Templates.

@description('The name of your Virtual Machine.')
param vmName string = 'simpleLinuxVM'

@description('Username for the Virtual Machine.')
param adminUsername string

@description('Type of authentication to use on the Virtual Machine. SSH key is recommended.')
@allowed([
 'sshPublicKey'
 'password'
])
param authenticationType string = 'password'

@description('SSH Key or password for the Virtual Machine. SSH key is recommended.')
@secure()
param adminPasswordOrKey string

@description('Unique DNS Name for the Public IP used to access the Virtual Machine.')
param dnsLabelPrefix string = toLower('${vmName}-${uniqueString(resourceGroup().id)}')

@description('The Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version.')
@allowed([
 'Ubuntu-2004'
 'Ubuntu-2204'
])
param ubuntuOSVersion string = 'Ubuntu-2004'

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

@description('The size of the VM')
param vmSize string = 'Standard_D2s_v3'

@description('Name of the VNET')
param virtualNetworkName string = 'vNet'

@description('Name of the subnet in the virtual network')
param subnetName string = 'Subnet'

@description('Name of the Network Security Group')
param networkSecurityGroupName string = 'SecGroupNet'

@description('Security Type of the Virtual Machine.')
@allowed([
 'Standard'
 'TrustedLaunch'
])
param securityType string = 'TrustedLaunch'

var imageReference = {
 'Ubuntu-2004': {
 publisher: 'Canonical'
 offer: '0001-com-ubuntu-server-focal'
 sku: '20_04-lts-gen2'
 version: 'latest'
 }
 'Ubuntu-2204': {
 publisher: 'Canonical'
 offer: '0001-com-ubuntu-server-jammy'
 sku: '22_04-lts-gen2'
 version: 'latest'
 }
}
var publicIPAddressName = '${vmName}PublicIP'
var networkInterfaceName = '${vmName}NetInt'
var osDiskType = 'Standard_LRS'
var subnetAddressPrefix = '10.1.0.0/24'
var addressPrefix = '10.1.0.0/16'
var linuxConfiguration = {
 disablePasswordAuthentication: true
 ssh: {
 publicKeys: [
 {
 path: '/home/${adminUsername}/.ssh/authorized_keys'
 keyData: adminPasswordOrKey
 }
 ]
 }
}
var securityProfileJson = {
 uefiSettings: {
 secureBootEnabled: true
 vTpmEnabled: true
 }
 securityType: securityType
}
var extensionName = 'GuestAttestation'
var extensionPublisher = 'Microsoft.Azure.Security.LinuxAttestation'
var extensionVersion = '1.0'
var maaTenantName = 'GuestAttestation'
var maaEndpoint = substring('emptystring', 0, 0)

resource networkInterface 'Microsoft.Network/networkInterfaces@2023-09-01' = {
 name: networkInterfaceName
 location: location
 properties: {
 ipConfigurations: [
 {
 name: 'ipconfig1'
 properties: {
 subnet: {
 id: virtualNetwork.properties.subnets[0].id
 }
 privateIPAllocationMethod: 'Dynamic'
 publicIPAddress: {
 id: publicIPAddress.id
 }
 }
 }
 ]
 networkSecurityGroup: {
 id: networkSecurityGroup.id
 }
 }
}

resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2023-09-01' = {
 name: networkSecurityGroupName
 location: location
 properties: {
 securityRules: [
 {
 name: 'SSH'
 properties: {
 priority: 1000
 protocol: 'Tcp'
 access: 'Allow'
 direction: 'Inbound'
 sourceAddressPrefix: '*'
 sourcePortRange: '*'
 destinationAddressPrefix: '*'
 destinationPortRange: '22'
 }
 }
 ]
 }
}

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-09-01' = {
 name: virtualNetworkName
 location: location
 properties: {
 addressSpace: {
 addressPrefixes: [
 addressPrefix
 ]
 }
 subnets: [
 {
 name: subnetName
 properties: {
 networkSecurityGroup: {
 id: networkSecurityGroup.id
 }
 addressPrefix: subnetAddressPrefix
 privateEndpointNetworkPolicies: 'Enabled'
 privateLinkServiceNetworkPolicies: 'Enabled'
 }
 }
 ]
 }
}

resource publicIPAddress 'Microsoft.Network/publicIPAddresses@2023-09-01' = {
 name: publicIPAddressName
 location: location
 sku: {
 name: 'Basic'
 }
 properties: {
 publicIPAllocationMethod: 'Dynamic'
 publicIPAddressVersion: 'IPv4'
 dnsSettings: {
 domainNameLabel: dnsLabelPrefix
 }
 idleTimeoutInMinutes: 4
 }
}

resource vm 'Microsoft.Compute/virtualMachines@2023-09-01' = {
 name: vmName
 location: location
 properties: {
 hardwareProfile: {
 vmSize: vmSize
 }
 storageProfile: {
 osDisk: {
 createOption: 'FromImage'
 managedDisk: {
 storageAccountType: osDiskType
 }
 }
 imageReference: imageReference[ubuntuOSVersion]
 }
 networkProfile: {
 networkInterfaces: [
 {
 id: networkInterface.id
 }
 ]
 }
 osProfile: {
 computerName: vmName
 adminUsername: adminUsername
 adminPassword: adminPasswordOrKey
 linuxConfiguration: ((authenticationType == 'password') ? null : linuxConfiguration)
 }
 securityProfile: (securityType == 'TrustedLaunch') ? securityProfileJson : null
 }
}

resource vmExtension 'Microsoft.Compute/virtualMachines/extensions@2023-09-01' = if (securityType == 'TrustedLaunch' && securityProfileJson.uefiSettings.secureBootEnabled && securityProfileJson.uefiSettings.vTpmEnabled) {
 parent: vm
 name: extensionName
 location: location
 properties: {
 publisher: extensionPublisher
 type: extensionName
 typeHandlerVersion: extensionVersion
 autoUpgradeMinorVersion: true
 enableAutomaticUpgrade: true
 settings: {
 AttestationConfig: {
 MaaSettings: {
 maaEndpoint: maaEndpoint
 maaTenantName: maaTenantName
 }
 }
 }
 }
}

output adminUsername string = adminUsername
output hostname string = publicIPAddress.properties.dnsSettings.fqdn
output sshCommand string = 'ssh ${adminUsername}@${publicIPAddress.properties.dnsSettings.fqdn}'

Several resources are defined in the Bicep file:

Deploy the Bicep file

  1. Save the Bicep file as main.bicep to your local computer.

  2. Deploy the Bicep file using either Azure CLI or Azure PowerShell.

    az group create --name exampleRG --location eastus
    
    az deployment group create --resource-group exampleRG --template-file main.bicep --parameters adminUsername=<admin-username>
    

    Note

    Replace <admin-username> with a unique username. You'll also be prompted to enter adminPasswordOrKey.

    When the deployment finishes, you should see a message indicating the deployment succeeded.

Cost information isn't presented during the virtual machine creation process for Bicep like it is for the Azure portal. If you want to learn more about how cost works for virtual machines, see the Cost optimization Overview page.

Review deployed resources

Use the Azure portal, Azure CLI, or Azure PowerShell to list the deployed resources in the resource group.

az resource list --resource-group exampleRG

Clean up resources

When no longer needed, use the Azure portal, Azure CLI, or Azure PowerShell to delete the VM and all of the resources in the resource group.

az group delete --name exampleRG

Next steps

In this quickstart, you deployed a simple virtual machine using a Bicep file. To learn more about Azure virtual machines, continue to the tutorial for Linux VMs.


Feedback

Was this page helpful?

Additional resources