This comprehensive guide will show you how to transition from a clean macOS terminal to a fully functioning Linux web server in Azure using the Azure CLI. By following these steps, you’ll implement a secure, segmented architecture aligned with cloud best practices.
🏗️ Introduction
Building in the cloud shouldn't require clicking through dozens of portal screens. Using the Azure CLI on your Mac allows for repeatable, scriptable, and professional infrastructure management. In this guide, we will follow the Azure Well-Architected Framework pillars—specifically Security and Operational Excellence—to deploy a virtualized environment.
Below is a Dev.to-style tutorial rewritten in original wording and structured as a step-by-step guide for macOS users. You can paste this directly into a Dev.to article editor.
How to Create Azure Infrastructure Using Azure CLI on macOS (Step-by-Step Guide)
Managing cloud infrastructure from the command line is one of the fastest and most repeatable ways to deploy resources in Microsoft Azure. Instead of manually clicking through the Azure Portal, you can automate the entire process with the Azure CLI.
In this guide, you'll learn how to:
- Install the Azure CLI on macOS
- Authenticate with your Azure account
- Create a Resource Group
- Build a Virtual Network and Subnet
- Configure a Network Security Group (NSG)
- Deploy an Ubuntu Virtual Machine
- Install Nginx and verify your web server
By the end, you'll have a working Linux VM running inside your own Azure network and accessible through the internet.
This approach also aligns with Azure Well-Architected Framework best practices, particularly Operational Excellence, by encouraging automation and repeatable infrastructure deployment.
1. Install Azure CLI on macOS
Before interacting with Azure resources from your terminal, you need the Azure Command Line Interface installed locally.
macOS users typically install software using Homebrew, a popular package manager.
Install Azure CLI
brew install azure-cli

This command downloads and installs the Azure CLI along with its dependencies.
Confirm Installation
az --version
If the installation succeeded, the terminal will display the CLI version and installed components.
Running the CLI locally allows you to interact directly with Azure APIs from your machine.
2. Authenticate With Your Azure Account
Next, you must sign in so Azure knows which account and subscription will own the resources you create.
Sign In
az login
Your default browser will open and prompt you to authenticate with your Azure account.
Once authenticated, your terminal session becomes authorized to execute Azure commands.
To confirm my active subscription, I entered 1 as this is my only active subscription.
Check Your Active Subscription
az account show

This command returns details about the currently selected Azure subscription.
Switch Subscription (Optional)
If you have multiple subscriptions:
az account set --subscription "Your Subscription Name"
This ensures all resources created during the lab are billed under the correct account.
From a security standpoint, authentication ensures only authorized users can create or modify cloud infrastructure.
3. Create a Resource Group
In Azure, every resource must exist inside a Resource Group, which acts as a logical container for related services.
Resource groups make it easier to:
- Manage permissions
- Monitor resources
- Delete entire environments at once
Define Variables
To make commands reusable and reduce typos, define variables for the resource group name and location.
RG="azurecli-lab-rg"
LOCATION="eastus"
Using variables allows you to reference the same values throughout your script.
Create the Resource Group
Creates a named resource group in East US. All resources in this lab will be placed here for easy cleanup.
Azure requires every resource to live inside a resource group. They make it easy to manage, monitor, and delete everything together at the end of the lab.
Operational Excellence — grouping related resources together is a best practice for manageability and cost tracking.
az group create --name $RG --location $LOCATION
This command provisions a new resource group in the East US region. Notice also the provisioning state is succeeded.
Verify Creation
You can also verify if it was created by running this command
az group show --name $RG
The output confirms the group exists and displays its configuration.
Organizing infrastructure into groups is a core Operational Excellence practice in Azure.
4. Create a Virtual Network
Most cloud resources require a private network so they can communicate securely.
Here, you will Creates a Virtual Network with a broad 10.0.0.0/16 IP address space.
This is needed VMs and other infrastructure need a secure, isolated private network to communicate with each other.
Security — creating an isolated network boundary is the foundational step of cloud security.
Azure provides this using a Virtual Network (VNet).
Create the VNet
az network vnet create \
--resource-group $RG \
--name lab-vnet \
--address-prefix 10.0.0.0/16 \
--location $LOCATION

This command builds a VNet with an address range of 10.0.0.0/16.
Think of the VNet as your private data center network inside Azure.
Creating isolated networks is an important security boundary in cloud architecture.
5. Create a Subnet
Subnets divide a larger network into smaller segments.
This allows you to separate different resource types and apply specific rules to them.
This Carves out a smaller 10.0.1.0/24 piece (subnet) of the VNet specifically for your VMs.
Segmenting networks allows you to apply different routing and firewall rules to different types of resources.
Create the Subnet
az network vnet subnet create \
--resource-group $RG \
--vnet-name lab-vnet \
--name lab-subnet \
--address-prefix 10.0.1.0/24
Here we allocate a smaller portion of the VNet specifically for our virtual machines.
Network segmentation improves both security and traffic management.
6. Create a Network Security Group
A Network Security Group (NSG) functions as a firewall for Azure resources.
It controls which traffic is allowed or denied.
Without an NSG attached, Microsoft allows no inbound traffic but allows all outbound traffic. We need an NSG to poke specific holes in the firewall.
Security — controlling traffic flow with firewalls is a basic security requirement.
Create the NSG
az network nsg create \
--resource-group $RG \
--name lab-nsg
The NSG will later be attached to the subnet so all resources inside inherit the same security rules.
7. Allow SSH and HTTP Traffic
Adds inbound rules prioritizing SSH (port 22) and HTTP (port 80) access from the internet.
You'll need SSH to log in and configure the server, and HTTP so users can view the web page.
Security — explicitly defining inbound access using the principle of least privilege.
By default, inbound traffic is restricted. We must explicitly allow access for:
- SSH (port 22) to manage the server
- HTTP (port 80) to serve web traffic
Allow SSH
az network nsg rule create \
--resource-group $RG \
--nsg-name lab-nsg \
--name AllowSSH \
--priority 1000 \
--destination-port-ranges 22 \
--access Allow \
--protocol Tcp \
--direction Inbound
Allow HTTP
az network nsg rule create \
--resource-group $RG \
--nsg-name lab-nsg \
--name AllowHTTP \
--priority 1010 \
--destination-port-ranges 80 \
--access Allow \
--protocol Tcp \
--direction Inbound

