DEV Community

Cover image for From Terminal to Cloud: A Mac User's Guide to Deploying Linux on Azure cli
Louis Oodo
Louis Oodo

Posted on

From Terminal to Cloud: A Mac User's Guide to Deploying Linux on Azure cli

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
Enter fullscreen mode Exit fullscreen mode

brew install azure-cli
This command downloads and installs the Azure CLI along with its dependencies.

Confirm Installation

az --version
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

az login

Your default browser will open and prompt you to authenticate with your Azure account.

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.

confirm my active subscription

Check Your Active Subscription

az account show
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Create the VNet
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
Enter fullscreen mode Exit fullscreen mode

Create the Subnet

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
Enter fullscreen mode Exit fullscreen mode

Create the 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

az network nsg rule create


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
Enter fullscreen mode Exit fullscreen mode

az network vnet subnet update

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
Enter fullscreen mode Exit fullscreen mode

Static Public IP

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
Enter fullscreen mode Exit fullscreen mode

az vm create
This command:

  • 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
Enter fullscreen mode Exit fullscreen mode

az network public-ip show

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
Enter fullscreen mode Exit fullscreen mode

az vm show

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>
Enter fullscreen mode Exit fullscreen mode

Replace <YOUR_PUBLIC_IP> with the IP from the earlier step.

YOUR_PUBLIC_IP

Install Nginx

Once logged in:

sudo apt update && sudo apt install nginx -y
Enter fullscreen mode Exit fullscreen mode

sudo apt update && sudo apt install nginx -y

sudo apt update && sudo apt install nginx -y

upgraded binary

Start and Enable the Web Server

sudo systemctl enable nginx && sudo systemctl start nginx
Enter fullscreen mode Exit fullscreen mode

Start and Enable the Web Server
This installs and launches the Nginx web server.


14. Test the Web Server

From your local machine:

curl http://<YOUR_PUBLIC_IP>
Enter fullscreen mode Exit fullscreen mode

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)