This project demonstrates how to automate the deployment of Azure Virtual Machines using Bicep (Infrastructure as Code) and Azure CLI. It is designed for beginners and intermediate Azure Infrastructure Engineers, with step-by-step instructions, including installation, setup, deployment, validation, and cleanup.
This project automates the provisioning of:
- A Resource Group
- A Virtual Network & Subnet
- A Network Interface
- A Public IP
- A Network Security Group
- A Virtual Machine (Windows/Linux)
- VM Extensions (optional)
All resources are deployed using a Bicep template executed through Azure CLI.
Follow the steps in order.
Download & install Azure CLI: https://learn.microsoft.com/cli/azure/install-azure-cli
Verify installation:
az --versionRun:
az bicep installVerify:
az bicep versionDownload: https://code.visualstudio.com/
Install extensions:
- Bicep Extension
- Azure CLI Tools Extension
Run:
az loginSelect your Azure account.
(Optional) set subscription:
az account set --subscription "<subscription-name-or-id>"Azure-VM-Automation/
│── main.bicep
│── parameters.json
│── deploy.sh (optional for automated script)
│── README.md
Create a file main.bicep and paste this basic template:
param location string = resourceGroup().location
param vmName string
param adminUsername string
param adminPassword string
resource vnet 'Microsoft.Network/virtualNetworks@2023-04-01' = {
name: '${vmName}-vnet'
location: location
properties: {
addressSpace: {
addressPrefixes: [ '10.0.0.0/16' ]
}
subnets: [
{
name: 'default'
properties: {
addressPrefix: '10.0.1.0/24'
}
}
]
}
}
resource publicIP 'Microsoft.Network/publicIPAddresses@2023-04-01' = {
name: '${vmName}-pip'
location: location
properties: {
publicIPAllocationMethod: 'Dynamic'
}
}
resource nic 'Microsoft.Network/networkInterfaces@2023-04-01' = {
name: '${vmName}-nic'
location: location
properties: {
ipConfigurations: [
{
name: 'ipconfig1'
properties: {
subnet: {
id: vnet.properties.subnets[0].id
}
publicIPAddress: {
id: publicIP.id
}
}
}
]
}
}
resource vm 'Microsoft.Compute/virtualMachines@2023-09-01' = {
name: vmName
location: location
properties: {
hardwareProfile: {
vmSize: 'Standard_B1s'
}
storageProfile: {
imageReference: {
publisher: 'Canonical'
offer: '0001-com-ubuntu-server-focal'
sku: '20_04-lts'
version: 'latest'
}
osDisk: {
createOption: 'FromImage'
}
}
osProfile: {
computerName: vmName
adminUsername: adminUsername
adminPassword: adminPassword
}
networkProfile: {
networkInterfaces: [
{
id: nic.id
}
]
}
}
}Create this file:
{
"vmName": { "value": "myAzureVM" },
"adminUsername": { "value": "azureuser" },
"adminPassword": { "value": "YourPassword123!" }
}⚠ Use a strong password or enable SSH for Linux.
Open terminal inside project folder:
az group create -n vm-rg -l eastusDeploy:
az deployment group create \
--resource-group vm-rg \
--template-file main.bicep \
--parameters @parameters.jsonDeployment takes 2–3 minutes.
az vm list -g vm-rg -o tableGet public IP:
az vm show -g vm-rg -n myAzureVM -d --query publicIps -o tsvSSH into VM:
ssh azureuser@<public-ip>If you want to delete everything:
az group delete -n vm-rg --yes --no-wait