These rules define exactly which ports external users may access.
This follows the principle of least privilege, allowing only required traffic.
8. Attach the NSG to the Subnet
To enforce the firewall rules, attach the NSG to the subnet.
Applying the NSG to the subnet ensures that any VM created in that subnet automatically inherits those exact firewall rules — protecting the entire subnet.
Security — subnet-level application of security controls.
az network vnet subnet update \
--resource-group $RG \
--vnet-name lab-vnet \
--name lab-subnet \
--network-security-group lab-nsg
Applying security at the subnet level ensures every VM deployed in the subnet automatically inherits the rules.
9. Allocate a Public IP Address
For external users to reach your virtual machine, it needs a public IP address.
Allocates a static public IP address in Azure.
Without a public IP, the VM can only be accessed internally through the VNet or a VPN. You need this to reach your web server from your browser.
Reliability — using a Static IP ensures the address does not change upon reboot.
Create a Static Public IP
az network public-ip create \
--resource-group $RG \
--name lab-public-ip \
--allocation-method Static \
--sku standard
Using a static IP ensures the address remains the same even if the VM restarts.
Stable IP addresses improve reliability and connectivity.
10. Create the Linux Virtual Machine
Now it's time to deploy the compute instance that will host your application.
Creates a B1s Ubuntu VM with auto-generated SSH keys and connects it to the existing subnet and firewall.
This is the actual cloud compute instance that will run your web application code.
Performance Efficiency — selecting the appropriately sized VM for your workload (B1s for dev/test).
Provision the VM
az vm create \
--resource-group $RG \
--name lab-vm \
--image Ubuntu2204 \
--size Standard_B1s \
--admin-username azureuser \
--generate-ssh-keys \
--vnet-name lab-vnet \
--subnet lab-subnet \
--public-ip-address lab-public-ip \
--nsg lab-nsg
- Deploys an Ubuntu 22.04 server
- Uses a B1s VM size suitable for development/testing
- Generates SSH keys automatically
- Connects the VM to your VNet and firewall
Choosing appropriately sized instances is part of Performance Efficiency in cloud architecture.
11. Retrieve the VM's Public IP
You’ll need the IP address to connect to the server.
Filters the Azure API response to return just the IP address string.
You'll need this IP to SSH into the machine and to test the web application.
Operational Excellence — automated retrieval of resource attributes avoids manual portal lookups.
az network public-ip show \
--resource-group $RG \
--name lab-public-ip \
--query ipAddress \
--output tsv
The command outputs just the IP address for easy copying.
12. Confirm the VM is Running
Before connecting, verify the VM is successfully deployed.
Queries the VM status and displays it in a clean table format.
Always verify provisioning success before attempting connections.
Operational Excellence — verification and monitoring.
az vm show \
--resource-group $RG \
--name lab-vm \
--show-details \
--query '{Name:name, State:powerState, IP:publicIps}' \
--output table
This displays the VM name, power state, and public IP in a readable format.
Always validating infrastructure after provisioning is a key Operational Excellence practice.
13. Connect via SSH and Install Nginx
Now you can access the server remotely.
Log into the VM over the internet via SSH, installs the Nginx package using APT, and starts the service.
A fresh VM is blank. Nginx serves as the web server to test our HTTP port 80 firewall rule.
Operational Excellence — bootstrap scripts or userdata are typically used to automate this step.
Connect to the VM
ssh -i ~/.ssh/id_rsa azureuser@<YOUR_PUBLIC_IP>
Replace <YOUR_PUBLIC_IP> with the IP from the earlier step.
Install Nginx
Once logged in:
sudo apt update && sudo apt install nginx -y
Start and Enable the Web Server
sudo systemctl enable nginx && sudo systemctl start nginx

This installs and launches the Nginx web server.
14. Test the Web Server
From your local machine:
curl http://<YOUR_PUBLIC_IP>
If everything worked correctly, you'll receive the default Nginx HTML response.
You can also open the IP address in your browser to see the web page.
Conclusion
Congratulations! You have successfully used your Mac to orchestrate a professional Azure environment. You’ve installed the tooling, established a secure network boundary with NSG rules, and deployed a functional Ubuntu web server.
Using the Azure CLI is a powerful way to deploy and manage cloud infrastructure without relying on the Azure Portal.
In this guide, you learned how to:
- Install and configure the Azure CLI
- Authenticate to Azure from your Mac
-
Create foundational infrastructure including:
- Resource Groups
- Virtual Networks
- Subnets
- Network Security Groups
Deploy an Ubuntu Virtual Machine
Install and test a web server
This CLI-driven workflow is a key step toward Infrastructure as Code, automation, and scalable cloud operations.
Mastering the Azure CLI gives you full control over your cloud environment directly from your terminal.
I would love to hear from you.























Top comments (0)