DEV Community

Cover image for Azure CLI: Setup Linux VM, VNet, Storage & Key Vault with Budget Alerts—A Comprehensive Step-by-Step Infrastructure Guide.
adegbola adeniyi
adegbola adeniyi

Posted on

Azure CLI: Setup Linux VM, VNet, Storage & Key Vault with Budget Alerts—A Comprehensive Step-by-Step Infrastructure Guide.

Introduction

Cloud computing has revolutionized how developers and IT professionals build, deploy, and manage applications. Among the leading platforms, Microsoft Azure stands out for its flexibility, scalability, and powerful infrastructure services. Whether you’re experimenting with Linux environments, hosting applications, or designing complex network architectures, Azure provides the tools to make it seamless.

In this guide, we’ll walk through the step-by-step process of creating a Linux Virtual Machine (VM) on Azure and then configuring a Virtual Network (VNet) with a Subnet using the Azure Command-Line Interface (CLI). By the end, you’ll not only understand how to spin up a Linux VM but also how to establish secure and organized network structures that support enterprise-grade applications.

Before diving in, it’s important to understand one of Azure’s fundamental concepts: the Resource Group.

A Resource Group in Azure is a logical container that holds related resources for an application or workload. It allows you to manage and organize resources such as VMs, storage accounts, and networks collectively, making deployment, monitoring, and lifecycle management much easier. Think of it as a folder where all the components of your project live together.

This tutorial is designed for beginners and intermediate users who want hands-on experience with Azure’s infrastructure services. No prior deep knowledge of cloud networking is required—just a willingness to learn and follow along.

This tutorial is broken down into several steps:

Step 1: Installing Azure Package Manager, Logging-in Into Azure Portal and Setting up Our Subscription
cli
winget install Microsoft.AzureCLI: Installs the Azure CLI tool using the Windows package manager (winget).

cli
az login --use-device-code: logs you into Azure by generating a temporary device code that you enter in a browser, allowing secure authentication without needing to store credentials directly in the terminal.

cli
az account show: displays details about the currently active Azure subscription and account context, including subscription ID, name, tenant ID, and whether it’s set as the default.

Step 2: Setting Up and Creating a Resource Group for holding, organizing and managing all related Resources meant for this Project

cli
RG=az-cli-lab-rg: defining a shell variable named RG with the value az-cli-lab-rg.
LOCATION=eastus: defining a shell variable named LOCATION with the value eastus
az group create --name $RG --location $LOCATION: - --name $RG specifies the name of the resource group (in this case, the value stored in the variable RG, e.g., az-cli-lab-rg).
--location $LOCATION defines the Azure region where the resource group will be hosted (e.g., eastus).

cli
az group show --name $RG:is used to retrieve and display details about an existing Azure Resource Group.

Step 3: Setting up Virtual Network, Sub Network, NSG and creating the inbound security rules(SSH and Https) and Allocating a Public IP.

cli
az network vnet create: Creates a new Virtual Network.
--resource-group $RG: Specifies the resource group where the VNet will be placed (using the variable RG).
--name lab-vnet: Names the VNet lab-vnet
--address-prefix 10.0.0.0/16: - Defines the IP address space for the VNet. Here, it allows addresses from 10.0.0.0 to 10.0.255.255.
--location $LOCATION: Sets the Azure region where the VNet will be created (using the variable LOCATION).

cli
az network vnet subnet create: Creates a new subnet within a specified VNet.
--resource-group $RG: Identifies the resource group where the VNet and subnet reside.
--vnet-name lab-vnet: Specifies the VNet (lab-vnet) in which the subnet will be created.
--name lab-subnet: - Names the subnet lab-subnet.
--address-prefix 10.0.1.0/24:- Defines the IP address range for the subnet. Here, it allows 256 addresses (from 10.0.1.0 to 10.0.1.255).

Cli
az network nsg create: Creates a new Network Security Group (NSG) in Azure.
--resource-group $RG: Specifies the resource group where the NSG will be created.
--name lab-nsg: Names the NSG lab-nsg.

Cli

