Chapter 2: Getting Started with Azure
Creating Your Azure Account
- Go to https://azure.microsoft.com/free
- Sign in with a Microsoft account (or create one)
- Complete identity verification and enter a credit card (not charged, just to prevent abuse)
- You receive $200 in free credits for 30 days and access to always-free tier services
Always-Free Services (selected)
| Service | Free limit |
|---|---|
| Azure App Service | 10 web apps (F1 tier) |
| Azure Functions | 1 million executions/month |
| Blob Storage | 5 GB LRS |
| Azure SQL Database | 100,000 vCore seconds/month (serverless) |
| Cosmos DB | 1,000 RU/s + 25 GB |
| Azure Monitor | 5 GB log ingestion/month |
| Azure DevOps | 5 users, unlimited pipelines |
After the free trial ends, you are only charged for resources you explicitly use. Nothing auto-upgrades to paid without action.
The Azure Portal
The Azure Portal at portal.azure.com is a web-based UI for managing all Azure resources.
Key Portal Areas
Azure Portal Layout
├── Left sidebar
│ ├── Home - Dashboard with recent resources
│ ├── Dashboard - Customisable pinned tiles
│ ├── All services - Full catalogue of Azure services
│ ├── Favourites - Your starred services
│ └── Recent resources - Last visited resources
├── Top bar
│ ├── Search bar (/) - Search resources, services, docs
│ ├── Cloud Shell (>_) - Browser-based terminal
│ ├── Notifications (bell) - Deployment and alert history
│ └── Settings (gear) - Portal appearance, language
└── Main content area
└── Resource blades - Configuration panels for each resource
Portal Tips
- Press G + /, or just /, to focus the global search bar instantly
- Pin frequently-used resources to your Dashboard
- Use Cost Management + Billing to track spending
- Use Resource Graph Explorer to query all your resources with Kusto Query Language (KQL)
Azure CLI
The Azure CLI (az) is the primary command-line tool for managing Azure resources. It works on macOS, Linux, and Windows.
Installation
macOS:
brew install azure-cli
Ubuntu / Debian:
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
Windows (PowerShell):
winget install Microsoft.AzureCLI
Verify installation:
az version
# Output: {"azure-cli": "2.x.x", ...}
Authentication
# Interactive browser login
az login
# Login to a specific tenant (if you have multiple)
az login --tenant <tenant-id>
# Login with a service principal (CI/CD environments)
az login --service-principal \
--username <app-id> \
--password <client-secret> \
--tenant <tenant-id>
# Check who you are logged in as
az account show
# List all accessible subscriptions
az account list --output table
# Switch to a different subscription
az account set --subscription "<name-or-id>"
Output Formats
# JSON (default): best for scripting
az group list --output json
# Table: best for human reading
az group list --output table
# TSV: best for shell scripting (no headers)
az group list --output tsv
# YAML: useful for config file generation
az group list --output yaml
# Set a default output format
az configure --defaults output=table
Querying with JMESPath
The --query flag accepts JMESPath expressions to filter JSON output:
# Get only names of resource groups
az group list --query "[].name" --output tsv
# Get name and location of all VMs
az vm list --query "[].{Name:name, Location:location}" --output table
# Filter VMs in East US
az vm list --query "[?location=='eastus'].name" --output tsv
# Get the ID of a specific storage account
az storage account show \
--name mystorageaccount \
--resource-group myapp-rg \
--query id \
--output tsv
Setting Defaults
Avoid repeating --resource-group and --location in every command:
# Set default resource group and location
az configure --defaults group=myapp-dev-rg location=eastus
# Now these commands don't need --resource-group or --location
az vm list
az storage account list
# Clear defaults
az configure --defaults group='' location=''
Useful CLI Commands
# Find all available commands for a service
az vm --help
az storage blob --help
# Search for a command by keyword
az find "create virtual machine"
# List all resource types in a namespace
az provider show --namespace Microsoft.Compute --query "resourceTypes[].resourceType" -o table
# Show available VM sizes in a region
az vm list-sizes --location eastus --output table
# Interactive mode (autocomplete + docs inline)
az interactive
Azure PowerShell
If you prefer PowerShell (common in Windows/enterprise environments):
# Install the Az module
Install-Module -Name Az -Scope CurrentUser
# Login
Connect-AzAccount
# List resource groups
Get-AzResourceGroup | Format-Table
# Create a resource group
New-AzResourceGroup -Name "myapp-rg" -Location "EastUS"
For this tutorial, all examples use Azure CLI (
az). The concepts are identical in PowerShell; only the syntax differs.
Azure Cloud Shell
Cloud Shell is a browser-based terminal available directly in the portal (click the >_ icon in the top bar). It provides:
- Pre-installed Azure CLI, PowerShell, Terraform, kubectl, Helm, git, and more
- Automatic authentication (no
az loginneeded) - Persistent storage in an Azure Storage account (5 GB free)
- Both Bash and PowerShell environments
Cloud Shell is ideal for quick one-off tasks without installing anything locally.
Bicep & Infrastructure as Code
Azure Bicep is Microsoft's declarative language for deploying Azure resources. It compiles to ARM (Azure Resource Manager) templates.
// main.bicep: deploy a storage account
param storageAccountName string = 'mystorageacct${uniqueString(resourceGroup().id)}'
param location string = resourceGroup().location
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
}
}
output storageAccountId string = storageAccount.id
# Deploy a Bicep file to a resource group
az deployment group create \
--resource-group myapp-rg \
--template-file main.bicep
# Preview changes without deploying (what-if)
az deployment group what-if \
--resource-group myapp-rg \
--template-file main.bicep
Terraform is equally popular and cloud-agnostic. See the DevOps chapter for details.
Your First Deployment
Let's deploy a minimal web app to verify everything is working:
# 1. Create a resource group
az group create \
--name hello-azure-rg \
--location eastus
# 2. Create an App Service plan (free tier)
az appservice plan create \
--name hello-plan \
--resource-group hello-azure-rg \
--sku F1 \
--is-linux
# 3. Create a web app (Python runtime)
az webapp create \
--name hello-azure-$RANDOM \
--resource-group hello-azure-rg \
--plan hello-plan \
--runtime "PYTHON:3.11"
# 4. Deploy a simple HTML page via zip deploy
echo "<h1>Hello from Azure!</h1>" > index.html
zip app.zip index.html
az webapp deploy \
--resource-group hello-azure-rg \
--name <your-app-name> \
--src-path app.zip \
--type zip
# 5. Open the app in your browser
az webapp browse \
--resource-group hello-azure-rg \
--name <your-app-name>
# 6. Clean up everything
az group delete --name hello-azure-rg --yes --no-wait
Naming Conventions
Consistent naming avoids confusion across teams and subscriptions.
Recommended Pattern
{project}-{component}-{environment}-{region (optional)}-{instance (optional)}
| Resource | Example Name |
|---|---|
| Resource Group | myapp-prod-rg |
| Virtual Machine | myapp-web-vm-01 |
| Storage Account | myappprodst01 (no hyphens allowed, max 24 chars) |
| Key Vault | myapp-prod-kv |
| App Service | myapp-prod-api |
| AKS Cluster | myapp-prod-aks |
| VNet | myapp-prod-vnet |
| Subnet | myapp-prod-web-snet |
| NSG | myapp-prod-web-nsg |
Naming Constraints
| Resource | Max length | Allowed characters | Case sensitive |
|---|---|---|---|
| Resource Group | 90 | Letters, numbers, underscores, hyphens, periods | No |
| Storage Account | 3–24 | Lowercase letters and numbers only | No |
| Key Vault | 3–24 | Letters, numbers, hyphens | No |
| VM | 1–15 (Windows), 1–64 (Linux) | Letters, numbers, hyphens | No |
Next Steps
Continue to 03-compute.md to explore Azure's compute options: virtual machines, App Service, containers, and Kubernetes.