Skip to content

Azure DevOps Interview Questions

Azure DevOps Interview Questions & Answers (1–50)

Section titled “Azure DevOps Interview Questions & Answers (1–50)”

Q1: What is Azure DevOps and what are its main services?

Section titled “Q1: What is Azure DevOps and what are its main services?”

Answer: Azure DevOps is Microsoft’s end-to-end software development platform covering planning, building, testing, and deploying applications.

Azure DevOps ServicePurposeAWS Equivalent
Azure BoardsWork items, sprints, Kanban, epicsJira / GitHub Issues
Azure ReposGit repositories (private, unlimited)CodeCommit / GitHub
Azure PipelinesCI/CD for any language/platform/cloudCodePipeline + CodeBuild
Azure ArtifactsPackage management (npm, Maven, NuGet, PyPI)CodeArtifact
Azure Test PlansManual + automated test management(no direct equivalent)

Key advantage: Azure Pipelines works with ANY cloud (AWS, GCP, Azure) and ANY git host (GitHub, GitLab, Bitbucket) — not just Azure.

Terminal window
# Access via CLI
npm install -g azure-devops-extension
az devops configure --defaults organization=https://dev.azure.com/myorg project=myproject
# List projects
az devops project list
# List pipelines
az pipelines list
# Trigger a pipeline
az pipelines run --name myPipeline --branch main

Interview tip: “Azure DevOps is modular — you can use just Pipelines with GitHub repos, or just Boards without Pipelines. Many companies use Azure Pipelines with GitHub repos for the best of both.”


Q2: What are Azure Pipelines and how do you create a CI pipeline?

Section titled “Q2: What are Azure Pipelines and how do you create a CI pipeline?”

Answer: Azure Pipelines is a CI/CD service supporting any language, platform, and cloud.

azure-pipelines.yml
trigger:
branches:
include:
- main
- develop
paths:
exclude:
- docs/**
- '**/*.md'
pr:
branches:
include:
- main
variables:
imageRepository: 'myapp'
containerRegistry: 'myregistry.azurecr.io'
dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile'
tag: '$(Build.BuildId)'
stages:
- stage: Test
displayName: 'Test Stage'
jobs:
- job: UnitTest
displayName: 'Run Unit Tests'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '18.x'
displayName: 'Install Node.js'
- script: |
npm ci
npm test -- --coverage
displayName: 'Install and Test'
- task: PublishTestResults@2
condition: always()
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: 'test-results/*.xml'
- task: PublishCodeCoverageResults@1
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: 'coverage/cobertura-coverage.xml'
- stage: Build
displayName: 'Build & Push Image'
dependsOn: Test
condition: succeeded()
jobs:
- job: BuildPush
pool:
vmImage: 'ubuntu-latest'
steps:
- task: Docker@2
displayName: 'Build and Push Docker Image'
inputs:
command: buildAndPush
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: 'ACR-Service-Connection'
tags: |
$(tag)
latest
- stage: DeployStaging
displayName: 'Deploy to Staging'
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop'))
jobs:
- deployment: DeployToStaging
environment: 'staging'
strategy:
runOnce:
deploy:
steps:
- task: KubernetesManifest@0
inputs:
action: 'deploy'
namespace: 'staging'
manifests: 'k8s/*.yaml'
containers: '$(containerRegistry)/$(imageRepository):$(tag)'
- stage: DeployProduction
displayName: 'Deploy to Production'
dependsOn: DeployStaging
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: DeployToProduction
environment: 'production' # Requires approval gate
strategy:
canary:
increments: [10, 50, 100]
deploy:
steps:
- task: KubernetesManifest@0
inputs:
action: 'deploy'
namespace: 'production'
manifests: 'k8s/*.yaml'
containers: '$(containerRegistry)/$(imageRepository):$(tag)'

Q3: How do you use Azure Pipelines templates?

Section titled “Q3: How do you use Azure Pipelines templates?”

Answer: Templates allow you to reuse pipeline logic — define once, use across many pipelines. Essential for DRY pipelines in large organizations.

Types of templates:

1. Step templates ← reuse a set of steps
2. Job templates ← reuse a whole job
3. Stage templates ← reuse a whole stage
4. Variable templates ← reuse variable sets
# templates/build-node.yml (reusable template)
parameters:
- name: nodeVersion
type: string
default: '18.x'
- name: runTests
type: boolean
default: true
- name: buildCommand
type: string
default: 'npm run build'
steps:
- task: NodeTool@0
inputs:
versionSpec: ${{ parameters.nodeVersion }}
displayName: 'Install Node.js ${{ parameters.nodeVersion }}'
- script: npm ci
displayName: 'Install dependencies'
- ${{ if parameters.runTests }}:
- script: npm test -- --coverage
displayName: 'Run tests with coverage'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '**/test-results.xml'
- script: ${{ parameters.buildCommand }}
displayName: 'Build'
# azure-pipelines.yml (pipeline using template)
trigger:
branches:
include: [main, develop]
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: BuildBackend
jobs:
- job: BuildAPI
steps:
- template: templates/build-node.yml # Use the template!
parameters:
nodeVersion: '20.x'
runTests: true
buildCommand: 'npm run build:prod'
- stage: BuildFrontend
jobs:
- job: BuildUI
steps:
- template: templates/build-node.yml # Same template, different params
parameters:
nodeVersion: '18.x'
runTests: false
buildCommand: 'npm run build:frontend'

Reference templates from other repos:

# Reference templates from a shared "pipeline-templates" repo
resources:
repositories:
- repository: templates
type: git
name: MyProject/pipeline-templates
ref: refs/heads/main
stages:
- template: deploy/aks-deploy.yml@templates # From other repo!
parameters:
environment: production

Interview tip: In large orgs, store templates in a dedicated pipeline-templates repository. Teams import these to ensure consistent build/deploy standards across 100+ pipelines without duplication.


Q4: How do you set up variable groups and secrets in Azure Pipelines?

Section titled “Q4: How do you set up variable groups and secrets in Azure Pipelines?”

Answer: Variable groups let you share variables/secrets across multiple pipelines without duplicating them.

Variable types in Azure Pipelines:

1. Pipeline variables ← defined in yaml or UI, per-pipeline
2. Variable groups ← shared across pipelines (link Key Vault)
3. Secret variables ← masked in logs, not passed to fork PRs
4. System variables ← built-in: Build.BuildId, System.TeamProject
5. Runtime parameters ← user-prompted when triggered manually
Terminal window
# Create variable group via CLI
az pipelines variable-group create \
--name production-vars \
--variables \
DB_HOST=db.example.com \
APP_PORT=3000 \
APP_VERSION=1.5.0
# Add secret variable (value hidden in logs)
az pipelines variable-group variable create \
--group-id 1 \
--name DB_PASSWORD \
--value "supersecret" \
--secret true
# Link to Azure Key Vault (auto-sync secrets from KV)
az pipelines variable-group create \
--name KeyVault-Secrets \
--authorize true \
--provider-name AzureKeyVault \
--provider-data '{
"vaultName": "my-keyvault",
"serviceEndpointId": "service-connection-id"
}'
# Use variable group in pipeline
variables:
- group: production-vars # All vars from group available
- group: KeyVault-Secrets # Auto-sync from Key Vault!
- name: buildConfiguration
value: Release
- name: imageTag
value: '$(Build.BuildId)' # Use system variable
steps:
# Variables available as environment variables
- script: echo $(DB_HOST) && echo $(APP_VERSION)
displayName: 'Show variables'
# Secrets: available but masked in logs
- script: |
echo "Connecting to database..."
./connect-db.sh # Uses DB_PASSWORD from env
env:
DB_PASSWORD: $(DB_PASSWORD) # Explicitly pass secrets to scripts
displayName: 'Connect to DB'
# Runtime parameter (user fills in when manually triggering)
parameters:
- name: environment
displayName: Target Environment
type: string
default: staging
values:
- staging
- production
stages:
- stage: Deploy
displayName: 'Deploy to ${{ parameters.environment }}'
jobs:
- deployment: Deploy
environment: ${{ parameters.environment }}

