mirror of
https://github.com/BagelHole/DevOps-Security-Agent-Skills.git
synced 2026-08-22 12:49:53 +02:00
508 lines
13 KiB
Markdown
508 lines
13 KiB
Markdown
---
|
|
name: azure-vms
|
|
description: Manage Azure Virtual Machines and scale sets. Configure availability sets and managed disks. Use when deploying compute resources on Azure.
|
|
license: MIT
|
|
metadata:
|
|
author: devops-skills
|
|
version: "1.0"
|
|
---
|
|
|
|
# Azure Virtual Machines
|
|
|
|
Deploy and manage Azure VMs, availability sets, scale sets, custom images, and managed disks. Covers VM creation, sizing, disk management, auto-scaling, and Terraform configurations for production environments.
|
|
|
|
## When to Use
|
|
|
|
- You need full control over the operating system and runtime environment.
|
|
- Your application requires specific OS configurations or kernel modules.
|
|
- You are running legacy applications that cannot be containerized.
|
|
- You need GPU-accelerated compute for ML training or rendering.
|
|
- You need high-availability compute with availability zones or scale sets.
|
|
|
|
## Prerequisites
|
|
|
|
```bash
|
|
# Install Azure CLI
|
|
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
|
|
|
|
# Login and set subscription
|
|
az login
|
|
az account set --subscription "my-subscription-id"
|
|
|
|
# Create resource group
|
|
az group create --name compute-rg --location eastus
|
|
|
|
# List available VM sizes in a region
|
|
az vm list-sizes --location eastus --output table
|
|
|
|
# List available VM images
|
|
az vm image list --output table
|
|
az vm image list --publisher Canonical --offer 0001-com-ubuntu-server-jammy --all --output table
|
|
```
|
|
|
|
## VM Creation
|
|
|
|
### Linux VM with SSH Key
|
|
|
|
```bash
|
|
az vm create \
|
|
--resource-group compute-rg \
|
|
--name myapp-vm \
|
|
--image Ubuntu2204 \
|
|
--size Standard_D4s_v5 \
|
|
--admin-username azureuser \
|
|
--generate-ssh-keys \
|
|
--vnet-name myapp-vnet \
|
|
--subnet app-subnet \
|
|
--nsg "" \
|
|
--public-ip-address "" \
|
|
--os-disk-size-gb 64 \
|
|
--os-disk-caching ReadWrite \
|
|
--storage-sku Premium_LRS \
|
|
--zone 1 \
|
|
--assign-identity \
|
|
--tags environment=prod team=platform app=myapp
|
|
|
|
# SSH into the VM (if public IP assigned)
|
|
ssh azureuser@$(az vm show -g compute-rg -n myapp-vm -d --query publicIps -o tsv)
|
|
```
|
|
|
|
### Windows VM
|
|
|
|
```bash
|
|
az vm create \
|
|
--resource-group compute-rg \
|
|
--name myapp-win-vm \
|
|
--image Win2022Datacenter \
|
|
--size Standard_D4s_v5 \
|
|
--admin-username azureadmin \
|
|
--admin-password 'S3cur3P@ssw0rd!' \
|
|
--vnet-name myapp-vnet \
|
|
--subnet app-subnet \
|
|
--public-ip-address "" \
|
|
--os-disk-size-gb 128 \
|
|
--storage-sku Premium_LRS \
|
|
--zone 1
|
|
```
|
|
|
|
### VM with Cloud-Init
|
|
|
|
```bash
|
|
# cloud-init.yaml
|
|
# #cloud-config
|
|
# package_update: true
|
|
# packages:
|
|
# - nginx
|
|
# - docker.io
|
|
# runcmd:
|
|
# - systemctl enable nginx
|
|
# - systemctl start nginx
|
|
# - usermod -aG docker azureuser
|
|
|
|
az vm create \
|
|
--resource-group compute-rg \
|
|
--name web-vm \
|
|
--image Ubuntu2204 \
|
|
--size Standard_B2s \
|
|
--admin-username azureuser \
|
|
--generate-ssh-keys \
|
|
--custom-data cloud-init.yaml \
|
|
--tags role=web
|
|
```
|
|
|
|
## VM Size Guide
|
|
|
|
| Family | Example Sizes | Use Case |
|
|
|--------|---------------|----------|
|
|
| B-series | Standard_B1s, Standard_B2s | Dev/test, low-traffic web servers |
|
|
| D-series | Standard_D4s_v5, Standard_D8s_v5 | General purpose, most production workloads |
|
|
| E-series | Standard_E4s_v5, Standard_E16s_v5 | Memory-intensive (databases, caching) |
|
|
| F-series | Standard_F4s_v2, Standard_F16s_v2 | CPU-intensive (batch processing, analytics) |
|
|
| L-series | Standard_L8s_v3, Standard_L32s_v3 | Storage-optimized (big data, SQL) |
|
|
| N-series | Standard_NC6s_v3, Standard_NC24ads_A100_v4 | GPU workloads (ML training, rendering) |
|
|
| M-series | Standard_M128s | SAP HANA, large in-memory workloads |
|
|
|
|
```bash
|
|
# Find VM sizes with specific capabilities
|
|
az vm list-sizes --location eastus \
|
|
--query "[?numberOfCores >= \`4\` && memoryInMb >= \`16000\`]" \
|
|
--output table
|
|
|
|
# Check VM size availability in a zone
|
|
az vm list-skus --location eastus \
|
|
--size Standard_D4s_v5 \
|
|
--output table
|
|
```
|
|
|
|
## Managed Disks
|
|
|
|
```bash
|
|
# Add a data disk to existing VM
|
|
az vm disk attach \
|
|
--resource-group compute-rg \
|
|
--vm-name myapp-vm \
|
|
--name myapp-data-disk \
|
|
--size-gb 256 \
|
|
--sku Premium_LRS \
|
|
--new \
|
|
--lun 0
|
|
|
|
# Create a standalone managed disk
|
|
az disk create \
|
|
--resource-group compute-rg \
|
|
--name shared-data-disk \
|
|
--size-gb 512 \
|
|
--sku Premium_LRS \
|
|
--zone 1
|
|
|
|
# Resize a disk (VM must be deallocated)
|
|
az vm deallocate --resource-group compute-rg --name myapp-vm
|
|
az disk update \
|
|
--resource-group compute-rg \
|
|
--name myapp-data-disk \
|
|
--size-gb 512
|
|
az vm start --resource-group compute-rg --name myapp-vm
|
|
|
|
# Snapshot a disk for backup
|
|
az snapshot create \
|
|
--resource-group compute-rg \
|
|
--name myapp-disk-snapshot \
|
|
--source myapp-data-disk
|
|
|
|
# Create disk from snapshot
|
|
az disk create \
|
|
--resource-group compute-rg \
|
|
--name myapp-disk-from-snap \
|
|
--source myapp-disk-snapshot \
|
|
--sku Premium_LRS
|
|
|
|
# List disks attached to a VM
|
|
az vm show \
|
|
--resource-group compute-rg \
|
|
--name myapp-vm \
|
|
--query "storageProfile.dataDisks" \
|
|
--output table
|
|
```
|
|
|
|
## Custom Images
|
|
|
|
```bash
|
|
# Generalize the VM (run inside the VM first)
|
|
# sudo waagent -deprovision+user -force
|
|
|
|
# Deallocate and generalize
|
|
az vm deallocate --resource-group compute-rg --name myapp-vm
|
|
az vm generalize --resource-group compute-rg --name myapp-vm
|
|
|
|
# Create image from VM
|
|
az image create \
|
|
--resource-group compute-rg \
|
|
--name myapp-golden-image \
|
|
--source myapp-vm \
|
|
--os-type Linux
|
|
|
|
# Create VM from custom image
|
|
az vm create \
|
|
--resource-group compute-rg \
|
|
--name myapp-from-image \
|
|
--image myapp-golden-image \
|
|
--size Standard_D4s_v5 \
|
|
--admin-username azureuser \
|
|
--generate-ssh-keys
|
|
|
|
# Use Azure Compute Gallery for shared images
|
|
az sig create \
|
|
--resource-group compute-rg \
|
|
--gallery-name myAppGallery
|
|
|
|
az sig image-definition create \
|
|
--resource-group compute-rg \
|
|
--gallery-name myAppGallery \
|
|
--gallery-image-definition myapp-image \
|
|
--publisher myorg \
|
|
--offer myapp \
|
|
--sku 1.0 \
|
|
--os-type Linux \
|
|
--os-state Generalized
|
|
|
|
az sig image-version create \
|
|
--resource-group compute-rg \
|
|
--gallery-name myAppGallery \
|
|
--gallery-image-definition myapp-image \
|
|
--gallery-image-version 1.0.0 \
|
|
--managed-image myapp-golden-image \
|
|
--target-regions eastus westus \
|
|
--replica-count 2
|
|
```
|
|
|
|
## Availability Sets and Zones
|
|
|
|
```bash
|
|
# Create availability set
|
|
az vm availability-set create \
|
|
--resource-group compute-rg \
|
|
--name myapp-avset \
|
|
--platform-fault-domain-count 3 \
|
|
--platform-update-domain-count 5
|
|
|
|
# Create VM in availability set
|
|
az vm create \
|
|
--resource-group compute-rg \
|
|
--name myapp-vm-1 \
|
|
--image Ubuntu2204 \
|
|
--size Standard_D4s_v5 \
|
|
--availability-set myapp-avset \
|
|
--admin-username azureuser \
|
|
--generate-ssh-keys
|
|
|
|
# Create VMs across availability zones
|
|
for zone in 1 2 3; do
|
|
az vm create \
|
|
--resource-group compute-rg \
|
|
--name "myapp-vm-zone${zone}" \
|
|
--image Ubuntu2204 \
|
|
--size Standard_D4s_v5 \
|
|
--zone "$zone" \
|
|
--admin-username azureuser \
|
|
--generate-ssh-keys \
|
|
--no-wait
|
|
done
|
|
```
|
|
|
|
## Virtual Machine Scale Sets
|
|
|
|
```bash
|
|
# Create VMSS with autoscaling
|
|
az vmss create \
|
|
--resource-group compute-rg \
|
|
--name myapp-vmss \
|
|
--image Ubuntu2204 \
|
|
--vm-sku Standard_D4s_v5 \
|
|
--instance-count 2 \
|
|
--admin-username azureuser \
|
|
--generate-ssh-keys \
|
|
--vnet-name myapp-vnet \
|
|
--subnet app-subnet \
|
|
--upgrade-policy-mode Rolling \
|
|
--health-probe "/" \
|
|
--load-balancer myapp-lb \
|
|
--zones 1 2 3 \
|
|
--custom-data cloud-init.yaml \
|
|
--tags environment=prod
|
|
|
|
# Configure autoscale rules
|
|
az monitor autoscale create \
|
|
--resource-group compute-rg \
|
|
--resource myapp-vmss \
|
|
--resource-type Microsoft.Compute/virtualMachineScaleSets \
|
|
--name myapp-autoscale \
|
|
--min-count 2 \
|
|
--max-count 20 \
|
|
--count 3
|
|
|
|
# Scale out when CPU > 70%
|
|
az monitor autoscale rule create \
|
|
--resource-group compute-rg \
|
|
--autoscale-name myapp-autoscale \
|
|
--condition "Percentage CPU > 70 avg 5m" \
|
|
--scale out 2
|
|
|
|
# Scale in when CPU < 30%
|
|
az monitor autoscale rule create \
|
|
--resource-group compute-rg \
|
|
--autoscale-name myapp-autoscale \
|
|
--condition "Percentage CPU < 30 avg 10m" \
|
|
--scale in 1
|
|
|
|
# Manual scale
|
|
az vmss scale \
|
|
--resource-group compute-rg \
|
|
--name myapp-vmss \
|
|
--new-capacity 5
|
|
|
|
# Update VMSS image
|
|
az vmss update \
|
|
--resource-group compute-rg \
|
|
--name myapp-vmss \
|
|
--set virtualMachineProfile.storageProfile.imageReference.version=latest
|
|
|
|
# Rolling upgrade of instances
|
|
az vmss rolling-upgrade start \
|
|
--resource-group compute-rg \
|
|
--name myapp-vmss
|
|
|
|
# List VMSS instances
|
|
az vmss list-instances \
|
|
--resource-group compute-rg \
|
|
--name myapp-vmss \
|
|
--output table
|
|
```
|
|
|
|
## VM Management Operations
|
|
|
|
```bash
|
|
# Start / Stop / Restart / Deallocate
|
|
az vm start --resource-group compute-rg --name myapp-vm
|
|
az vm stop --resource-group compute-rg --name myapp-vm
|
|
az vm restart --resource-group compute-rg --name myapp-vm
|
|
az vm deallocate --resource-group compute-rg --name myapp-vm
|
|
|
|
# Run command on a VM
|
|
az vm run-command invoke \
|
|
--resource-group compute-rg \
|
|
--name myapp-vm \
|
|
--command-id RunShellScript \
|
|
--scripts "df -h && free -m && uptime"
|
|
|
|
# Enable boot diagnostics
|
|
az vm boot-diagnostics enable \
|
|
--resource-group compute-rg \
|
|
--name myapp-vm
|
|
|
|
# Get boot diagnostics log
|
|
az vm boot-diagnostics get-boot-log \
|
|
--resource-group compute-rg \
|
|
--name myapp-vm
|
|
|
|
# Enable Azure Backup
|
|
az backup protection enable-for-vm \
|
|
--resource-group compute-rg \
|
|
--vault-name myapp-vault \
|
|
--vm myapp-vm \
|
|
--policy-name DefaultPolicy
|
|
|
|
# Resize a VM
|
|
az vm resize \
|
|
--resource-group compute-rg \
|
|
--name myapp-vm \
|
|
--size Standard_D8s_v5
|
|
```
|
|
|
|
## Terraform Configuration
|
|
|
|
```hcl
|
|
resource "azurerm_linux_virtual_machine" "main" {
|
|
name = "myapp-vm"
|
|
resource_group_name = azurerm_resource_group.main.name
|
|
location = azurerm_resource_group.main.location
|
|
size = "Standard_D4s_v5"
|
|
admin_username = "azureuser"
|
|
zone = "1"
|
|
network_interface_ids = [azurerm_network_interface.main.id]
|
|
|
|
admin_ssh_key {
|
|
username = "azureuser"
|
|
public_key = file("~/.ssh/id_rsa.pub")
|
|
}
|
|
|
|
os_disk {
|
|
caching = "ReadWrite"
|
|
storage_account_type = "Premium_LRS"
|
|
disk_size_gb = 64
|
|
}
|
|
|
|
source_image_reference {
|
|
publisher = "Canonical"
|
|
offer = "0001-com-ubuntu-server-jammy"
|
|
sku = "22_04-lts-gen2"
|
|
version = "latest"
|
|
}
|
|
|
|
identity {
|
|
type = "SystemAssigned"
|
|
}
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
resource "azurerm_managed_disk" "data" {
|
|
name = "myapp-data-disk"
|
|
resource_group_name = azurerm_resource_group.main.name
|
|
location = azurerm_resource_group.main.location
|
|
storage_account_type = "Premium_LRS"
|
|
create_option = "Empty"
|
|
disk_size_gb = 256
|
|
zone = "1"
|
|
tags = var.tags
|
|
}
|
|
|
|
resource "azurerm_virtual_machine_data_disk_attachment" "data" {
|
|
managed_disk_id = azurerm_managed_disk.data.id
|
|
virtual_machine_id = azurerm_linux_virtual_machine.main.id
|
|
lun = 0
|
|
caching = "ReadOnly"
|
|
}
|
|
|
|
resource "azurerm_linux_virtual_machine_scale_set" "main" {
|
|
name = "myapp-vmss"
|
|
resource_group_name = azurerm_resource_group.main.name
|
|
location = azurerm_resource_group.main.location
|
|
sku = "Standard_D4s_v5"
|
|
instances = 3
|
|
admin_username = "azureuser"
|
|
zones = [1, 2, 3]
|
|
|
|
admin_ssh_key {
|
|
username = "azureuser"
|
|
public_key = file("~/.ssh/id_rsa.pub")
|
|
}
|
|
|
|
source_image_reference {
|
|
publisher = "Canonical"
|
|
offer = "0001-com-ubuntu-server-jammy"
|
|
sku = "22_04-lts-gen2"
|
|
version = "latest"
|
|
}
|
|
|
|
os_disk {
|
|
caching = "ReadWrite"
|
|
storage_account_type = "Premium_LRS"
|
|
}
|
|
|
|
network_interface {
|
|
name = "vmss-nic"
|
|
primary = true
|
|
|
|
ip_configuration {
|
|
name = "internal"
|
|
primary = true
|
|
subnet_id = azurerm_subnet.app.id
|
|
}
|
|
}
|
|
|
|
automatic_os_upgrade_policy {
|
|
disable_automatic_rollback = false
|
|
enable_automatic_os_upgrade = true
|
|
}
|
|
|
|
rolling_upgrade_policy {
|
|
max_batch_instance_percent = 20
|
|
max_unhealthy_instance_percent = 20
|
|
max_unhealthy_upgraded_instance_percent = 5
|
|
pause_time_between_batches = "PT0S"
|
|
}
|
|
|
|
tags = var.tags
|
|
}
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
| Symptom | Cause | Fix |
|
|
|---------|-------|-----|
|
|
| VM fails to start | Quota exceeded in region | Check quota with `az vm list-usage --location eastus`; request increase |
|
|
| SSH connection refused | NSG blocking port 22 or VM not running | Check NSG rules and VM power state; use Azure Bastion for private VMs |
|
|
| VM disk full | OS disk too small or logs not rotated | Resize disk after deallocating; configure log rotation |
|
|
| VM performance is slow | Wrong VM size or disk throttling | Check metrics with `az monitor metrics list`; upgrade size or disk tier |
|
|
| Scale set not scaling out | Autoscale rule threshold not met | Review autoscale settings; verify metric thresholds match workload |
|
|
| Custom image VM boot fails | Image not properly generalized | Re-run `waagent -deprovision` before capturing; check boot diagnostics |
|
|
| VMSS rolling upgrade stuck | Health probe failing on new instances | Fix application health endpoint; check `az vmss rolling-upgrade get-latest` |
|
|
| Spot VM evicted unexpectedly | Azure reclaimed capacity | Use eviction policy `Deallocate` and set up eviction notifications |
|
|
|
|
## Related Skills
|
|
|
|
- `azure-networking` -- VNet and NSG configuration for VM connectivity.
|
|
- `azure-aks` -- Container alternative when VMs are not required.
|
|
- `arm-templates` -- Bicep-based VM deployment templates.
|
|
- `terraform-azure` -- Terraform-based VM and VMSS provisioning.
|