az network nsg rule create: Adds a new rule to the NSG.
--resource-group $RG: Resource group where the NSG resides.
--nsg-name lab-nsg: Target NSG name.
--name AllowSSH / AllowHTTP: Names of the rules.
--priority 1000/1010: Determines rule order (lower = higher priority).
--destination-port-ranges 22 SSH Access /80 HTTP Access: Ports being opened
--access Allow: Grants access (instead of denying).
--protocol Tcp: Protocol type.
--direction Inbound: Applies to incoming traffic.

Cli
az network vnet subnet update*: Updates the configuration of an existing subnet.
*
--resource-group $RG
: Specifies the resource group where the subnet and NSG exist.
--vnet-name lab-vnet: Identifies the Virtual Network containing the subnet.
--name lab-subnet: The subnet being updated.
--network-security-group lab-nsg: - Associates the NSG (lab-nsg) with the subnet.

cli
az network public-ip create: The base command to create a public IP in Azure.
--resource-group $RG:- Specifies the resource group where the public IP will be created. $RG is a variable holding the resource group name.
--name lab-public-ip: Assigns the name lab-public-ip to the new public IP resource.
--allocation-method Static: Ensures the IP address is static, meaning it won’t change once assigned (as opposed to dynamic allocation).
--sku Standard: creates a more reliable, secure, and scalable public IP address. No zone redundancy, limited security features.

Step 4: Creating a VM, SSH into your VM & install Nginx
Creates a B1s Ubuntu VM with auto-generated SSH keys and connects it to the existing subnet and firewall.
cli
az vm create: Creates a new virtual machine.
--resource-group $RG: Deploys the VM into the resource group stored in the variable.
--name lab-vm:- Names the VM lab-vm.
--image Ubuntu2204: Uses the Ubuntu 22.04 LTS image.
--size Standard_B1s: Chooses a small, cost-effective VM size (1 vCPU, 1 GiB RAM).
--admin-username azureuser: Sets the admin account username.
--generate-ssh-keys: Automatically generates SSH keys if none exist locally.
--vnet-name lab-vnet: Places the VM in the virtual network lab-vnet.
--subnet lab-subnet: Assigns the VM to the subnet lab-subnet.
--public-ip-address lab-public-ip: Associates the VM with the public IP resource lab-public-ip.
--nsg lab-nsg:Attaches the network security group lab-nsg for traffic rules.
cli
az vm show: Displays information about an existing VM.
--resource-group $RG: Specifies the resource group where the VM resides.
--name lab-vm: Targets the VM named lab-vm.
--show-details: Includes additional details like networking and power state.
--query '{Name:name, State:powerState, IP:publicIps}': Uses JMESPath query syntax to filter and return only:The VM’s name, - The VM’s current power state (e.g., VM running, VM stopped), The public IP address assigned.
--output table: Formats the result into a human-readable table.
cli
ssh -i ~/.ssh/id_rsa azureuser@102.37.12.118: Connects securely to your VM using the private
sudo apt update && sudo apt install nginx -y: Refreshes the package index and installs Nginx web server automatically ( skips confirmation).
sudo systemctl enable nginx && sudo systemctl start nginx curl http://102.37.12.118: Ensures Nginx starts on boot. Immediately starts the Nginx service.

Step 5: Create a Storage Account, Upload Files, Store Secrets in Azure Key Vault
cli
STORAGE_NAME="labstorage$RANDOM": Creates a unique name by appending a random number to . Storage account names must be globally unique and lowercase.
az storage account create : Creates a new storage account.
--name $STORAGE_NAME : Uses the variable you defined above.
--resource-group $RG : Places the storage account in your resource
--location $LOCATION :Specifies the Azure region (e.g.,South Africa North).
--sku Standard_LRS : Chooses locally redundant storage (cost‑effective, three copies in one datacenter).
--kind StorageV2: Creates a modern general‑purpose v2 storage account (recommended for most workloads).

Create a Blob Container
cli
az storage container create : Creates a new blob container.
--name lab-files : Names the container lab-files.
--account-name $STORAGE_NAME : Uses the storage account you created earlier.
--auth-mode login: Authenticates using your Azure CLI login credentials (instead of needing an access key).