Common mistake: Secrets are NOT automatically passed to scripts as environment variables — you must explicitly map them with env: MYVAR: $(mySecret). Otherwise the script sees an empty string, not the secret value.


Q5: How do you create and manage an AKS cluster?

Section titled “Q5: How do you create and manage an AKS cluster?”

Answer:

Terminal window
# Create AKS cluster
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--node-count 3 \
--node-vm-size Standard_D4s_v3 \
--enable-addons monitoring \
--enable-managed-identity \
--network-plugin azure \
--network-policy calico \
--generate-ssh-keys
# Get credentials
az aks get-credentials \
--resource-group myResourceGroup \
--name myAKSCluster
# View nodes
kubectl get nodes
# Scale node pool
az aks scale \
--resource-group myResourceGroup \
--name myAKSCluster \
--node-count 5
# Enable cluster autoscaler
az aks update \
--resource-group myResourceGroup \
--name myAKSCluster \
--enable-cluster-autoscaler \
--min-count 2 \
--max-count 10
# Upgrade cluster
az aks upgrade \
--resource-group myResourceGroup \
--name myAKSCluster \
--kubernetes-version 1.28.0

Q6: How do you deploy to AKS from Azure Pipelines?

Section titled “Q6: How do you deploy to AKS from Azure Pipelines?”

Answer:

azure-pipelines.yml
- task: AzureCLI@2
displayName: 'Get AKS credentials'
inputs:
azureSubscription: 'Azure-Service-Connection'
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az aks get-credentials \
--resource-group $(resourceGroup) \
--name $(aksCluster) \
--overwrite-existing
- task: KubernetesManifest@0
displayName: 'Deploy to AKS'
inputs:
action: 'deploy'
kubernetesServiceConnection: 'AKS-Service-Connection'
namespace: 'production'
manifests: |
k8s/deployment.yaml
k8s/service.yaml
containers: |
$(containerRegistry)/$(imageRepository):$(tag)
# Blue-Green with Kubernetes manifest
- task: KubernetesManifest@0
inputs:
action: 'promote'
namespace: 'production'
strategy: 'blue-green'
manifests: 'k8s/*.yaml'

Q7: How do you configure AKS with Azure Container Registry (ACR)?

Section titled “Q7: How do you configure AKS with Azure Container Registry (ACR)?”

Answer:

Terminal window
# Create ACR
az acr create \
--resource-group myResourceGroup \
--name myACR \
--sku Standard \
--admin-enabled false
# Attach ACR to AKS (grants pull permission)
az aks update \
--resource-group myResourceGroup \
--name myAKSCluster \
--attach-acr myACR
# Build and push image to ACR
az acr build \
--registry myACR \
--image myapp:latest \
--file Dockerfile \
.
# Enable geo-replication (Premium SKU)
az acr replication create \
--registry myACR \
--location westeurope
# Scan images with Defender for Containers
az security assessment list \
--query "[?displayName=='Vulnerabilities in Azure Container Registry images']"

Answer:

AspectARM TemplatesBicep
FormatJSONDomain-specific language
VerbosityVery verboseConcise
Type checkingNoYes
Transpiles toARM JSON
ReadabilityLowHigh
// main.bicep — Deploy an App Service
param location string = resourceGroup().location
param appName string
param sku string = 'B1'
resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = {
name: '${appName}-plan'
location: location
sku: {
name: sku
}
kind: 'linux'
properties: {
reserved: true
}
}
resource appService 'Microsoft.Web/sites@2022-09-01' = {
name: appName
location: location
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
linuxFxVersion: 'NODE|18-lts'
appSettings: [
{
name: 'NODE_ENV'
value: 'production'
}
]
}
}
}
output appUrl string = 'https://${appService.properties.defaultHostName}'
Terminal window
# Deploy Bicep
az deployment group create \
--resource-group myResourceGroup \
--template-file main.bicep \
--parameters appName=my-webapp
# Preview changes (what-if)
az deployment group what-if \
--resource-group myResourceGroup \
--template-file main.bicep
# In Azure Pipelines
- task: AzureResourceManagerTemplateDeployment@3
inputs:
deploymentScope: 'Resource Group'
azureResourceManagerConnection: 'Azure-Connection'
subscriptionId: '$(subscriptionId)'
action: 'Create Or Update Resource Group'
resourceGroupName: 'myResourceGroup'
location: 'East US'
templateLocation: 'Linked artifact'
csmFile: 'infrastructure/main.bicep'
overrideParameters: '-appName $(appName)'

Answer:

main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
backend "azurerm" {
resource_group_name = "terraform-state-rg"
storage_account_name = "tfstateaccount"
container_name = "tfstate"
key = "production.terraform.tfstate"
}
}
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "main" {
name = "production-rg"
location = "East US"
}
resource "azurerm_kubernetes_cluster" "aks" {
name = "production-aks"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
dns_prefix = "production-aks"
default_node_pool {
name = "default"
node_count = 3
vm_size = "Standard_D4s_v3"
enable_auto_scaling = true
min_count = 2
max_count = 10
}
identity {
type = "SystemAssigned"
}
network_profile {
network_plugin = "azure"
network_policy = "calico"
load_balancer_sku = "standard"
}
monitor_metrics {}
}

Q10: How do you set up Azure Monitor and Application Insights?

Section titled “Q10: How do you set up Azure Monitor and Application Insights?”

Answer:

Terminal window
# Create Log Analytics Workspace
az monitor log-analytics workspace create \
--resource-group myResourceGroup \
--workspace-name myWorkspace \
--location eastus \
--retention-time 90
# Create Application Insights
az monitor app-insights component create \
--app myapp-insights \
--location eastus \
--resource-group myResourceGroup \
--workspace-resource-id $WORKSPACE_ID
# Get instrumentation key
az monitor app-insights component show \
--app myapp-insights \
--resource-group myResourceGroup \
--query instrumentationKey
// Node.js — Application Insights SDK
const appInsights = require('applicationinsights');
appInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY)
.setAutoDependencyCorrelation(true)
.setAutoCollectRequests(true)
.setAutoCollectPerformance(true, true)
.setAutoCollectExceptions(true)
.setAutoCollectDependencies(true)
.start();
// Custom telemetry
const client = appInsights.defaultClient;
client.trackEvent({ name: 'UserSignup', properties: { userId: '123' } });
client.trackMetric({ name: 'QueueDepth', value: 42 });
client.trackException({ exception: new Error('Failed to process') });
// KQL Query in Log Analytics
// Top 10 slowest requests
requests
| where timestamp > ago(1h)
| project name, duration, success, resultCode
| order by duration desc
| take 10
// Error rate over time
exceptions
| where timestamp > ago(24h)
| summarize ErrorCount=count() by bin(timestamp, 1h)
| render timechart

Q11: How do you configure Azure Key Vault for applications?

Section titled “Q11: How do you configure Azure Key Vault for applications?”

Answer:

