DEV Community

Cover image for Building a Production-Style Azure Infrastructure with Azure CLI: Lessons from a Real Deployment
Rahimah Sulayman
Rahimah Sulayman

Posted on

Building a Production-Style Azure Infrastructure with Azure CLI: Lessons from a Real Deployment

How I deployed Linux and Windows virtual machines, configured networking, secured public access, and troubleshot real Azure deployment issues using only Azure CLI.


Introduction

One of the best ways to learn cloud engineering is to build infrastructure the same way it is deployed in real environments.

Instead of clicking through the Azure Portal, I challenged myself to provision an entire production-style environment using Azure CLI. The objective wasn't simply to deploy virtual machines: it was to understand the deployment process, solve real-world problems, validate every resource, and document the entire journey.

The final environment included:

  • Ubuntu Server running Nginx
  • Windows Server running IIS
  • Windows 11 client VM
  • Shared Virtual Network
  • Network Security Groups
  • Public connectivity validation
  • Complete cleanup after deployment

More importantly, the project involved several real Azure deployment challenges that required investigation and troubleshooting before the infrastructure was fully operational.


Project Objectives

The goals of this lab were to:

  • Provision Azure infrastructure entirely with Azure CLI
  • Deploy Linux and Windows virtual machines
  • Configure virtual networking
  • Deploy a Windows 11 client VM
  • Install and configure Nginx
  • Install and configure IIS
  • Configure Network Security Groups
  • Validate public connectivity
  • Practice troubleshooting real Azure deployment issues
  • Document the entire implementation

Architecture

The deployed environment consisted of:

  • Azure Resource Group
  • Virtual Network
  • Shared Subnet
  • Ubuntu Server VM
  • Windows Server VM
  • Windows 11 Client VM
  • Network Security Groups
  • Nginx Web Server
  • IIS Web Server

Although this is a learning project, the overall deployment closely resembles the structure used in many production Azure environments.


Infrastructure Deployed

Resource Name
Resource Group rg-globalretail-prod-001
Region West Europe
Ubuntu VM vm-linux-web-01
Windows Server VM vm-win-admin01
Windows 11 VM vm-win11-ha
Virtual Network vm-linux-web-01VNET
Subnet vm-linux-web-01Subnet

Deployment Process

Step 1 — Creating the Resource Group

Everything began by creating a dedicated Resource Group to logically organize every Azure resource used throughout the project.

This became the container for all virtual machines, networking resources, storage, and security components.

Resource Group Created

rg


Step 2 — Deploying the Ubuntu Server

The first virtual machine deployed was an Ubuntu Server running Ubuntu 22.04 LTS.

This server would later host the Nginx web server.

Deployment was completed using Azure CLI without touching the Azure Portal.

Linux VM Created

linux vm


Step 3 — Deploying Windows Server

Next came the Windows Server virtual machine.

This VM would later host Internet Information Services (IIS).

The deployment wasn't completely smooth, however...


Real-World Troubleshooting

One thing I appreciated about this project was that it wasn't a perfect "follow-the-lab" experience.

Several real deployment issues occurred along the way.

Windows Computer Name Limitation

The initial deployment failed because the Windows computer name exceeded Microsoft's 15-character limit.

After shortening the VM name, deployment continued successfully.


Azure CLI Returned ResourceNotFound

Immediately after deployment, Azure CLI displayed a ResourceNotFound error for the Windows VM.

Instead of assuming the deployment had failed, I verified the environment using:

az vm list --resource-group rg-globalretail-prod-001 --output table
Enter fullscreen mode Exit fullscreen mode

The VM had actually been created successfully.

This reinforced an important lesson:

Always verify the actual Azure resource state instead of relying solely on CLI output.


Windows 11 Deployment Failed

The Windows 11 deployment initially failed because Azure attempted to create a subnet that conflicted with the existing virtual network.

The solution was to query the existing subnet and explicitly specify it during deployment.


SSH Authentication Failed

Connecting to Ubuntu initially produced:

Permission denied (publickey)
Enter fullscreen mode Exit fullscreen mode

After investigating, I discovered the local machine did not contain an SSH key pair.

Generating a new RSA key pair resolved the issue immediately.


Configuring the Servers

With the infrastructure successfully deployed, the next phase involved configuring the workloads.

Ubuntu

After connecting through SSH:

  • Updated package repositories
  • Installed Nginx
  • Verified the service was running
sudo apt update
sudo apt install nginx -y
sudo systemctl status nginx
Enter fullscreen mode Exit fullscreen mode

Windows Server

After connecting through Remote Desktop:

  • Opened PowerShell
  • Installed IIS
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
Enter fullscreen mode Exit fullscreen mode

Network Security

Neither web server was initially reachable.

The reason?

HTTP traffic wasn't allowed through the Network Security Groups.

After creating inbound TCP port 80 rules for both virtual machines, browser access worked immediately.

This served as a good reminder that:

Infrastructure deployment is only one part of cloud engineering.

Networking and security configuration are equally important.


Validation

The environment was validated by confirming that:

  • SSH access worked correctly
  • Remote Desktop access worked correctly
  • Nginx was running
  • IIS was installed successfully
  • HTTP traffic was permitted
  • Both web servers were accessible from a web browser

Browser showing Nginx or IIS page
nginx

iis


What I Learned

This project reinforced several important Azure concepts:

  • Azure regions don't always have capacity for every VM size.
  • Windows virtual machines have naming constraints.
  • Existing VNets and subnets should be reused explicitly.
  • SSH authentication requires both server-side and client-side configuration.
  • Azure CLI responses should always be validated.
  • Network Security Groups are critical for application accessibility.
  • Cleaning up cloud resources prevents unnecessary costs.

Most importantly...

Cloud engineering isn't simply deploying resources.

It's understanding how infrastructure, networking, security, authentication, and troubleshooting all work together.


Source Code

The complete project — including Azure CLI commands, deployment documentation, troubleshooting notes, and screenshots is available on GitHub:

👉 https://github.com/rahimahisah17/globalretail-prod-lab


Final Thoughts

This project pushed me beyond simply following documentation.

It required investigating deployment failures, validating Azure resources, solving networking issues, configuring Linux and Windows servers, and documenting every stage of the deployment process.

Every challenge became an opportunity to better understand how Azure behaves in real-world scenarios.

I'm looking forward to building even more production - style cloud infrastructure projects as I continue developing my Azure and cloud engineering skills.


Thanks for reading! If you have suggestions, questions, or similar experiences deploying infrastructure with Azure CLI, I'd love to hear about them.

azure #azurecli #cloud #cloudcomputing #devops #linux #windowsserver #nginx #iis #networking #cloudengineering

Top comments (2)

Collapse
 
rahimah_dev profile image
Rahimah Sulayman

One of the biggest lessons from this project was learning not to trust the first error message at face value. For example, Azure CLI returned a ResourceNotFound error even though the VM had already been created successfully. Verifying the actual resource state before troubleshooting further saved a lot of unnecessary work. Have you ever run into a similar situation with Azure or another cloud platform?

Collapse
 
rahimah_dev profile image
Rahimah Sulayman

Building the infrastructure was only part of the journey. The real learning came from troubleshooting VM naming constraints, SSH authentication, subnet configuration, and Network Security Group rules. Those challenges made the project far more valuable than if everything had worked perfectly the first time. What's the most memorable deployment issue you've had to solve?