Upload a FIle
cli
echo 'Hello from Azure CLI Lab!' > sample.txt: Writes the string Hello from Azure CLI Lab! into a new file called in your current directory.
az storage blob upload : Uploads a file into an Azure Storage Blob container.
--account-name $STORAGE_NAME : Specifies the storage account you created earlier.
--container-name lab-files : Targets the blob container named lab-files.
--name sample.txt : Sets the blob’s name in Azure (what it will be called once uploaded).
--file sample.txt : Points to the local file you just created.
--auth-mode login: Uses your Azure CLI login credentials (Azure AD) for authentication instead of an account key.
NB: before you can upload a file, you need to assign role permission the user.

List blobs in the container
cli
az storage blob list : Lists blobs (files) stored in a container.
--account-name $STORAGE_NAME : Specifies the storage account.
--container-name lab-files : Targets the container named lab-files.
--auth-mode login : Uses your Azure AD login credentials for authentication.
--output table: Formats the output in a clean table view.

Create a Key Vault
cli
KV_NAME="lab-kv-$RANDOM": Creates a variable for the Key Vault name. The suffix ensures uniqueness since Key Vault names must be globally unique.
az keyvault create : Command to create a new Azure Key Vault resource.
--name $KV_NAME : Uses the variable you defined as the Key Vault’s name.
--resource-group $RG : Places the Key Vault inside the resource group you specify.
--location $LOCATION : pecifies the Azure region (e.g., , ) where the Key Vault will be created.
--enable-rbac-authorization false: Disables Role-Based Access Control (RBAC) authorization for this Key Vault. Instead, it will use the traditional Access Policies model to control who can access secrets, keys, and certificates.

Store a Secret
cli
az keyvault secret set : Command to create or update a secret in Azure Key Vault.
--vault-name $KV_NAME : Specifies which Key Vault to store the secret in (using the variable you defined earlier).
--name db-password : The logical name (identifier) for the secret. In this case, it’s called db-password.
--value 'SuperSecure@pass123':

Retrieve the secret
cli
az keyvault secret show : Retrieves details of a secret stored in Azure Key Vault.
--vault-name $KV_NAME : Specifies which Key Vault to query (using the variable you defined earlier).
--name db-password : Identifies the secret you want to fetch, in this case db-password.
--query value : Filters the output to return only the secret’s value (instead of the full JSON object).
--output tsv: Formats the result as plain text (tab‑separated values), which means you’ll just see the secret string itself without extra formatting.

Assign VM a Managed Identity to access the vault
cli
az vm identity assign :- Enables a system‑assigned managed identity for your VM.
--resource-group $RG \
--name lab-vm
PRINCIPAL_ID=$(az vm show \
--query identity.principalId \
--output tsv)
az role assignment create \
--role 'Key Vault Secrets User' \
--assignee $PRINCIPAL_ID \
--scope $(az keyvault show --name $KV_NAME --query id --output tsv).

Monitor Cost & Set a budget Alert
cli
az consumption budget create :
--name lab-budget :The budget’s name.
--amount 100 : Spending limit (in your subscription’s currency).
--category Cost : Tracks actual cost (instead of usage).
--time-grain Monthly :Resets every month.
--start-date $(date +%Y-%m-01) : Defines the active period for the budget.
--end-date 2026-12-31 :Defines the active period for the budget.
--resource-group $RG :Scope the budget to a specific resource group.

Conclusion
By following this step‑by‑step guide, you’ve seen how the Azure CLI can be used to provision a Linux virtual machine, configure networking with VNets and subnets, set up a storage account for file management, securely store sensitive information in Azure Key Vault, and establish cost monitoring through budget alerts. Together, these tasks demonstrate the power of Azure’s integrated services: infrastructure, security, and governance working seamlessly through command‑line automation.
The process not only equips you with practical skills for deploying and managing cloud resources but also highlights best practices—such as using managed identities for secure access and leveraging budgets to maintain financial control. With these foundations in place, you can confidently expand into more advanced scenarios, knowing that your environment is secure, scalable, and cost‑aware. This holistic approach ensures that your Azure deployments remain both technically robust and operationally sustainable.

Top comments (0)