Terminal window
# Create Key Vault
az keyvault create \
--name myKeyVault \
--resource-group myResourceGroup \
--location eastus \
--enable-rbac-authorization true
# Add secrets
az keyvault secret set \
--vault-name myKeyVault \
--name DatabasePassword \
--value "supersecret"
# Grant access to AKS managed identity
az role assignment create \
--role "Key Vault Secrets User" \
--assignee $AKS_IDENTITY_CLIENT_ID \
--scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myKeyVault
# AKS — Azure Key Vault Provider for Secrets Store CSI Driver
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: azure-kvname
spec:
provider: azure
parameters:
usePodIdentity: "false"
clientID: $CLIENT_ID
keyvaultName: myKeyVault
cloudName: AzurePublicCloud
objects: |
array:
- |
objectName: DatabasePassword
objectType: secret
tenantId: $TENANT_ID
secretObjects:
- secretName: db-password
type: Opaque
data:
- objectName: DatabasePassword
key: password

Q12: How do you deploy Azure Functions in a CI/CD pipeline?

Section titled “Q12: How do you deploy Azure Functions in a CI/CD pipeline?”

Answer:

# azure-pipelines.yml for Azure Functions
- stage: BuildFunction
jobs:
- job: Build
steps:
- task: NodeTool@0
inputs:
versionSpec: '18.x'
- script: |
npm ci
npm run build
npm test
displayName: 'Build and Test'
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
includeRootFolder: false
archiveFile: '$(Build.ArtifactStagingDirectory)/function-app.zip'
- publish: $(Build.ArtifactStagingDirectory)
artifact: drop
- stage: DeployFunction
jobs:
- deployment: Deploy
environment: production
strategy:
runOnce:
deploy:
steps:
- task: AzureFunctionApp@2
inputs:
azureSubscription: 'Azure-Connection'
appType: functionAppLinux
appName: 'my-function-app'
package: $(Pipeline.Workspace)/drop/function-app.zip
runtimeStack: 'NODE|18'
deploymentMethod: 'auto'
slotName: 'staging' # Deploy to staging slot first
# Swap slots (staging → production)
- task: AzureAppServiceManage@0
inputs:
azureSubscription: 'Azure-Connection'
Action: 'Swap Slots'
WebAppName: 'my-function-app'
ResourceGroupName: 'myResourceGroup'
SourceSlot: 'staging'

Q13: How does Azure Active Directory integrate with DevOps?

Section titled “Q13: How does Azure Active Directory integrate with DevOps?”

Answer:

Terminal window
# Create service principal for CI/CD
az ad sp create-for-rbac \
--name "github-actions-sp" \
--role Contributor \
--scopes /subscriptions/$SUBSCRIPTION_ID \
--sdk-auth # Outputs JSON for GitHub secret
# For GitHub Actions — use OIDC (no long-lived credentials)
az ad app federated-credential create \
--id $APP_ID \
--parameters '{
"name": "github-actions",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:org/repo:ref:refs/heads/main",
"audiences": ["api://AzureADTokenExchange"]
}'
# GitHub Actions with OIDC
permissions:
id-token: write
contents: read
steps:
- uses: azure/login@v1
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Deploy to Azure
uses: azure/webapps-deploy@v2
with:
app-name: 'my-web-app'
package: './dist'

Q14: How do you use Azure Storage in DevOps workflows?

Section titled “Q14: How do you use Azure Storage in DevOps workflows?”

Answer:

Terminal window
# Create storage account (for Terraform state, artifacts)
az storage account create \
--name tfstateaccount \
--resource-group terraform-state-rg \
--location eastus \
--sku Standard_LRS \
--allow-blob-public-access false
# Create blob container
az storage container create \
--account-name tfstateaccount \
--name tfstate \
--auth-mode login
# Enable soft delete and versioning
az storage blob service-properties update \
--account-name tfstateaccount \
--enable-delete-retention true \
--delete-retention-days 30 \
--enable-versioning true
# Copy build artifacts to storage
az storage blob upload-batch \
--account-name myartifacts \
--destination artifacts/$BUILD_ID \
--source ./dist

Q15: How do you perform zero-downtime deployments in Azure App Service?

Section titled “Q15: How do you perform zero-downtime deployments in Azure App Service?”

Answer:

Terminal window
# Using Deployment Slots (Blue-Green)
# Create staging slot
az webapp deployment slot create \
--name myWebApp \
--resource-group myResourceGroup \
--slot staging
# Deploy to staging
az webapp deploy \
--resource-group myResourceGroup \
--name myWebApp \
--slot staging \
--src-path ./dist.zip
# Test staging
curl https://myWebApp-staging.azurewebsites.net/health
# Swap slots (instant traffic switch)
az webapp deployment slot swap \
--resource-group myResourceGroup \
--name myWebApp \
--slot staging \
--target-slot production
# Auto-swap (automatic after deployment)
az webapp deployment slot auto-swap \
--resource-group myResourceGroup \
--name myWebApp \
--slot staging \
--auto-swap-slot production

Back to DevOps Q&A Index


Section 7: Azure Quick-Fire Interview Questions

Section titled “Section 7: Azure Quick-Fire Interview Questions”

Q16: What is the difference between Azure DevOps and GitHub Actions?

Section titled “Q16: What is the difference between Azure DevOps and GitHub Actions?”

Answer:

