This is Day 2 of my 90-day cloud engineering challenge. Day 1 was about installing tools and getting familiar with the Azure CLI. Day 2 was different — instead of just running commands to learn syntax, I gave myself a real-world scenario and worked through it the way an actual DevOps engineer would on the job.
The Scenario
To push myself past "tutorial mode," I simulated a message from a team lead:
"Taiwo, we need a new environment for the payments project. Create a resource group for dev, one for staging. Tag them properly. Create a storage account in dev. List everything and send me a clean output. Then document it."
No step-by-step instructions. No exact commands handed to me — just a goal. That's closer to how real work actually shows up: as an outcome someone needs, not a tutorial to follow. My job was to translate that into the right CLI commands, tag things properly, and produce a clean, professional result.
Commands I Used
Listing and inspecting resource groups
az group list
az group list --output table
az group list --output tsv
az group list --output jsonc
I started by getting comfortable with different output formats. In a real environment with dozens or hundreds of resources, raw JSON is hard to scan quickly — table and tsv make it much easier to read at a glance or pipe into other tools/scripts.
Filtering with --query
az group list --query "[].{Name:name, Location:location}" --output table
az group list --query "[?location=='eastus'].name" --output table
az account show --query "name" --output tsv
This is where things started feeling like real engineering rather than just running commands. --query lets you filter and reshape the JSON output before it even hits your screen — instead of scrolling through everything, you ask for exactly what you need. When you're dealing with 200+ resources, this isn't optional; it's how you stay sane.
Tagging resources properly
az group update \
--name taiwo-devops-rg \
--tags Environment=Dev Owner=Taiwo Project=AzureCLILab
az group show \
--name taiwo-devops-rg \
--query "tags" \
--output table
Tags seem like a small detail until you realize how much they matter in a real company. Tags answer three questions instantly, for any resource, at any scale:
- Who owns it?
- What project does it belong to?
- What environment is it — dev, staging, or production?
Without consistent tagging, a subscription with hundreds of resources becomes nearly impossible to manage, audit, or clean up safely.
The Automation Script
Rather than running each command by hand every time I needed an environment, I wrote a Bash script to provision the entire setup — dev resource group, staging resource group, and a storage account — in one run:
#!/bin/bash
# ============================================
# Azure Environment Provisioner
# Author: Taiwo
# Description: Provisions dev environment
# for any project automatically
# ============================================
# Variables — change these for any project
PROJECT="payments"
OWNER="Taiwo"
LOCATION="eastus"
STORAGE_NAME="taiwo${PROJECT}dev001"
echo "🚀 Starting provisioning for project: $PROJECT"
# Step 1: Create Dev Resource Group
echo "📁 Creating Dev Resource Group..."
az group create \
--name "${PROJECT}-dev-rg" \
--location "$LOCATION" \
--tags Environment=Dev Owner=$OWNER Project=$PROJECT
# Step 2: Create Staging Resource Group
echo "📁 Creating Staging Resource Group..."
az group create \
--name "${PROJECT}-staging-rg" \
--location "$LOCATION" \
--tags Environment=Staging Owner=$OWNER Project=$PROJECT
# Step 3: Create Storage Account
echo "💾 Creating Storage Account..."
az storage account create \
--name "$STORAGE_NAME" \
--resource-group "${PROJECT}-dev-rg" \
--location "$LOCATION" \
--sku Standard_LRS \
--kind StorageV2 \
--tags Environment=Dev Owner=$OWNER Project=$PROJECT
# Step 4: Confirm everything
echo "✅ Provisioning complete. Here is your environment:"
az group list --output table
echo "🎉 Done! Project $PROJECT environment is ready."
The script takes a few simple variables — project name, owner, and location — and provisions a complete environment from scratch, consistently, every single time. Change the PROJECT variable and the same script provisions an environment for a completely different project. That's the difference between "I ran some commands" and "I built something reusable."
Bonus: A Git Workflow Script
Outside of the Azure work itself, I also wrote a small Bash script to speed up my Git workflow — staging, committing, and pushing in a single command instead of typing three separate ones every time:
#!/bin/bash
# Exit if any command fails
set -e
trap 'echo "❌ A command failed. Exiting..."' ERR
echo "Current branch: $(git branch --show-current)"
# Stage all changes
git add .
# Prompt for commit message
while true; do
read -p "Enter a commit message: " commitMessage
if [ -n "$commitMessage" ]; then
break
fi
echo "Commit message cannot be empty."
done
# Commit and push
git commit -m "$commitMessage"
git push
echo "✅ Changes committed and pushed successfully."
Small touches here matter: set -e and the trap ensure the script stops cleanly the moment something fails instead of plowing ahead, and the commit-message prompt won't let me accidentally push with an empty message. It's a small script, but it's the kind of "make my own workflow faster" thinking that DevOps is built on.
What This Taught Me About Real DevOps Work
Today reframed how I think about the CLI. It's not just a faster way to click buttons — it's a tool for repeatability, filtering, and automation at a scale where doing things manually simply breaks down.
In a real company, this is what the day-to-day actually looks like:
- Spinning up a storage account for a dev team on request
- Checking what resources are currently running in production
- Cleaning up a test environment left over from last sprint
- Standing up a new resource group for a new project
- Filtering out the handful of failed resources from a list of 200+
- Wrapping repeatable tasks into scripts instead of typing them out every time
None of that works well through a portal UI when you're dealing with real scale. It works through commands, queries, tags, and scripts — exactly what I practiced today.
Problems I Faced
The biggest challenge wasn't syntax — it was genuinely understanding why each piece mattered (tagging, querying, scripting) rather than just copying commands. Once I slowed down and researched the reasoning behind each one, things started clicking. I'd rather understand the "why" once than memorize the "what" repeatedly.
What Clicked Today
- Provisioned a full dev + staging environment from a single scenario, not a tutorial
- Created a Storage Account via CLI inside the correct resource group
- Used
--queryto filter and reshape output like an engineer working at scale - Wrote a reusable Bash automation script for environment provisioning
- Wrote a separate Git workflow script to speed up my own commit/push process
What's Next
Day 1 was about learning the tool. Day 2 was about using it to solve a problem someone else gave me. That shift — from "following steps" to "interpreting a request and deciding the steps myself" — is the part I want to keep practicing for the rest of these 90 days.
Following along with a 90-day hands-on cloud engineering challenge. Catch up on Day 1 here.
Top comments (0)