Azure Fundamentals
Core Concepts
# Azure Core Concepts
Subscription: Root management unit for billing and resource management
Resource Group: Logical container for Azure resources
Region: Geographical location containing Azure datacenters
Availability Zone: Physically separate locations within an Azure region
Resource: Individual compute, storage, networking components
# Azure Management Scopes
Management Group → Subscription → Resource Group → Resource
Subscription: Root management unit for billing and resource management
Resource Group: Logical container for Azure resources
Region: Geographical location containing Azure datacenters
Availability Zone: Physically separate locations within an Azure region
Resource: Individual compute, storage, networking components
# Azure Management Scopes
Management Group → Subscription → Resource Group → Resource
Best Practice: Organize resources by lifecycle and ownership in resource groups for better management.
Azure CLI Basics
# Login to Azure
az login
# Set subscription context
az account set --subscription "My Subscription"
# Create a resource group
az group create --name MyResourceGroup --location eastus
# List all resource groups
az group list --output table
# Create a virtual machine
az vm create --resource-group MyResourceGroup \
--name MyVM --image UbuntuLTS --admin-username azureuser
# Get public IP of a VM
az vm list-ip-addresses --resource-group MyResourceGroup --name MyVM
az login
# Set subscription context
az account set --subscription "My Subscription"
# Create a resource group
az group create --name MyResourceGroup --location eastus
# List all resource groups
az group list --output table
# Create a virtual machine
az vm create --resource-group MyResourceGroup \
--name MyVM --image UbuntuLTS --admin-username azureuser
# Get public IP of a VM
az vm list-ip-addresses --resource-group MyResourceGroup --name MyVM
Compute Services
Virtual Machines
# VM Sizes (examples)
B-series: Burstable VMs for dev/test
D-series: General purpose compute
E-series: Optimized for in-memory databases
F-series: Compute optimized
N-series: GPU enabled
# Create a Windows VM
az vm create --resource-group MyRG \
--name MyWinVM --image Win2019Datacenter \
--admin-username azureuser --admin-password MyPassword123!
# Create a Linux VM with SSH
az vm create --resource-group MyRG --name MyLinuxVM \
--image UbuntuLTS --generate-ssh-keys
# Open port 80 for web traffic
az vm open-port --port 80 --resource-group MyRG --name MyVM
B-series: Burstable VMs for dev/test
D-series: General purpose compute
E-series: Optimized for in-memory databases
F-series: Compute optimized
N-series: GPU enabled
# Create a Windows VM
az vm create --resource-group MyRG \
--name MyWinVM --image Win2019Datacenter \
--admin-username azureuser --admin-password MyPassword123!
# Create a Linux VM with SSH
az vm create --resource-group MyRG --name MyLinuxVM \
--image UbuntuLTS --generate-ssh-keys
# Open port 80 for web traffic
az vm open-port --port 80 --resource-group MyRG --name MyVM
Tip: Use availability sets for VM fault tolerance and availability zones for higher resiliency.
App Services
# Create an App Service plan
az appservice plan create --name MyPlan \
--resource-group MyRG --sku B1 --is-linux
# Create a web app
az webapp create --name MyWebApp \
--resource-group MyRG --plan MyPlan \
--runtime "PYTHON|3.9"
# Deployment slots for staging
az webapp deployment slot create --name MyWebApp \
--resource-group MyRG --slot staging
# Deploy from GitHub
az webapp deployment source config --name MyWebApp \
--resource-group MyRG --repo-url https://github.com/user/repo \
--branch master --manual-integration
# Application settings
az webapp config appsettings set --name MyWebApp \
--resource-group MyRG --settings \
DB_HOST="mydbserver.database.windows.net"
az appservice plan create --name MyPlan \
--resource-group MyRG --sku B1 --is-linux
# Create a web app
az webapp create --name MyWebApp \
--resource-group MyRG --plan MyPlan \
--runtime "PYTHON|3.9"
# Deployment slots for staging
az webapp deployment slot create --name MyWebApp \
--resource-group MyRG --slot staging
# Deploy from GitHub
az webapp deployment source config --name MyWebApp \
--resource-group MyRG --repo-url https://github.com/user/repo \
--branch master --manual-integration
# Application settings
az webapp config appsettings set --name MyWebApp \
--resource-group MyRG --settings \
DB_HOST="mydbserver.database.windows.net"
Azure Functions
# Create a Function App
az functionapp create --name MyFunctionApp \
--resource-group MyRG --storage-account mystorageacc \
--consumption-plan-location westus --runtime python \
--functions-version 4
# Function triggers examples:
HTTP trigger: Web APIs, webhooks
Timer trigger: Scheduled tasks
Blob trigger: Process new storage blobs
Queue trigger: Process queue messages
Event Hub trigger: Process event streams
# Deploy function code
func azure functionapp publish MyFunctionApp
# List functions
az functionapp function list --name MyFunctionApp \
--resource-group MyRG
az functionapp create --name MyFunctionApp \
--resource-group MyRG --storage-account mystorageacc \
--consumption-plan-location westus --runtime python \
--functions-version 4
# Function triggers examples:
HTTP trigger: Web APIs, webhooks
Timer trigger: Scheduled tasks
Blob trigger: Process new storage blobs
Queue trigger: Process queue messages
Event Hub trigger: Process event streams
# Deploy function code
func azure functionapp publish MyFunctionApp
# List functions
az functionapp function list --name MyFunctionApp \
--resource-group MyRG
Containers
# Azure Container Instances (ACI)
az container create --resource-group MyRG --name mycontainer \
--image nginx --ports 80 --dns-name-label mydns \
--location eastus
# Azure Kubernetes Service (AKS)
# Create AKS cluster
az aks create --resource-group MyRG --name MyAKSCluster \
--node-count 3 --generate-ssh-keys
# Get credentials to connect to cluster
az aks get-credentials --resource-group MyRG --name MyAKSCluster
# Scale AKS cluster
az aks scale --resource-group MyRG --name MyAKSCluster \
--node-count 5
# Deploy application to AKS
kubectl apply -f my-deployment.yaml
az container create --resource-group MyRG --name mycontainer \
--image nginx --ports 80 --dns-name-label mydns \
--location eastus
# Azure Kubernetes Service (AKS)
# Create AKS cluster
az aks create --resource-group MyRG --name MyAKSCluster \
--node-count 3 --generate-ssh-keys
# Get credentials to connect to cluster
az aks get-credentials --resource-group MyRG --name MyAKSCluster
# Scale AKS cluster
az aks scale --resource-group MyRG --name MyAKSCluster \
--node-count 5
# Deploy application to AKS
kubectl apply -f my-deployment.yaml
Storage Services
Blob Storage
# Create storage account
az storage account create --name mystorageaccount \
--resource-group MyRG --location eastus \
--sku Standard_LRS --kind StorageV2
# Create container
az storage container create --name mycontainer \
--account-name mystorageaccount
# Upload blob
az storage blob upload --account-name mystorageaccount \
--container-name mycontainer --name myfile.txt \
--file ./local-file.txt --type block
# Generate SAS token (valid 1 hour)
az storage blob generate-sas --account-name mystorageaccount \
--container-name mycontainer --name myfile.txt \
--permissions r --expiry $(date -u -d "1 hour" '+%Y-%m-%dT%H:%MZ')
# Access tiers
Hot: Frequently accessed data
Cool: Infrequently accessed, 30-day min retention
Archive: Rarely accessed, 180-day min retention
az storage account create --name mystorageaccount \
--resource-group MyRG --location eastus \
--sku Standard_LRS --kind StorageV2
# Create container
az storage container create --name mycontainer \
--account-name mystorageaccount
# Upload blob
az storage blob upload --account-name mystorageaccount \
--container-name mycontainer --name myfile.txt \
--file ./local-file.txt --type block
# Generate SAS token (valid 1 hour)
az storage blob generate-sas --account-name mystorageaccount \
--container-name mycontainer --name myfile.txt \
--permissions r --expiry $(date -u -d "1 hour" '+%Y-%m-%dT%H:%MZ')
# Access tiers
Hot: Frequently accessed data
Cool: Infrequently accessed, 30-day min retention
Archive: Rarely accessed, 180-day min retention
Other Storage Options
# Azure Files (SMB shares)
az storage share create --name myshare \
--account-name mystorageaccount
# Azure Table Storage (NoSQL)
az storage table create --name mytable \
--account-name mystorageaccount
# Queue Storage
az storage queue create --name myqueue \
--account-name mystorageaccount
# Disk Storage (Managed Disks)
SKU types:
- Standard HDD: Economy, backup
- Standard SSD: Web servers, lightly used
- Premium SSD: Production, heavily used
- Ultra Disk: High throughput, low latency
# Create managed disk
az disk create --resource-group MyRG --name MyDisk \
--size-gb 1024 --sku Premium_LRS
az storage share create --name myshare \
--account-name mystorageaccount
# Azure Table Storage (NoSQL)
az storage table create --name mytable \
--account-name mystorageaccount
# Queue Storage
az storage queue create --name myqueue \
--account-name mystorageaccount
# Disk Storage (Managed Disks)
SKU types:
- Standard HDD: Economy, backup
- Standard SSD: Web servers, lightly used
- Premium SSD: Production, heavily used
- Ultra Disk: High throughput, low latency
# Create managed disk
az disk create --resource-group MyRG --name MyDisk \
--size-gb 1024 --sku Premium_LRS
Database Services
Azure SQL Database
# Create SQL Server
az sql server create --name mysqlserver \
--resource-group MyRG --location eastus \
--admin-user sqladmin --admin-password MyPassword123!
# Create SQL Database
az sql db create --resource-group MyRG \
--server mysqlserver --name mydatabase \
--service-objective S0 --max-size 250GB
# Service tiers:
DTU-based:
- Basic: Lightweight workloads
- Standard: Most common workloads
- Premium: High performance
vCore-based:
- General Purpose: Budget-oriented
- Business Critical: High availability
- Hyperscale: Scalable storage
# Allow Azure services to access
az sql server firewall-rule create --resource-group MyRG \
--server mysqlserver --name AllowAzureServices \
--start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
az sql server create --name mysqlserver \
--resource-group MyRG --location eastus \
--admin-user sqladmin --admin-password MyPassword123!
# Create SQL Database
az sql db create --resource-group MyRG \
--server mysqlserver --name mydatabase \
--service-objective S0 --max-size 250GB
# Service tiers:
DTU-based:
- Basic: Lightweight workloads
- Standard: Most common workloads
- Premium: High performance
vCore-based:
- General Purpose: Budget-oriented
- Business Critical: High availability
- Hyperscale: Scalable storage
# Allow Azure services to access
az sql server firewall-rule create --resource-group MyRG \
--server mysqlserver --name AllowAzureServices \
--start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
Azure Cosmos DB
# Create Cosmos DB account
az cosmosdb create --name mycosmosaccount \
--resource-group MyRG --locations regionName=eastus
# Create SQL API database
az cosmosdb sql database create --account-name mycosmosaccount \
--name myDatabase --resource-group MyRG
# Create container
az cosmosdb sql container create --account-name mycosmosaccount \
--database-name myDatabase --name myContainer \
--resource-group MyRG --partition-key-path "/myPartitionKey"
# Consistency levels:
Strong: Linearizability, highest consistency
Bounded staleness: Reads lag behind by k prefixes or t interval
Session: Monotonic reads, writes, read-your-writes
Consistent prefix: Updates returned in order
Eventual: No ordering guarantee for reads
az cosmosdb create --name mycosmosaccount \
--resource-group MyRG --locations regionName=eastus
# Create SQL API database
az cosmosdb sql database create --account-name mycosmosaccount \
--name myDatabase --resource-group MyRG
# Create container
az cosmosdb sql container create --account-name mycosmosaccount \
--database-name myDatabase --name myContainer \
--resource-group MyRG --partition-key-path "/myPartitionKey"
# Consistency levels:
Strong: Linearizability, highest consistency
Bounded staleness: Reads lag behind by k prefixes or t interval
Session: Monotonic reads, writes, read-your-writes
Consistent prefix: Updates returned in order
Eventual: No ordering guarantee for reads
Note: Cosmos DB supports multiple APIs: SQL, MongoDB, Cassandra, Gremlin, and Table.
Networking
Virtual Network
# Create virtual network
az network vnet create --resource-group MyRG \
--name MyVnet --address-prefix 10.0.0.0/16 \
--subnet-name MySubnet --subnet-prefix 10.0.0.0/24
# Create subnet
az network vnet subnet create --resource-group MyRG \
--vnet-name MyVnet --name MySubnet2 \
--address-prefixes 10.0.1.0/24
# Network security group (NSG)
az network nsg create --resource-group MyRG --name MyNSG
# NSG rule to allow SSH
az network nsg rule create --resource-group MyRG \
--nsg-name MyNSG --name AllowSSH --priority 1000 \
--protocol Tcp --direction Inbound --source-address-prefixes '*' \
--source-port-ranges '*' --destination-address-prefixes '*' \
--destination-port-ranges 22 --access Allow
# Associate NSG with subnet
az network vnet subnet update --resource-group MyRG \
--vnet-name MyVnet --name MySubnet --network-security-group MyNSG
az network vnet create --resource-group MyRG \
--name MyVnet --address-prefix 10.0.0.0/16 \
--subnet-name MySubnet --subnet-prefix 10.0.0.0/24
# Create subnet
az network vnet subnet create --resource-group MyRG \
--vnet-name MyVnet --name MySubnet2 \
--address-prefixes 10.0.1.0/24
# Network security group (NSG)
az network nsg create --resource-group MyRG --name MyNSG
# NSG rule to allow SSH
az network nsg rule create --resource-group MyRG \
--nsg-name MyNSG --name AllowSSH --priority 1000 \
--protocol Tcp --direction Inbound --source-address-prefixes '*' \
--source-port-ranges '*' --destination-address-prefixes '*' \
--destination-port-ranges 22 --access Allow
# Associate NSG with subnet
az network vnet subnet update --resource-group MyRG \
--vnet-name MyVnet --name MySubnet --network-security-group MyNSG
Load Balancing
# Azure Load Balancer
Public load balancer: Internet-facing traffic
Internal load balancer: Internal network traffic
# Create public load balancer
az network lb create --resource-group MyRG \
--name MyLB --sku Standard --public-ip-address MyPublicIP \
--frontend-ip-name MyFrontEnd --backend-pool-name MyBackendPool
# Application Gateway
Layer 7 load balancing: URL-based routing, SSL offloading
WAF integration: Web application firewall
# Create Application Gateway
az network application-gateway create --name MyAppGateway \
--resource-group MyRG --location eastus \
--vnet-name MyVnet --subnet MySubnet \
--capacity 2 --sku Standard_v2 \
--public-ip-address MyAGPublicIP
# Front Door (global load balancer)
Global HTTP load balancing: Anycast protocol
SSL offload: TLS termination at edge
WAF protection: DDoS protection
Public load balancer: Internet-facing traffic
Internal load balancer: Internal network traffic
# Create public load balancer
az network lb create --resource-group MyRG \
--name MyLB --sku Standard --public-ip-address MyPublicIP \
--frontend-ip-name MyFrontEnd --backend-pool-name MyBackendPool
# Application Gateway
Layer 7 load balancing: URL-based routing, SSL offloading
WAF integration: Web application firewall
# Create Application Gateway
az network application-gateway create --name MyAppGateway \
--resource-group MyRG --location eastus \
--vnet-name MyVnet --subnet MySubnet \
--capacity 2 --sku Standard_v2 \
--public-ip-address MyAGPublicIP
# Front Door (global load balancer)
Global HTTP load balancing: Anycast protocol
SSL offload: TLS termination at edge
WAF protection: DDoS protection
Security & Identity
Azure Active Directory
# Create AD user
az ad user create --display-name "John Doe" \
--password MyPassword123! --user-principal-name \
john.doe@mycompany.com --mail-nickname johndoe
# Create AD group
az ad group create --display-name "App Developers" \
--mail-nickname appdevs
# Add user to group
az ad group member add --group "App Developers" \
--member-id john.doe@mycompany.com
# Create service principal
az ad sp create-for-rbac --name MyServicePrincipal \
--role contributor --scopes /subscriptions/{sub-id}
# Managed Identity (system-assigned)
Automatically created: Tied to resource lifecycle
Azure AD only: Identity lives in Azure AD
# Enable system-assigned identity on VM
az vm identity assign --name MyVM --resource-group MyRG
az ad user create --display-name "John Doe" \
--password MyPassword123! --user-principal-name \
john.doe@mycompany.com --mail-nickname johndoe
# Create AD group
az ad group create --display-name "App Developers" \
--mail-nickname appdevs
# Add user to group
az ad group member add --group "App Developers" \
--member-id john.doe@mycompany.com
# Create service principal
az ad sp create-for-rbac --name MyServicePrincipal \
--role contributor --scopes /subscriptions/{sub-id}
# Managed Identity (system-assigned)
Automatically created: Tied to resource lifecycle
Azure AD only: Identity lives in Azure AD
# Enable system-assigned identity on VM
az vm identity assign --name MyVM --resource-group MyRG
Azure Key Vault
# Create Key Vault
az keyvault create --name MyKeyVault --resource-group MyRG \
--location eastus --sku standard
# Store secret
az keyvault secret set --vault-name MyKeyVault \
--name MySecret --value "TopSecretPassword123!"
# Retrieve secret
az keyvault secret show --vault-name MyKeyVault --name MySecret
# Create key
az keyvault key create --vault-name MyKeyVault \
--name MyKey --protection software
# Import certificate
az keyvault certificate import --vault-name MyKeyVault \
--name MyCert --file ./certificate.pfx
# Access policies
Grant permissions to user:
az keyvault set-policy --name MyKeyVault \
--user-principal-name john.doe@mycompany.com \
--secret-permissions get list
az keyvault create --name MyKeyVault --resource-group MyRG \
--location eastus --sku standard
# Store secret
az keyvault secret set --vault-name MyKeyVault \
--name MySecret --value "TopSecretPassword123!"
# Retrieve secret
az keyvault secret show --vault-name MyKeyVault --name MySecret
# Create key
az keyvault key create --vault-name MyKeyVault \
--name MyKey --protection software
# Import certificate
az keyvault certificate import --vault-name MyKeyVault \
--name MyCert --file ./certificate.pfx
# Access policies
Grant permissions to user:
az keyvault set-policy --name MyKeyVault \
--user-principal-name john.doe@mycompany.com \
--secret-permissions get list