FeatureAzure DevOps PipelinesGitHub Actions
PlatformMicrosoft AzureGitHub
PricingFree 1800 min/monthFree 2000 min/month
TriggersGit events, schedulesGit events, schedules, API
MarketplaceAzure DevOps MarketplaceGitHub Marketplace
IntegrationAzure services (native)Any cloud
YAMLazure-pipelines.yml.github/workflows/*.yml
Self-hosted✅ Azure Agents✅ Self-hosted runners
Best forAzure-heavy orgs, enterpriseGitHub repos, open-source

Q17: What is Azure Resource Manager (ARM) and why does it matter?

Section titled “Q17: What is Azure Resource Manager (ARM) and why does it matter?”

Answer: ARM is Azure’s deployment and management layer — ALL interactions with Azure go through it.

Terminal window
# Everything in Azure uses ARM:
# - Portal → ARM API
# - CLI → ARM API
# - SDK → ARM API
# - Terraform AzureRM → ARM API
# ARM benefits:
# - Consistent authentication (Azure AD)
# - Resource grouping
# - Tags for cost management
# - Role-Based Access Control (RBAC)
# - Deployment templates (ARM/Bicep)
# - Resource locking
# Resource Groups = logical containers for related resources
az group create --name production-rg --location eastus
# Resource lock — prevent accidental deletion
az lock create \
--name DoNotDelete \
--lock-type CanNotDelete \
--resource-group production-rg

Q18: What is Azure RBAC and how does it work?

Section titled “Q18: What is Azure RBAC and how does it work?”

Answer: RBAC (Role-Based Access Control) controls who can do what to Azure resources.

Terminal window
# Built-in roles:
# Owner: Full access + manage access
# Contributor: Full access, cannot manage access
# Reader: Read-only access
# User Access Administrator: Manage access only
# Assign role to user
az role assignment create \
--assignee user@company.com \
--role Contributor \
--scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/production-rg
# Assign role to service principal
az role assignment create \
--assignee $SERVICE_PRINCIPAL_ID \
--role "AcrPull" \
--scope /subscriptions/$SUB/resourceGroups/rg/providers/Microsoft.ContainerRegistry/registries/myACR
# Create custom role
az role definition create --role-definition '{
"Name": "AKS Deployer",
"Description": "Can deploy to AKS but not delete",
"Actions": [
"Microsoft.ContainerService/managedClusters/read",
"Microsoft.ContainerService/managedClusters/listClusterUserCredential/action"
],
"NotActions": [],
"AssignableScopes": ["/subscriptions/SUBSCRIPTION_ID"]
}'
# List assignments
az role assignment list --resource-group production-rg --output table

Q19: How do you implement Azure Policy for compliance?

Section titled “Q19: How do you implement Azure Policy for compliance?”

Answer: Azure Policy enforces organizational standards and compliance across Azure resources.

Terminal window
# Azure Policy = guardrails for Azure
# Example: Require all resources to have specific tags
# Create policy (require 'environment' tag)
az policy definition create \
--name 'require-environment-tag' \
--display-name 'Require Environment Tag' \
--description 'Requires environment tag on all resources' \
--rules '{
"if": {
"field": "tags[environment]",
"exists": "false"
},
"then": {
"effect": "deny"
}
}' \
--mode All
# Assign policy to subscription
az policy assignment create \
--name 'require-environment-tag-assignment' \
--scope /subscriptions/$SUBSCRIPTION_ID \
--policy require-environment-tag
# Common built-in policies:
az policy definition list --query "[?policyType=='BuiltIn'].displayName" | \
grep -i "kubernetes\|container\|security"
# - Kubernetes cluster should not allow privileged containers
# - Ensure HTTPS on App Service
# - Storage accounts should use private endpoints

Q20: What is Azure Managed Identity and why is it better than service principals?

Section titled “Q20: What is Azure Managed Identity and why is it better than service principals?”

Answer: Managed Identity = Azure-managed credentials (no passwords to store/rotate).

Terminal window
# Without Managed Identity:
# - Store client ID + client secret in app configuration
# - Rotate secrets manually
# - Risk of secret leakage
# With Managed Identity:
# - Azure manages the identity
# - No credentials to store
# - Automatically rotated by Azure
# Types:
# System-assigned: tied to one resource, deleted with resource
# User-assigned: created independently, can be shared
# Enable system-assigned identity on AKS
az aks update \
--resource-group myRG \
--name myAKS \
--enable-managed-identity
# Enable on App Service
az webapp identity assign \
--resource-group myRG \
--name myWebApp
# Returns principalId — use this for RBAC
# Grant managed identity access to Key Vault
az keyvault set-policy \
--name myKeyVault \
--object-id $MANAGED_IDENTITY_PRINCIPAL_ID \
--secret-permissions get list
# In application code — no credentials needed!
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
credential = DefaultAzureCredential() # Uses managed identity automatically
client = SecretClient(vault_url="https://myKeyVault.vault.azure.net/", credential=credential)
secret = client.get_secret("DatabasePassword")

Q21: How do you set up Azure Container Apps?

Section titled “Q21: How do you set up Azure Container Apps?”

Answer: Azure Container Apps is a serverless container platform (like AWS ECS Fargate but managed).

Terminal window
# Create Container Apps environment
az containerapp env create \
--name myEnvironment \
--resource-group myResourceGroup \
--location eastus \
--logs-workspace-id $LOG_ANALYTICS_WORKSPACE_ID \
--logs-workspace-key $LOG_ANALYTICS_KEY
# Deploy container app
az containerapp create \
--name myapp \
--resource-group myResourceGroup \
--environment myEnvironment \
--image myacr.azurecr.io/myapp:latest \
--registry-server myacr.azurecr.io \
--target-port 3000 \
--ingress external \
--min-replicas 1 \
--max-replicas 10 \
--scale-rule-name http-scaling \
--scale-rule-type http \
--scale-rule-http-concurrency 100 \
--env-vars NODE_ENV=production \
--secrets db-password=secretref:DatabasePassword
# Update with new image
az containerapp update \
--name myapp \
--resource-group myResourceGroup \
--image myacr.azurecr.io/myapp:v2.0
# View logs
az containerapp logs show \
--name myapp \
--resource-group myResourceGroup \
--follow

Q22: What is the difference between AKS, ACI, and Container Apps?

Section titled “Q22: What is the difference between AKS, ACI, and Container Apps?”

Answer:

FeatureAKSACIContainer Apps
TypeManaged K8sServerless containersServerless containers
ComplexityHighLowMedium
ScalingHPA + Cluster AutoscalerManualKEDA-based auto
K8s featuresFullNoneLimited
CostCluster fee + nodesPer secondPer vCPU/memory
Use caseComplex microservicesOne-off tasksMicroservices, APIs
ControlFullMinimalMedium
Terminal window
# ACI — for short-lived, one-off tasks
az container create \
--resource-group myRG \
--name db-migration \
--image myacr.azurecr.io/myapp:latest \
--command-line "python manage.py migrate" \
--restart-policy Never

Q23: How does Azure DevOps Boards integrate with CI/CD?

Section titled “Q23: How does Azure DevOps Boards integrate with CI/CD?”

Answer:

Terminal window
# Work items linked to commits/PRs
# Commit message format: "Fixed #123 - Login bug"
# AB#123 references Azure Boards work item
# Branch policies requiring linked work items
az repos policy work-item-linking create \
--blocking true \
--branch main \
--enabled true \
--repository-id $REPO_ID
# Auto-transition work items on PR completion
# Settings: Project → Boards → Project configuration → Automations
# "When a PR is completed → Move linked work items to 'Done'"
# Query work items in pipeline
- task: PowerShell@2
inputs:
targetType: inline
script: |
$token = "$(System.AccessToken)"
$url = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/wit/workitems/$(WORK_ITEM_ID)"
$response = Invoke-RestMethod -Uri $url -Headers @{Authorization="Bearer $token"}
Write-Host "Work item state: $($response.fields.'System.State')"

Q24: How do you implement infrastructure tagging strategy in Azure?

Section titled “Q24: How do you implement infrastructure tagging strategy in Azure?”

Answer:

dev/staging/production
# Consistent tagging policy:
# - team: backend/frontend/platform
# - project: myapp
# - cost-center: engineering
# - managed-by: terraform/bicep/manual
# Apply tags to resource group
az group update \
--name myResourceGroup \
--tags environment=production team=backend project=myapp
# Apply tags inherit to all resources via policy
az policy assignment create \
--name inherit-rg-tags \
--scope /subscriptions/$SUB/resourceGroups/production-rg \
--policy "Inherit a tag from the resource group" \
--params '{"tagName": {"value": "environment"}}'
# Cost analysis by tag
az consumption usage list \
--start-date 2024-01-01 \
--end-date 2024-01-31 \
--query "[].{cost: pretaxCost, tags: tags}"
# Enforce tags with Azure Policy
az policy assignment create \
--name require-team-tag \
--policy require-tag-policy \
--params '{"tagName": {"value": "team"}}'

Q25: What is Azure Service Bus and when to use it?

Section titled “Q25: What is Azure Service Bus and when to use it?”

Answer: Azure Service Bus is a fully managed enterprise message broker.

Terminal window
# Create Service Bus namespace
az servicebus namespace create \
--resource-group myRG \
--name myapp-servicebus \
--sku Standard
# Create queue
az servicebus queue create \
--resource-group myRG \
--namespace-name myapp-servicebus \
--name orders \
--max-delivery-count 10 \
--lock-duration PT30S \
--dead-lettering-on-message-expiration true
# Create topic (pub/sub pattern)
az servicebus topic create \
--resource-group myRG \
--namespace-name myapp-servicebus \
--name order-events
# Create subscription (consumer)
az servicebus topic subscription create \
--resource-group myRG \
--namespace-name myapp-servicebus \
--topic-name order-events \
--name inventory-processor
# Producer (Python)
from azure.servicebus import ServiceBusClient, ServiceBusMessage
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
with ServiceBusClient("myapp-servicebus.servicebus.windows.net", credential) as client:
with client.get_queue_sender("orders") as sender:
sender.send_messages(ServiceBusMessage('{"orderId": "123"}'))
# Consumer
with client.get_queue_receiver("orders") as receiver:
for msg in receiver.receive_messages(max_message_count=10):
print(str(msg))
receiver.complete_message(msg)

Q26: How do you configure Managed Prometheus and Grafana in Azure?

Section titled “Q26: How do you configure Managed Prometheus and Grafana in Azure?”

Answer:

Terminal window
# Enable Azure Managed Prometheus on AKS
az aks update \
--resource-group myRG \
--name myAKS \
--enable-azure-monitor-metrics
# Create Azure Managed Grafana
az grafana create \
--name myGrafana \
--resource-group myRG \
--location eastus
# Link Grafana to Azure Monitor Workspace
GRAFANA_ID=$(az grafana show --name myGrafana --resource-group myRG --query id -o tsv)
MONITOR_WORKSPACE_ID=$(az monitor account show --name myMonitor --resource-group myRG --query id -o tsv)
az grafana update \
--name myGrafana \
--resource-group myRG \
--grafana-major-version 10
# Pre-built K8s dashboards automatically available:
# - Kubernetes / Cluster Summary
# - Kubernetes / Node Summary
# - Kubernetes / Workload Summary

Q27: What is Azure Defender for Containers?

Section titled “Q27: What is Azure Defender for Containers?”

Answer: Microsoft Defender for Containers provides security for AKS clusters and container registries.

Terminal window
# Enable Defender for Containers
az security pricing create \
--name Containers \
--tier Standard
# Features:
# 1. ACR image scanning (on push)
# 2. AKS runtime threat detection
# 3. Kubernetes control plane audit log analysis
# 4. Security recommendations (Secure Score)
# View recommendations
az security assessment list \
--query "[?resourceType=='Microsoft.ContainerService/managedClusters']"
# Common findings:
# - Privileged containers running in cluster
# - Missing pod security policies
# - Public access to Kubernetes API
# - Outdated Kubernetes version
# Enable on ACR
az acr config content-trust update \
--status enabled \
--registry myACR

Q28: How does Azure Load Balancer differ from Azure Application Gateway?

Section titled “Q28: How does Azure Load Balancer differ from Azure Application Gateway?”

Answer:

FeatureAzure Load BalancerApplication Gateway
LayerL4 (TCP/UDP)L7 (HTTP/HTTPS)
Path routing❌ No✅ Yes
SSL termination❌ No✅ Yes
WAF❌ No✅ Optional
Cookie affinity❌ No✅ Yes
Autoscaling❌ No✅ Yes (v2)
CostLowHigher
Use caseNon-HTTP servicesWeb apps, APIs
Terminal window
# Azure Application Gateway = Azure's equivalent of AWS ALB + WAF
az network application-gateway create \
--resource-group myRG \
--name myAppGateway \
--location eastus \
--sku WAF_v2 \
--capacity 2 \
--vnet-name myVNet \
--subnet myAGSubnet \
--public-ip-address myPublicIP \
--http-settings-cookie-based-affinity Enabled \
--frontend-port 443 \
--http-settings-port 80
# Enable WAF
az network application-gateway waf-config set \
--gateway-name myAppGateway \
--resource-group myRG \
--enabled true \
--firewall-mode Prevention \
--rule-set-version 3.2

Q29: How do you troubleshoot Azure Pipeline failures?

Section titled “Q29: How do you troubleshoot Azure Pipeline failures?”

Answer:

Terminal window
# 1. View pipeline logs in Azure DevOps UI
# Pipelines → Failed run → Click on failed job → View logs
# 2. Enable debug logging
# Add pipeline variable:
# system.debug = true
# Shows verbose output including all commands
# 3. Download logs via CLI
az pipelines runs show --id $RUN_ID --org $ORG_URL --project $PROJECT
# 4. Re-run failed jobs
az pipelines runs job list \
--run-id $RUN_ID \
--org $ORG_URL \
--project $PROJECT
# 5. Test locally with act (GitHub Actions) or local agent
./run.sh # Test self-hosted agent
# Common pipeline failures:
# - Service connection expired → Renew service principal
# - Agent pool offline → Check agent status
# - Permission denied → Check RBAC on service connection
# - Image not found → Check ACR login in pipeline
# - Variable not defined → Add to variable group or pipeline variables

Q30: What is Azure Managed Disks and how are they used with AKS?

Section titled “Q30: What is Azure Managed Disks and how are they used with AKS?”

Answer:

Terminal window
# Azure Disk types:
# Premium SSD (P-series): Fast, for databases
# Standard SSD (E-series): General purpose
# Ultra Disk: Highest performance, lowest latency
# Standard HDD: Archives, infrequent access
# AKS Storage Classes
kubectl get storageclass
# NAME PROVISIONER
# azuredisk-csi-lrs disk.csi.azure.com # Default, LRS
# azurefile-csi file.csi.azure.com # RWX capable
# azuredisk-csi-premium disk.csi.azure.com # Premium SSD
# Create PVC with Azure Premium SSD
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-storage
spec:
accessModes:
- ReadWriteOnce
storageClassName: managed-premium
resources:
requests:
storage: 50Gi
EOF
# Azure Files for RWX (shared across pods)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-storage
spec:
accessModes:
- ReadWriteMany # Multiple pods can write
storageClassName: azurefile-csi
resources:
requests:
storage: 100Gi
EOF

Q31: How do you implement Azure Cost Management in DevOps?

Section titled “Q31: How do you implement Azure Cost Management in DevOps?”

Answer:

Terminal window
# 1. View costs
az consumption usage list \
--start-date 2024-01-01 \
--end-date 2024-01-31 \
--output table
# 2. Create budget with alerts
az consumption budget create \
--budget-name monthly-budget \
--amount 5000 \
--time-grain Monthly \
--start-date 2024-01-01 \
--end-date 2024-12-31 \
--category Cost \
--notification-enabled true \
--notification-operator GreaterThan \
--notification-threshold 80 \
--contact-emails admin@company.com
# 3. AKS cost optimization
# - Use Spot node pools for dev/test
az aks nodepool add \
--resource-group myRG \
--cluster-name myAKS \
--name spotpool \
--priority Spot \
--eviction-policy Delete \
--spot-max-price -1 \
--node-count 3 \
--node-vm-size Standard_D4s_v3
# 4. Auto-scale for zero cost at night (dev)
az aks update --name myDevAKS --resource-group myRG --node-count 0
# 5. Use Azure Spot VMs for CI runners (70% cheaper)

Q32: What is Azure Application Service Plan and how does it affect scaling?

Section titled “Q32: What is Azure Application Service Plan and how does it affect scaling?”

Answer:

Terminal window
# App Service Plans:
# F1 (Free): 1GB, shared, no scaling
# B1 (Basic): 1.75GB, dedicated, manual scale
# P1v3 (Premium): 8GB, dedicated, auto-scale
# P2v3: 16GB (for high traffic)
# Create App Service Plan (Premium for production)
az appservice plan create \
--name myAppPlan \
--resource-group myRG \
--sku P1v3 \
--is-linux \
--number-of-workers 2
# Configure auto-scaling rules
az monitor autoscale create \
--resource-group myRG \
--name myAutoscale \
--resource myAppPlan \
--resource-type Microsoft.Web/serverfarms \
--min-count 2 \
--max-count 10 \
--count 2
# Scale up on CPU > 70%
az monitor autoscale rule create \
--resource-group myRG \
--autoscale-name myAutoscale \
--condition "CpuPercentage > 70 avg 5m" \
--scale out 1
# Scale down on CPU < 30%
az monitor autoscale rule create \
--resource-group myRG \
--autoscale-name myAutoscale \
--condition "CpuPercentage < 30 avg 10m" \
--scale in 1

Q33: How do you set up Azure Front Door for global load balancing?

Section titled “Q33: How do you set up Azure Front Door for global load balancing?”

Answer: Azure Front Door is a global CDN + load balancer + WAF (similar to AWS CloudFront + Global Accelerator).

Terminal window
# Create Front Door profile
az afd profile create \
--profile-name myFrontDoor \
--resource-group myRG \
--sku Standard_AzureFrontDoor
# Add endpoint
az afd endpoint create \
--resource-group myRG \
--profile-name myFrontDoor \
--endpoint-name myapp-endpoint
# Add origin group (backend servers)
az afd origin-group create \
--resource-group myRG \
--profile-name myFrontDoor \
--origin-group-name myOriginGroup \
--probe-request-type GET \
--probe-protocol Https \
--probe-interval-in-seconds 30 \
--probe-path /health
# Add origin (backend)
az afd origin create \
--resource-group myRG \
--profile-name myFrontDoor \
--origin-group-name myOriginGroup \
--origin-name eastus-app \
--host-name myapp-eastus.azurewebsites.net \
--origin-host-header myapp-eastus.azurewebsites.net \
--priority 1 \
--weight 1000
# Add routing rule
az afd route create \
--resource-group myRG \
--profile-name myFrontDoor \
--endpoint-name myapp-endpoint \
--route-name myRoute \
--origin-group myOriginGroup \
--supported-protocols Https \
--https-redirect Enabled

Q34: What is Azure DevOps REST API and how do you use it?

Section titled “Q34: What is Azure DevOps REST API and how do you use it?”

Answer:

Terminal window
# Azure DevOps has full REST API for automation
BASE_URL="https://dev.azure.com/{organization}/{project}/_apis"
# Get builds
curl -u :$PAT \
"$BASE_URL/build/builds?api-version=7.1" | jq '.value[].result'
# Trigger pipeline
curl -u :$PAT \
-X POST \
-H "Content-Type: application/json" \
"$BASE_URL/build/builds?api-version=7.1" \
-d '{
"definition": {"id": 1},
"sourceBranch": "refs/heads/main",
"parameters": "{\"environment\": \"staging\"}"
}'
# Create work item
curl -u :$PAT \
-X POST \
-H "Content-Type: application/json-patch+json" \
"$BASE_URL/wit/workitems/\$Task?api-version=7.1" \
-d '[
{"op": "add", "path": "/fields/System.Title", "value": "Deploy v2.0"},
{"op": "add", "path": "/fields/System.AssignedTo", "value": "dev@company.com"}
]'
# Use in Python
import requests
from base64 import b64encode
headers = {
'Authorization': f'Basic {b64encode(f":{PAT}".encode()).decode()}',
'Content-Type': 'application/json'
}
response = requests.get(f'{BASE_URL}/build/builds?api-version=7.1', headers=headers)

Q35: How do you implement rollback in Azure Pipelines?

Section titled “Q35: How do you implement rollback in Azure Pipelines?”

Answer:

# Strategy 1: Rerun previous successful build
# Pipelines → Find last successful run → Rerun
# Strategy 2: Deployment slot swap back
steps:
- task: AzureAppServiceManage@0
inputs:
azureSubscription: 'Azure-Connection'
Action: 'Swap Slots'
WebAppName: 'myWebApp'
ResourceGroupName: 'myRG'
SourceSlot: 'production' # Swap back
TargetSlot: 'staging'
# Strategy 3: AKS rollback
- task: Kubernetes@1
inputs:
connectionType: 'Azure Resource Manager'
azureSubscriptionEndpoint: 'Azure-Connection'
azureResourceGroup: 'myRG'
kubernetesCluster: 'myAKS'
command: 'rollout'
arguments: 'undo deployment/myapp -n production'
# Strategy 4: Terraform rollback
# Git revert infrastructure changes
# Re-run terraform apply with old state
# Strategy 5: Feature flag toggle
# Disable new feature in Azure App Configuration
az appconfig kv set \
--name myAppConfig \
--key "FeatureFlags:NewCheckout" \
--value "false"

Q36: What is Azure Bicep and how does it compare to Terraform?

Section titled “Q36: What is Azure Bicep and how does it compare to Terraform?”

Answer:

FeatureBicepTerraform
ScopeAzure onlyMulti-cloud
LanguageBicep DSLHCL
State managementARM (no state file).tfstate file
ModulesBicep modulesTerraform modules
Drift detectionLimitedterraform plan
Learning curveMedium (Azure knowledge)Medium (HCL)
Best forAzure-only orgsMulti-cloud or AWS+Azure
// Bicep — AKS cluster
param clusterName string
param location string = resourceGroup().location
param nodeCount int = 3
resource aks 'Microsoft.ContainerService/managedClusters@2023-05-01' = {
name: clusterName
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
dnsPrefix: clusterName
agentPoolProfiles: [
{
name: 'default'
count: nodeCount
vmSize: 'Standard_D4s_v3'
enableAutoScaling: true
minCount: 2
maxCount: 10
mode: 'System'
}
]
addonProfiles: {
omsagent: {
enabled: true
config: {
logAnalyticsWorkspaceResourceID: logAnalyticsWorkspaceId
}
}
}
}
}
output clusterFqdn string = aks.properties.fqdn

Q37: How do you configure network security in AKS?

Section titled “Q37: How do you configure network security in AKS?”

Answer:

Terminal window
# 1. Private cluster (no public API server)
az aks create \
--resource-group myRG \
--name myPrivateAKS \
--enable-private-cluster \
--load-balancer-sku standard \
--network-plugin azure
# 2. Calico NetworkPolicy
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress: [] # No ingress allowed by default
EOF
# Allow specific traffic
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080
EOF
# 3. Azure Firewall for egress control
az aks update \
--resource-group myRG \
--name myAKS \
--outbound-type userDefinedRouting
# 4. Authorized IP ranges for API server
az aks update \
--resource-group myRG \
--name myAKS \
--api-server-authorized-ip-ranges "192.168.1.0/24,10.0.0.0/8"

Q38: How do you implement GitOps with Azure DevOps and Flux?

Section titled “Q38: How do you implement GitOps with Azure DevOps and Flux?”

Answer:

Terminal window
# Install Flux on AKS via Azure CLI
az k8s-configuration flux create \
--resource-group myRG \
--cluster-name myAKS \
--cluster-type managedClusters \
--name gitops-config \
--scope cluster \
--url https://dev.azure.com/myorg/myproject/_git/k8s-configs \
--branch main \
--kustomization name=production path=./overlays/production prune=true
# Flux watches the Git repo and reconciles cluster state
# Developer workflow:
# 1. Developer commits to k8s-configs repo
# 2. Flux detects change
# 3. Flux applies change to cluster
# 4. No manual kubectl apply needed!
# View Flux status
kubectl get gitrepository -n flux-system
kubectl get kustomization -n flux-system
flux get kustomizations
# Force reconciliation
flux reconcile kustomization production --with-source
# Suspend/resume reconciliation
flux suspend kustomization production
flux resume kustomization production

Q39: What is Azure DevTest Labs and how is it used?

Section titled “Q39: What is Azure DevTest Labs and how is it used?”

Answer: DevTest Labs enables teams to quickly create environments in Azure with cost controls.

Terminal window
# DevTest Labs use cases:
# - Dev/test environments
# - Training environments
# - Proof of concept environments
# - On-demand VMs with auto-shutdown
# Create DevTest Lab
az lab create \
--resource-group myRG \
--name myDevTestLab \
--location eastus
# Add auto-shutdown policy (cost savings)
az lab policy set \
--lab-name myDevTestLab \
--resource-group myRG \
--policy-set-name default \
--name LabVmsShutdown \
--policy-type Schedule \
--status Enabled \
--fact-data '{"taskType":"LabVmsShutdownTask","dailyRecurrence":{"time":"2200"},"timeZoneId":"UTC"}'
# Create VM from approved image
az lab vm create \
--lab-name myDevTestLab \
--resource-group myRG \
--name devvm01 \
--image "Ubuntu Server 20.04 LTS" \
--image-type GalleryImage \
--size Standard_B2ms
# Claim VM (DevTest Labs self-service portal)
az lab vm claim \
--lab-name myDevTestLab \
--resource-group myRG \
--name devvm01

Q40: How do you implement end-to-end Azure DevSecOps?

Section titled “Q40: How do you implement end-to-end Azure DevSecOps?”

Answer:

# Complete DevSecOps pipeline in Azure Pipelines
stages:
- stage: SecurityScan
jobs:
- job: SAST
steps:
# Static Application Security Testing
- task: SonarCloudPrepare@1
inputs:
SonarCloud: 'SonarCloud-Connection'
organization: 'myorg'
scannerMode: 'CLI'
- script: sonar-scanner
- task: SonarCloudPublish@1
inputs:
pollingTimeoutSec: '300'
# Dependency scanning
- task: SnykSecurityScan@1
inputs:
serviceConnectionEndpoint: 'Snyk-Connection'
testType: 'app'
failOnIssues: true
monitorWhen: always
- job: ContainerScan
steps:
- task: AzureContainerScan@0
inputs:
azureSubscription: 'Azure-Connection'
imageName: '$(imageRepository):$(tag)'
registryName: 'myacr.azurecr.io'
# Microsoft Defender scan results
- task: PowerShell@2
inputs:
targetType: inline
script: |
$findings = az security assessment list --query "[?resourceType=='Microsoft.ContainerRegistry/registries']" | ConvertFrom-Json
if ($findings.status.code -eq 'Unhealthy') {
Write-Error "Security vulnerabilities found!"
exit 1
}
- stage: Build
dependsOn: SecurityScan
condition: succeeded()
jobs:
- job: BuildAndPush
steps:
- task: Docker@2
inputs:
command: buildAndPush
tags: |
$(tag)
latest
- stage: Deploy
dependsOn: Build
jobs:
- deployment: Production
environment: production
strategy:
runOnce:
deploy:
steps:
- task: KubernetesManifest@0
inputs:
action: deploy
namespace: production
manifests: k8s/

Q41: How do you troubleshoot AKS node issues?

Section titled “Q41: How do you troubleshoot AKS node issues?”

Answer:

Terminal window
# 1. Check node status
kubectl get nodes
kubectl describe node aks-nodepool1-123456-vmss000000
# 2. Check node conditions
kubectl get nodes -o custom-columns=\
NAME:.metadata.name,\
STATUS:.status.conditions[-1].type,\
REASON:.status.conditions[-1].reason
# 3. SSH to AKS node (without bastion)
az aks debug node-ssh \
--resource-group myRG \
--cluster-name myAKS \
--node-name aks-nodepool1-123456-vmss000000
# 4. Check kubelet logs on node
journalctl -u kubelet -n 100
# 5. Check container runtime
crictl ps -a # View all containers including stopped
crictl logs <container-id>
# 6. Node network debugging
az network watcher check-connectivity \
--resource-group myRG \
--source-resource <vm-id> \
--dest-address 10.0.0.5 \
--dest-port 80
# 7. Cordon node and migrate workloads
kubectl cordon aks-nodepool1-123456-vmss000000
kubectl drain aks-nodepool1-123456-vmss000000 --ignore-daemonsets
# 8. Delete and replace node
az aks nodepool delete-machines \
--resource-group myRG \
--cluster-name myAKS \
--nodepool-name nodepool1 \
--machine-names aks-nodepool1-123456-vmss000000

Q42: What is the Azure Well-Architected Framework?

Section titled “Q42: What is the Azure Well-Architected Framework?”

Answer: Microsoft’s guidance framework for cloud-native applications across 5 pillars.

5 Pillars of Azure Well-Architected Framework:
1. Reliability
- High availability (multi-AZ, multi-region)
- Fault tolerance and disaster recovery
- Health monitoring and alerting
- Backup and restore procedures
2. Security
- Zero-trust model
- Identity and access management (Azure AD)
- Data protection (Key Vault, encryption)
- Network security (NSG, Azure Firewall)
3. Cost Optimization
- Right-sizing resources
- Reserved instances / savings plans
- Auto-scaling to match demand
- Cost monitoring and budgets
4. Operational Excellence
- Infrastructure as Code (Bicep/Terraform)
- CI/CD pipelines
- Monitoring and observability
- Incident management
5. Performance Efficiency
- Auto-scaling
- Caching (Redis Cache)
- CDN (Azure Front Door)
- Database optimization
Terminal window
# Azure Advisor — Well-Architected recommendations
az advisor recommendation list --output table
az advisor recommendation list \
--category Cost \
--query "[?impact=='High']"

Q43: How do you implement Azure Chaos Studio for resilience testing?

Section titled “Q43: How do you implement Azure Chaos Studio for resilience testing?”

Answer:

Terminal window
# Azure Chaos Studio = Azure-native chaos engineering tool
# Similar to AWS Fault Injection Simulator
# Enable Chaos Studio on AKS
az resource update \
--ids $AKS_RESOURCE_ID \
--set properties.agentPoolProfiles[0].count=3
# Create experiment — kill random pods
cat <<EOF | az rest --method PUT \
--uri "https://management.azure.com/subscriptions/$SUB/resourceGroups/myRG/providers/Microsoft.Chaos/experiments/kill-pods?api-version=2023-04-01" \
--body @-
{
"location": "eastus",
"properties": {
"steps": [{
"name": "Kill Pods",
"branches": [{
"name": "branch1",
"actions": [{
"type": "continuous",
"name": "urn:csci:microsoft:azureKubernetesService:podChaos/1.0",
"parameters": [{
"key": "jsonSpec",
"value": "{\"action\":\"pod-failure\",\"mode\":\"one\",\"selector\":{\"labelSelectors\":{\"app\":\"myapp\"}}}"
}],
"duration": "PT5M"
}]
}]
}],
"targets": [{
"id": "$AKS_RESOURCE_ID/providers/Microsoft.Chaos/targets/Microsoft-AzureKubernetesService",
"roles": []
}]
}
}
EOF
# Start experiment
az chaos experiment start \
--resource-group myRG \
--name kill-pods

Answer: Landing Zones are pre-configured Azure environments following best practices — used for enterprise-scale onboarding.

Azure Landing Zone Architecture:
├── Management Group (root)
│ ├── Platform
│ │ ├── Identity (Azure AD, Key Vault)
│ │ ├── Management (Log Analytics, Automation)
│ │ └── Connectivity (Hub VNet, ExpressRoute, VPN)
│ └── Landing Zones
│ ├── Corp (internal apps, connected to Hub)
│ └── Online (internet-facing, no Hub connection)
│ Each landing zone includes:
│ - Pre-configured RBAC
│ - Azure Policies (compliance guardrails)
│ - Network (spoke VNet peered to Hub)
│ - Security baselines
Terminal window
# Deploy Azure Landing Zone with Terraform
git clone https://github.com/Azure/terraform-azurerm-caf-enterprise-scale
cd terraform-azurerm-caf-enterprise-scale
terraform init
terraform plan -out tfplan \
-var root_parent_id=$ROOT_MGMT_GROUP_ID \
-var root_id=myorg
terraform apply tfplan

Q45: How do you set up Azure Monitor Alerts for DevOps?

Section titled “Q45: How do you set up Azure Monitor Alerts for DevOps?”

Answer:

Terminal window
# 1. Metric alert
az monitor metrics alert create \
--name high-cpu-alert \
--resource-group myRG \
--scopes $AKS_RESOURCE_ID \
--condition "avg Percentage CPU > 80" \
--window-size 5m \
--evaluation-frequency 1m \
--action $ACTION_GROUP_ID \
--severity 2
# 2. Log alert (KQL)
az monitor scheduled-query create \
--resource-group myRG \
--name error-rate-alert \
--scopes $LOG_ANALYTICS_WORKSPACE_ID \
--condition "count > 100" \
--condition-query \
"exceptions | where timestamp > ago(5m) | summarize count()" \
--window-duration PT5M \
--evaluation-frequency PT5M \
--action $ACTION_GROUP_ID \
--severity 1
# 3. Create action group (notifications)
az monitor action-group create \
--resource-group myRG \
--name myActionGroup \
--short-name myAG \
--email-receiver name=DevOps email=devops@company.com \
--webhook-receiver name=Slack \
service-uri=https://hooks.slack.com/services/xxx/yyy/zzz \
use-common-alert-schema true
# 4. Alert processing rule (suppress during maintenance)
az monitor alert-processing-rule create \
--resource-group myRG \
--rule-name MaintenanceWindow \
--enabled true \
--scopes $RESOURCE_ID \
--filter-alert-rule-name contains "high-cpu" \
--action-type "RemoveAllActionGroups" \
--recurrence-type Weekly \
--recurrence-days Sunday \
--recurrence-start-time "02:00:00" \
--recurrence-end-time "04:00:00"

Q46: How do you implement observability in Azure with OpenTelemetry?

Section titled “Q46: How do you implement observability in Azure with OpenTelemetry?”

Answer:

Terminal window
# OpenTelemetry → Azure Monitor (auto-instrumentation for AKS)
az aks update \
--resource-group myRG \
--name myAKS \
--enable-azure-monitor-metrics \
--azure-monitor-workspace-resource-id $MONITOR_WORKSPACE_ID
# Application-level OpenTelemetry
pip install opentelemetry-distro azure-monitor-opentelemetry
# Python app
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace, metrics
configure_azure_monitor(
connection_string="InstrumentationKey=xxx"
)
tracer = trace.get_tracer(__name__)
@app.route('/api/orders')
def get_orders():
with tracer.start_as_current_span("get-orders") as span:
span.set_attribute("user.id", user_id)
orders = db.query("SELECT * FROM orders")
return jsonify(orders)

Q47: What is Azure DevOps Environments and how do deployment gates work?

Section titled “Q47: What is Azure DevOps Environments and how do deployment gates work?”

Answer:

# Azure DevOps Environments = deployment targets with approvals and history
# Create environments: Pipelines → Environments → New
# Deployment with gates
stages:
- stage: Deploy
jobs:
- deployment: DeployProduction
environment: production # Links to Azure DevOps Environment
strategy:
runOnce:
preDeploy:
steps:
- script: echo "Pre-deploy checks"
deploy:
steps:
- task: KubernetesManifest@0
inputs:
action: deploy
namespace: production
manifests: k8s/
routeTraffic:
steps:
- script: echo "Traffic is now flowing to new version"
postRouteTraffic:
steps:
# Automated gate — check error rate
- task: InvokeRestAPI@1
inputs:
connectionType: 'connectedServiceName'
serviceConnection: 'Monitoring-Connection'
method: 'GET'
urlSuffix: '/api/metrics/error-rate'
successCriteria: '$.errorRate < 0.01'
on:
failure:
steps:
- script: kubectl rollout undo deployment/myapp -n production

Q48: How do you perform Azure resource cleanup with automation?

Section titled “Q48: How do you perform Azure resource cleanup with automation?”

Answer:

Terminal window
# Scheduled cleanup of dev/test resources using Azure Automation
# Create Runbook to delete old resources
az automation runbook create \
--automation-account-name myAutomation \
--resource-group myRG \
--name cleanup-old-resources \
--type Python3
# Schedule it
az automation schedule create \
--automation-account-name myAutomation \
--resource-group myRG \
--name daily-cleanup \
--frequency Day \
--interval 1 \
--start-time "2024-01-01T02:00:00+00:00"
# Python runbook content
cat <<'EOF'
import automationassets
from datetime import datetime, timedelta
import azure.mgmt.resource
creds = automationassets.get_automation_runas_credential("AzureRunAsConnection")
# Find resources older than 7 days in dev environment
cutoff = datetime.utcnow() - timedelta(days=7)
# Delete dev resources created before cutoff date
EOF
# Alternative: Azure DevOps pipeline scheduled cleanup
schedules:
- cron: "0 2 * * *"
displayName: Daily Cleanup
branches:
include:
- main
always: true
stages:
- stage: Cleanup
jobs:
- job: CleanupDevResources
steps:
- task: AzureCLI@2
inputs:
azureSubscription: 'Azure-Connection'
scriptType: bash
inlineScript: |
# Delete resource groups tagged for cleanup
az group list --tag cleanup=true --query "[].name" -o tsv | \
xargs -I{} az group delete --name {} --yes --no-wait

Q49: What is the difference between Azure ExpressRoute and VPN Gateway?

Section titled “Q49: What is the difference between Azure ExpressRoute and VPN Gateway?”

Answer:

FeatureExpressRouteVPN Gateway
ConnectionPrivate (ISP/partner)Public internet (encrypted)
Bandwidth50Mbps – 100GbpsUp to 10Gbps
LatencyLow, consistentVariable
ReliabilitySLA-backedInternet-dependent
CostHigh (circuit + gateway)Lower
Use caseEnterprise, complianceGeneral hybrid cloud
Terminal window
# VPN Gateway (for most organizations)
az network vnet-gateway create \
--resource-group myRG \
--name myVPNGateway \
--vnet myVNet \
--public-ip-address myPublicIP \
--gateway-type Vpn \
--sku VpnGw2 \
--vpn-type RouteBased
# Connect to on-premise
az network vpn-connection create \
--resource-group myRG \
--name myVPNConnection \
--vnet-gateway1 myVPNGateway \
--local-gateway2 myLocalGateway \
--shared-key MySharedKey
# ExpressRoute (requires ISP partner setup)
az network express-route create \
--resource-group myRG \
--name myExpressRoute \
--bandwidth 1000 \
--peering-location "Silicon Valley" \
--provider "Equinix" \
--sku-family MeteredData \
--sku-tier Premium

Q50: How do you implement Azure Arc for hybrid/multi-cloud management?

Section titled “Q50: How do you implement Azure Arc for hybrid/multi-cloud management?”

Answer: Azure Arc extends Azure management to on-premise, other clouds, and edge environments.

Terminal window
# Arc-enabled servers (manage any Linux/Windows server from Azure)
# Run on on-premise or another cloud server:
az connectedmachine connect \
--resource-group myRG \
--name my-onprem-server \
--location eastus \
--subscription $SUBSCRIPTION_ID
# Now manage on-prem server from Azure:
# - Azure Monitor
# - Defender for Cloud
# - Azure Policy
# - Azure Automation (patching)
# - Azure AD SSH login
# Arc-enabled Kubernetes (manage any K8s from Azure)
az connectedk8s connect \
--resource-group myRG \
--name my-gke-cluster \
--location eastus
# kubeconfig from GKE cluster
# Now use Azure Pipelines, Azure Policy, GitOps (Flux)
# on ANY Kubernetes cluster (GKE, EKS, on-prem)
az connectedk8s list --output table
# Shows all connected clusters regardless of where they run
# Deploy via GitOps to Arc-enabled K8s
az k8s-configuration flux create \
--resource-group myRG \
--cluster-name my-gke-cluster \
--cluster-type connectedClusters \
--name gitops-config \
--url https://github.com/myorg/k8s-configs \
--branch main

Back to DevOps Q&A Index