Container Apps solved the availability engine with very little effort, and that is the best news in the previous lesson. But there is a different front at Contoso Airlines: the flight operations platform, twelve microservices that coordinate gate assignment, crew rotation, fuel loading and delays, written by three teams, with one component that demands high-memory nodes and another that needs affinity between pods. That system calls for fine-grained control of scheduling, network policies between services and third-party operators. There, yes: Kubernetes.
This lesson teaches Azure Kubernetes Service honestly: what it gives you, what remains your work, what it really costs and in which cases adopting it is over-engineering. Contoso adopts it for flight operations, not for the whole platform, and that decision is the first lesson.
Contents
- When Kubernetes is justified and when it is not
- Kubernetes concepts, the essentials
- What AKS manages and what remains yours
- Creating
aks-contoso-operacionesand choosing the network model - Identity: Entra ID, RBAC and workload identity
- Deploying the application with manifests and
kubectl - Managed ingress and certificates
- Scaling, requests and limits
- Upgrades, disruptions and maintenance
- Persistent storage, observability, Helm and realistic cost
- Common Mistakes and Tips
- Exercises
- Conclusion
- When Kubernetes is justified and when it is not
| Signal | Kubernetes? |
|---|---|
| A handful of stateless APIs with uneven load | No: Container Apps, cheaper |
| Twelve or more services with dependencies between them | Yes |
| You need operators, service meshes or CRDs, or per-workload hardware (GPU) | Yes |
| Real portability between clouds or your own data center | Yes |
| "It's what everyone uses now", or nobody knows how to operate a cluster | No, and those are the two most frequent reasons |
The hidden cost of Kubernetes is not the node bill, it is the team's time: quarterly upgrades, API versions being retired, network debugging, certificate management. If nobody is going to spend time on that, a cluster ages until it becomes a risk. Contoso takes it on only where the return justifies it.
- Kubernetes concepts, the essentials
graph TD
subgraph CP["Control plane (managed by AKS, free)"]
API[API server] --- ETCD[(etcd)]
API --- SCHED[Scheduler] --- CTRL[Controllers]
end
subgraph NODES["Node pools (your virtual machines, you pay)"]
N1["Node 1: gates pod + crew pod"]
N2["Node 2: gates pod + fuel pod"]
end
API --> N1
API --> N2
ING[Ingress: operaciones.contosoairlines.example] --> SVC[Service: gates]
SVC --> N1
SVC --> N2
- Control plane: the brain. The API server receives every instruction, etcd stores the desired state, the scheduler decides which node each pod fits on and the controllers endlessly correct the difference between what exists and what should exist. That reconciliation loop is the central idea of Kubernetes: you declare the destination, the system takes care of the route.
- Node: a virtual machine that runs pods, grouped with others into node pools. And pod: the smallest schedulable unit, one or more containers that share networking and storage. It is ephemeral: if it dies, it does not come back; another one is born with a different IP address.
- Deployment and ReplicaSet: the deployment declares "I want N replicas of this pod with this image"; the ReplicaSet keeps the count and orchestrates rolling updates.
- Service and ingress: the service gives a stable IP and DNS name in front of a changing set of pods — it solves the fact that pods have no fixed address — while the ingress routes incoming HTTP traffic by host name and path, with TLS, through a single entry point for many services.
- Namespace: a logical partition of the cluster with its own quotas and permissions; Contoso uses
operaciones-vuelo,integracionandmonitorizacion. And ConfigMap and Secret: configuration and sensitive data injected as environment variables or files. Careful: a Kubernetes Secret is only base64-encoded, not encrypted, which is why Contoso pulls them fromkv-contoso-pro.
- What AKS manages and what remains yours
| Responsibility | AKS | You |
|---|---|---|
| Control plane (API, etcd, scheduler) | Yes, and it is free | — |
| etcd backups | Yes | — |
| Nodes: virtual machines and disks | Provisions them | You pay for them |
| OS patching and Kubernetes version | Publishes images and versions | Deciding and launching the upgrade |
| Manifests, limits, network policies, alerts | Integrations | Yours |
Say it plainly, because it generates a lot of surprise bills: the AKS control plane is free on the Free tier; what you pay for are the nodes, which are ordinary virtual machines with their compute price and their disks. An "empty" cluster with three nodes costs the same as three virtual machines left running. The Standard tier adds an SLA with a per-cluster hourly cost, and that is what is appropriate in production.
- Creating
aks-contoso-operaciones and choosing the network model
aks-contoso-operaciones and choosing the network modelaz aks create \
--resource-group rg-contoso-reservas-pro --name aks-contoso-operaciones \
--location westeurope --tier standard --kubernetes-version 1.30.4 \
--nodepool-name sistema --node-count 3 --node-vm-size Standard_D4s_v5 --zones 1 2 3 \
--enable-cluster-autoscaler --min-count 3 --max-count 6 \
--network-plugin azure --network-plugin-mode overlay --network-policy cilium \
--vnet-subnet-id $(az network vnet subnet show -g rg-contoso-red-pro \
--vnet-name vnet-contoso-pro -n snet-app --query id -o tsv) \
--enable-aad --enable-azure-rbac --enable-managed-identity \
--enable-oidc-issuer --enable-workload-identity \
--attach-acr acrcontosopro --enable-addons monitoring \
--workspace-resource-id $(az monitor log-analytics workspace show \
-g rg-contoso-seguridad-pro -n log-contoso-pro --query id -o tsv) \
--tags entorno=produccion proyecto=contoso-reservas \
centro-coste=CC-1042 [email protected]And straight after it the user node pool, because mixing system and application workloads in the same pool is a classic mistake:
az aks nodepool add \
--resource-group rg-contoso-reservas-pro --cluster-name aks-contoso-operaciones \
--name aplicaciones --mode User \
--node-vm-size Standard_D8s_v5 --node-count 2 --zones 1 2 3 \
--enable-cluster-autoscaler --min-count 2 --max-count 12The decisions behind all this:
--nodepool-name sistemawith--mode System(implicit increate): it hosts CoreDNS,metrics-serverand the add-ons. If a runaway application workload eats its memory, DNS goes down for the entire cluster. Separate them.--zones 1 2 3spreads the nodes across availability zones — without this, a zone incident takes the cluster with it — and--enable-cluster-autoscaleradds and removes nodes according to the pods that do not fit, which is different from pod scaling (section 8).--attach-acr acrcontosoproassigns theAcrPullrole to the cluster's kubelet identity for you; without it, pods fail withImagePullBackOffand the error is opaque. And--enable-workload-identityplus--enable-oidc-issueris the foundation of section 5.
Networking: kubenet, Azure CNI and CNI Overlay
| kubenet | Azure CNI | Azure CNI Overlay | |
|---|---|---|---|
| Pod IP | Internal overlay network | From the virtual network subnet | Managed overlay network |
| Subnet IP consumption | Very low | Very high | Very low |
| Direct connectivity to the pod | No, with hops | Yes | Not direct |
| Performance and status | Lower; being retired | Maximum; current | Almost like CNI; recommended |
The most expensive design mistake in AKS is choosing Azure CNI without doing the arithmetic: each node reserves in advance as many IPs as the maximum number of pods it can host (30 by default), so 20 nodes consume 600 addresses and a /24 runs out before you have even started. Contoso uses CNI Overlay over snet-app (10.20.2.0/24): the nodes take IPs from the subnet, the pods from an overlay space, and the subnet copes with growth. Network policy (Cilium) is added so that a pod can be explicitly forbidden from talking to another; without it, inside the cluster everything talks to everything.
- Identity: Entra ID, RBAC and workload identity
With --enable-aad --enable-azure-rbac, who gets into the cluster is decided by Microsoft Entra ID and what they can do is decided by Azure RBAC, using the same groups from module 4:
CLUSTER_ID=$(az aks show -g rg-contoso-reservas-pro -n aks-contoso-operaciones --query id -o tsv)
# Infrastructure: full cluster administration
az role assignment create --role "Azure Kubernetes Service RBAC Cluster Admin" \
--assignee-object-id $(az ad group show -g Contoso-Infraestructura --query id -o tsv) \
--assignee-principal-type Group --scope $CLUSTER_ID
# Development: write access only inside THEIR namespace
az role assignment create --role "Azure Kubernetes Service RBAC Writer" \
--assignee-object-id $(az ad group show -g Contoso-Desarrollo --query id -o tsv) \
--assignee-principal-type Group --scope "$CLUSTER_ID/namespaces/operaciones-vuelo"Workload identity is the piece that removes secrets from inside the cluster. A Kubernetes service account is federated with id-contoso-api-pro: the pod receives a token signed by the cluster's OIDC issuer, exchanges it for an Entra ID token and reaches kv-contoso-pro and db-reservas with DefaultAzureCredential, the same code as in 04-02, with no key at all.
# Federate the namespace's service account with the managed identity
az identity federated-credential create \
--name fed-operaciones --identity-name id-contoso-api-pro \
--resource-group rg-contoso-seguridad-pro \
--issuer $(az aks show -g rg-contoso-reservas-pro -n aks-contoso-operaciones \
--query oidcIssuerProfile.issuerUrl -o tsv) \
--subject system:serviceaccount:operaciones-vuelo:sa-operaciones \
--audience api://AzureADTokenExchange
- Deploying the application with manifests and
kubectl
kubectlBefore the deployment you need the sa-operaciones service account in the operaciones-vuelo namespace, annotated with azure.workload.identity/client-id pointing at the client ID of id-contoso-api-pro. It is the in-cluster counterpart of the federated credential above.
apiVersion: apps/v1
kind: Deployment
metadata: { name: panel-operaciones, namespace: operaciones-vuelo }
spec:
replicas: 3
selector: { matchLabels: { app: panel-operaciones } }
template:
metadata:
labels:
app: panel-operaciones
azure.workload.identity/use: "true" # injects the federated token
spec:
serviceAccountName: sa-operaciones
containers:
- name: panel
image: acrcontosopro.azurecr.io/panel-operaciones:4821
ports: [ { containerPort: 8080 } ]
resources: # section 8 explains why
requests: { cpu: "250m", memory: "256Mi" }
limits: { cpu: "1000m", memory: "512Mi" }
readinessProbe: { httpGet: { path: /salud, port: 8080 } } # ready for traffic
livenessProbe: { httpGet: { path: /salud, port: 8080 } } # alive; if not, restart
topologySpreadConstraints: # spreads the 3 replicas across the 3 zones
- { maxSkew: 1, topologyKey: topology.kubernetes.io/zone,
whenUnsatisfiable: DoNotSchedule,
labelSelector: { matchLabels: { app: panel-operaciones } } }
---
apiVersion: v1
kind: Service
metadata: { name: svc-panel-operaciones, namespace: operaciones-vuelo }
spec:
type: ClusterIP # internal; the ingress is what publishes it
selector: { app: panel-operaciones }
ports: [ { port: 80, targetPort: 8080 } ]
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: { name: ing-operaciones, namespace: operaciones-vuelo }
spec:
ingressClassName: webapprouting.kubernetes.azure.com
rules:
- host: operaciones.contosoairlines.example
http:
paths:
- { path: /, pathType: Prefix,
backend: { service: { name: svc-panel-operaciones, port: { number: 80 } } } }
tls:
- hosts: [ operaciones.contosoairlines.example ]
secretName: tls-operaciones # certificate synchronized from Key VaultField by field, what is not obvious:
- The deployment's
selector.matchLabelsand the template'slabelsmust match: that is the link between the deployment and its pods, and misaligning them leaves the deployment with no replicas.serviceAccountNameplus theazure.workload.identity/uselabel are what activate the federation from section 5. - The image carries the tag
4821, the build identifier from the pipeline (05-03), neverlatest. readinessProbeversuslivenessProbe: the first controls whether the pod enters the load balancing; the second whether it gets restarted. Confusing them produces cascading restarts under load. AndtopologySpreadConstraintsforces the three replicas to be spread across the three zones: without it, the scheduler can put all three on the same node.type: ClusterIP: the service does not publish itself. UsingLoadBalancerper service creates a public IP for each one and multiplies both cost and exposed surface.
Essential kubectl: kubectl apply -f manifiestos/ applies; kubectl get pods -n operaciones-vuelo -o wide lists with node and IP; kubectl describe pod <name> gives you the events, which is always where the cause of the failure is; kubectl logs -f <pod> follows the logs; kubectl rollout status deploy/panel-operaciones waits for the rollout and kubectl rollout undo reverts it; kubectl top pods shows real consumption, essential for tuning section 8.
- Managed ingress and certificates
Installing and maintaining an ingress controller by hand is recurring work. The application routing add-on deploys a managed NGINX and integrates it with DNS and Key Vault:
az aks approuting enable -g rg-contoso-reservas-pro -n aks-contoso-operaciones \
--enable-kv --attach-kv $(az keyvault show -n kv-contoso-pro --query id -o tsv)With that, the certificate for operaciones.contosoairlines.example lives in kv-contoso-pro, is synchronized as a Kubernetes Secret and renews itself without intervention. The certificate is never copied into a repository or a manifest.
- Scaling, requests and limits
Three scalers that are constantly confused:
| Scaler | What it does | Signal |
|---|---|---|
| Horizontal pod autoscaler (HPA) | Adds or removes replicas | CPU, memory or a custom metric |
| Cluster autoscaler | Adds or removes nodes | Pending pods that do not fit |
| Virtual nodes | Schedules pods on ACI, with no node | Immediate bursts, without starting machines |
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: hpa-panel, namespace: operaciones-vuelo }
spec:
scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: panel-operaciones }
minReplicas: 3
maxReplicas: 20
metrics:
- { type: Resource,
resource: { name: cpu, target: { type: Utilization, averageUtilization: 70 } } }The first two scalers work as a chain: the HPA asks for more replicas, they do not fit, they stay pending and the cluster autoscaler starts nodes. And here is the key point of the whole lesson: the HPA calculates the usage percentage against the request (requests), and the scheduler decides where a pod fits by looking at its request. With no requests there is no percentage to calculate and no information to schedule with.
Requests and limits are the number one cause of unstable clusters. With no requests, the scheduler thinks the pod consumes nothing and piles pods onto a node until it is exhausted. With no memory limits, a leak in one pod eats the node's memory and the kernel starts killing processes: healthy pods with nothing to do with the problem go down. With CPU limits set too low, the pod is throttled and latency shoots up without CPU looking high at all.
The practical rule: set requests at the 50th-percentile consumption measured with kubectl top, and limits at around double that. Back it up with ResourceQuota and LimitRange in the namespace so that no manifest without limits ever gets applied.
- Upgrades, disruptions and maintenance
Kubernetes ships versions at a good pace and AKS supports only a few of them. Upgrading is not optional; it is a calendar task.
az aks get-upgrades -g rg-contoso-reservas-pro -n aks-contoso-operaciones -o table
az aks upgrade -g rg-contoso-reservas-pro -n aks-contoso-operaciones \
--kubernetes-version 1.31.1 --control-plane-only # the plane first
az aks nodepool upgrade -g rg-contoso-reservas-pro --cluster-name aks-contoso-operaciones \
-n aplicaciones --kubernetes-version 1.31.1 # then each poolAlways upgrade the control plane first and the node pools afterwards, one at a time, and from one minor version to the next, with no jumps. Nodes are replaced by cordoning and draining, and that is where the pod disruption budget comes in, preventing the drain from taking a service below a minimum:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata: { name: pdb-panel, namespace: operaciones-vuelo }
spec:
minAvailable: 2 # the drain never leaves fewer than 2 replicas
selector: { matchLabels: { app: panel-operaciones } }Without it, a drain can take all three replicas at once and the operations dashboard disappears during the upgrade. Round it out with a planned maintenance window (az aks maintenanceconfiguration add) so that automatic node OS upgrades do not land in the check-in rush hour.
- Storage, observability, Helm and cost
A pod's disk is ephemeral. To persist, you declare a persistent volume claim against a storage class:
| Class | Backing | Access | Use at Contoso |
|---|---|---|---|
managed-csi (and -premium) |
Azure Disk | A single node | Data for a single pod; the Premium variant for demanding I/O |
azurefile-csi |
Azure Files (SMB/NFS) | Several nodes at once | Files shared between replicas |
The decisive distinction is the access mode: an Azure Disk is mounted by a single node, so it is no use for three replicas spread across zones; for that you need Azure Files. And by default the reclaim policy is Delete: deleting the claim makes the disk and the data disappear. In production, Retain.
Observability is solved with Container Insights, already enabled in the az aks create against log-contoso-pro: node and pod metrics, container and control plane logs, all queryable with KQL. How to exploit them is module 7 (07-01 and 07-02); here it is enough to leave it switched on from the start, because nobody enables it in time once the cluster is already failing.
Helm, GitOps and realistic cost
Helm is the Kubernetes package manager: it packages a set of manifests into a chart with parameterized values, so that deploying to desarrollo and to produccion is the same chart with a different values file; it is to manifests what Bicep modules are to templates (05-06). GitOps with Flux is the natural next step: instead of the pipeline pushing with kubectl apply, an agent inside the cluster watches the contoso-infra repository and reconciles the cluster towards what Git says; the repository becomes the single source of truth and configuration drift corrects itself. AKS offers it as a managed extension.
Realistic cost. A production cluster like Contoso's, with 3 Standard_D4s_v5 system nodes and 2 to 12 Standard_D8s_v5 application nodes, plus the Standard tier, disks, load balancer and log ingestion, comes in at the order of several thousand euros a month, and Log Analytics ingestion surprises people more than anyone expects. How to bring it down:
- Spot instances (
az aks nodepool add --priority Spot --eviction-policy Delete --spot-max-price -1) in a dedicated pool for interruption-tolerant workloads — batch jobs, testing: up to 80-90% less, in exchange for an eviction with two minutes' notice. - Scaling user pools to zero with
--min-count 0, and stopping the development cluster withaz aks stop/az aks start: a stopped cluster does not bill for nodes. Automate it overnight and at weekends with Azure Automation (07-04). - Tuning
requeststo what is genuinely consumed: inflated requests force the autoscaler to start half-empty nodes. It is the least visible saving and often the biggest.
Common Mistakes and Tips
- Adopting AKS without needing it: if Container Apps covers the case, AKS only adds bills and work. And deploying with no
requestsorlimits, the number one cause of unstable clusters; enforce it withLimitRange. - Choosing Azure CNI without doing the IP arithmetic. The subnet runs out and expanding it forces you to rebuild the cluster. Use CNI Overlay.
- Mixing application workloads into the system pool. A runaway pod takes down CoreDNS and the cluster with it.
- Storing secrets as Kubernetes
Secrets (base64 only) or putting aLoadBalancerServiceon each microservice (twelve public IPs). Workload identity againstkv-contoso-pro, and a single ingress with host-based routing. - Leaving the cluster un-upgraded: versions fall out of support and the accumulated upgrade becomes risky. Quarterly calendar.
- Tip:
kubectl describe podbefore anything else. 90% of failures (ImagePullBackOff,CrashLoopBackOff,Pendingfor lack of resources) are explained in its events section. And apply network policies from the start: retrofitting them into a production cluster is painful.
Exercises
Exercise 1. An operations microservice stays in Pending state and the cluster autoscaler does not start any nodes. Its manifest asks for requests: { cpu: "8000m", memory: "32Gi" } and the aplicaciones pool uses Standard_D8s_v5 (8 vCPU, 32 GiB).
- Explain why the pod will never be scheduled and why the cluster autoscaler does not fix it by adding nodes.
- Give two different solutions and say which one you would choose.
Exercise 2. Design the cluster for the "Contoso Miles" platform: six microservices, daytime traffic and almost none at night, plus a nightly points recalculation process that tolerates interruptions.
- Define the node pools with their mode, size, zones and autoscaler bounds.
- Justify the use of spot instances and their risks, state the mandatory tags for the secondary project and two additional cost-saving measures.
Exercise 3. A pod has to read a secret from kv-contoso-pro and query db-reservas.
- List the steps to achieve that with no credential in the cluster, and explain the relationship between the OIDC issuer, the service account and
id-contoso-api-pro. - Why is it better than mounting a Kubernetes
Secretwith the connection string?
Solutions
Solution 1:
- Because the request consumes the whole node, and the operating system, the kubelet and the system add-ons already reserve a share: the allocatable capacity of a
Standard_D8s_v5is less than 8 vCPU and 32 GiB, so no node of that size has room. The autoscaler only starts nodes if the pod would fit on a new node in the pool; since it does not fit, it concludes that adding nodes is useless and does nothing. That is correct behavior, even if the silence is confusing. - (a) Reduce the request to what it genuinely consumes, measured with
kubectl top— 4 vCPU and 16 GiB, for example. (b) Create a node pool with larger machines, of theStandard_E16s_v5kind, and steer the pod there withnodeSelector. I would go for (a) first, because the request is almost always inflated "just in case"; (b) only if the measurement confirms that the workload genuinely needs that size.
Solution 2:
- A
sistemapool in System mode, 2Standard_D2s_v5nodes, zones 1-2-3, autoscaler from 2 to 3. Anaplicacionespool in User mode,Standard_D4s_v5, zones 1-2-3, autoscaler from 2 to 8 during the day. Alotespool in User mode with--priority Spot,Standard_D8s_v5, autoscaler from 0 to 6, with its corresponding taint so that only the nightly process gets scheduled there. - The points recalculation is idempotent, resumable and has no user waiting on it: if Azure evicts a node with two minutes' notice, the job is rescheduled and only time is lost, in exchange for an enormous saving. The real risk is using spot instances for online services, where an eviction translates into errors for the user; that is why the pool is separate and tainted. Tags:
entorno,proyecto=contoso-millas,centro-coste=CC-2077andpropietario. Additional savings: scale thelotespool to zero outside the nightly window and stop the development cluster withaz aks stopfrom a runbook overnight and at weekends.
Solution 3:
- (a) Create the cluster with
--enable-oidc-issuer --enable-workload-identity. (b) Create thesa-operacionesservice account inoperaciones-vuelo, annotated with the client ID ofid-contoso-api-pro. (c) Create the federated credential withaz identity federated-credential createand the subjectsystem:serviceaccount:operaciones-vuelo:sa-operaciones. (d) Giveid-contoso-api-prothe Key Vault Secrets User role onkv-contoso-proand create the external user indb-reservas. (e) In the pod,serviceAccountNameand theazure.workload.identity/use: "true"label, and in the code,DefaultAzureCredential. As for the relationship: the cluster's OIDC issuer signs the service account's token and the federated credential declares to Entra ID that that specific issuer and that specific subject may obtain tokens forid-contoso-api-pro; the trust is cryptographic, not a shared password. - Because a Kubernetes
Secretis base64-encoded, not encrypted: anyone who can read it in the namespace, or who gets hold of an etcd backup, reads it in the clear. On top of that it has to be rotated by hand in every cluster. With workload identity the secret does not exist: there are short-lived tokens issued and revocable from Entra ID, with traceability in the sign-in logs.
Conclusion
Kubernetes stops being a word and becomes a tool with a criterion for use. You know when it is justified and when it is over-engineering, and you have seen Contoso adopt it only for the flight operations platform while the availability engine stays quite happily on Container Apps. You handle the essential concepts — control plane and nodes, pod, deployment, replica, service, ingress, namespace, ConfigMap and Secret — and you understand the reconciliation loop that holds them up. You are clear about the responsibility boundary: the control plane is free, the nodes are paid for, and upgrades, limits and policies remain yours.
You have created aks-contoso-operaciones with separate system and user pools, availability zones, cluster autoscaler, CNI Overlay so as not to exhaust the subnet, network policy, Entra ID integration and Azure RBAC per namespace, image pulls from acrcontosopro with --attach-acr, and workload identity that gives pods access to kv-contoso-pro and db-reservas without a single secret. You have deployed with manifests explained field by field, published with the application routing add-on and Key Vault certificates, and you know how to use kubectl to diagnose. You have mastered the three scalers and, above all, why the absence of requests and limits is the number one cause of unstable clusters. You know how to upgrade in the right order while protecting availability with disruption budgets and maintenance windows, how to persist with disks versus Azure Files depending on the access mode, and how to leave Container Insights on from minute one. And you know the maturity path — Helm, GitOps with Flux — and the real cost with its levers: spot instances, pools that scale to zero, stopping the development cluster and tuning requests.
Contoso now has two ways of running its own code and a reasonable doubt: for many tasks, keeping something running is absurd. Generating the PDF of a boarding pass takes two seconds and happens when a booking is confirmed; synchronizing the fare catalog happens when a document changes in cosmos-contoso-tarifas-pro. For that you do not want a container waiting or a pod switched on, you want the code to run when something happens and not to exist the rest of the time. That is serverless computing, and the next lesson, Azure Functions, takes it in detail: triggers and bindings, hosting plans, Contoso's two real functions, Durable Functions for orchestrating check-in, and the hard lesson nobody gets to skip — idempotency.
Azure Course
Module 1: Introduction to Azure
- What Is Azure?
- Service Models, Regions and Availability Zones
- Creating and Setting Up Your Azure Account
- A Tour of the Azure Portal
- Azure Resource Manager: Subscriptions, Resource Groups and Tags
- Azure CLI, PowerShell and Cloud Shell
Module 2: Core Azure Services
- Azure Virtual Machines
- Compute Scaling and High Availability
- Azure App Service
- Azure Storage: Blobs, Files, Queues and Tables
- Azure Networking: Virtual Networks, Subnets and NSGs
- Hybrid Connectivity and Global Delivery
Module 3: Azure Databases
- Choosing the Right Data Service
- Azure SQL Database
- Azure Cosmos DB
- Azure Database for MySQL
- Azure Database for PostgreSQL
- Data Analytics: Data Lake, Data Factory and Synapse
Module 4: Security in Azure
- Microsoft Entra ID and Identity Management
- RBAC and Managed Identities
- Azure Key Vault
- DDoS Protection and Web Application Firewall
- Microsoft Defender for Cloud
- Governance and Compliance with Azure Policy
Module 5: Azure DevOps
- Introduction to Azure DevOps
- Azure Repos
- Azure Pipelines: Continuous Integration
- Continuous Deployment with Environments and Approvals
- Azure Artifacts
- Infrastructure as Code with Bicep
Module 6: Advanced Azure Services
- Containers in Azure: Container Registry and Container Apps
- Azure Kubernetes Service (AKS)
- Azure Functions
- Azure Logic Apps
- Messaging and Events: Service Bus, Event Grid and Event Hubs
- Azure AI Services
Module 7: Monitoring and Management
- Azure Monitor: Metrics, Alerts and Dashboards
- Log Analytics and KQL Queries
- Application Insights
- Azure Automation and Runbooks
- Backup and Disaster Recovery
Module 8: Cost Management and Optimization
- Pricing Calculator and Cost Estimation
- Azure Cost Management: Analysis, Budgets and Alerts
- Reservations, Savings Plans and Azure Hybrid Benefit
- Azure Advisor
- Optimization Strategies and FinOps Culture
