The previous lesson gave you the framework that says how an architecture ought to be built. This one covers the other half of the craft, which is learned far more slowly and almost always by paying for it: how they get built badly. Not with abstract examples, but with the concrete catalog of mistakes that show up again and again in organizations of every size, told with their symptom, with what it costs to correct them once they are entrenched, and with the prevention that would have avoided them for a fraction of that price.
There is an asymmetry that justifies the whole lesson: almost all of these mistakes are cheap to prevent and expensive to fix. Tagging from day one is free; retro-tagging two hundred resources is weeks of work. Moving a secret into Key Vault before you write the first line is half an hour; doing it after it has spent six months in the repository history means rotating it, auditing accesses and being unable to prove nobody used it.
The lesson works through six families — cost, security, architecture, operations, governance and data — devotes a section to the four mistakes the Contoso team did make during the course and how it spotted them, and closes with the warning signs that anticipate each family before the problem is visible on the bill or in an incident.
Reminder: the euro figures are illustrative and fictitious, and they show orders of magnitude, not real prices.
Contents
- Why a catalog of mistakes
- Cost mistakes
- Security mistakes
- Architecture mistakes
- Operations mistakes
- Governance and organizational mistakes
- Mistakes with data
- The four mistakes Contoso did make
- Warning signs
- Common Mistakes and Tips
- Exercises
- Conclusion
- Why a catalog of mistakes
Three reasons why these mistakes repeat themselves in organizations that already know the theory:
- The cloud punishes late. Creating an oversized machine does not fail: it works perfectly and the bill arrives thirty days later. What does not throw an error immediately does not get corrected.
- The urgent displaces the important. Nobody plans to leave a secret in the code: it gets left there "just for Thursday's demo" and is never looked at again.
- The cost of the mistake grows non-linearly. A naming convention is trivial with ten resources, awkward with a hundred and unmanageable with five hundred.
- Nobody sees the mistake from the inside. The team that built the system has normalized its quirks; that is why cross-team reviews and catalogs like this one find things that have been in plain sight for years.
That is why the pattern in the tables below is always the same: mistake → symptom → cost of fixing it late → prevention. The column most worth reading is the third.
The multiplier depends almost entirely on when it is detected:
| Point of detection | Relative cost to correct | Example with "secret in the code" |
|---|---|---|
| In the design review | x1 | You decide to use a managed identity: zero extra work |
| In the pull request | x2 | A reviewer flags it; it is changed before merging |
| Before production | x10 | Configuration has to be rewritten and retested |
| Already in production | x50 | Rotate, redeploy, coordinate a window and audit accesses |
| After an incident | x500 | All of the above plus notification, forensics and regulatory exposure |
The operational conclusion is not "we need to be more careful", which is not actionable: it is to move detection up the table with automatic mechanisms — policies, templates, pipeline scanning, design checklists.
flowchart LR
A["Quick decision<br/>today"] --> B["It works"]
B --> C["Nobody reviews it"]
C --> D["It gets replicated<br/>across 20 resources"]
D --> E["Correction cost<br/>x10 or x100"]
B -.->|"prevention:<br/>policy, template,<br/>review"| F["Fixed<br/>in minutes"]
- Cost mistakes
| Mistake | Symptom | Cost of fixing it late | Prevention |
|---|---|---|---|
| Sizing for the peak | Average CPU of 5%, the bill never comes down | Months paying 3-5 times what is needed; resizing demands a window and testing | Size for the average and autoscale for the peak |
| Orphaned resources | Disks, public IPs and NICs with no owner after migrations | Hundreds of euros a month for years; nobody dares delete without knowing whose they were | A mandatory propietario tag and a monthly Resource Graph query |
| Not tagging | The bill cannot be split across projects | Manual retro-tagging of the whole inventory, weeks of work | The hereda-centro-coste policy and mandatory tags from day one |
| Reserving before stabilizing | A 3-year commitment on the wrong size | You pay for the mistake until the term ends; exchanges have limits | Optimize first, commit afterwards, and start with 1 year |
| Ignoring data transfer out | The network line item growing with no explanation | Redesigning cross-region flows with production already running | Keep traffic inside the region, cache at the edge, review the network line item |
| Uncontrolled log ingestion | Observability as the third biggest item on the bill | Panic cuts that leave the team blind | Filter at source, Basic plan for high volume, retention per table |
| Non-production environments on 24x7 | Development costs as much as production | Savings lost, month after month, with nothing in return | A shutdown runbook driven by the horario tag |
The most expensive one on the list is none of them in particular: it is not having a budget with an alert, because that turns any of the above into a problem discovered a quarter too late.
It is worth seeing the asymmetry with illustrative numbers. An orphaned 512 GB disk costs on the order of €40/month: it goes unnoticed. Twenty orphaned disks accumulated over two years of migrations are about €19,000 spent on nothing, and by that point nobody knows whose each one was, so deleting them requires an investigation that costs more hours than the first month's saving. The mistake was not the disk: it was having no owner tag and never looking. Prevention would have cost one policy and a ten-line monthly query.
- Security mistakes
| Mistake | Symptom | Cost of fixing it late | Prevention |
|---|---|---|---|
| Keys and connection strings in the code | Secrets visible in the repository and its history | Rotating everything, auditing accesses and being unable to prove it was never used | Managed identities; Key Vault; secret scanning in the pipeline |
| Owner for everybody | Anybody can delete anything | A permissions audit and awkward conversations; one irreversible accidental deletion | Minimal roles per group, PIM for anything privileged |
| Public storage accounts | A blob reachable without authentication | Breach notification, a potential fine, reputational damage | The sin-blobs-publicos policy from the start |
| Not rotating secrets | Years-old keys in production | Nobody knows what breaks when you rotate, so it never gets rotated | Automated rotation and mandatory expiry in Key Vault |
| Optional MFA | One leaked password is enough to get in | Identity compromise; the investigation costs more than the attack | Mandatory MFA through conditional access, no exceptions |
| RDP/SSH open to the internet | Thousands of daily access attempts in the logs | A compromised machine, mining or encryption, and a full rebuild | NSGs with no management ports; bastion-contoso-pro |
| Ignoring Defender's recommendations | A dashboard in red that nobody has looked at for months | The incident arrives by exactly the route the dashboard was pointing at | A monthly review with an owner and exclusions justified in writing |
| Flat, unsegmented networks | Everything can reach everything inside the virtual network | Lateral movement after a minor compromise | Subnets by function, NSGs, private endpoints |
A nuance about the first, which is the most frequent: removing the secret from the code does not remove it from the history. If it was ever published, it has to be considered compromised and rotated, even though the commit that deleted it looks like it solved the problem.
And a nuance about the sixth, which is the one producing the most serious incidents with the least sophistication: exposed management ports are not found by an attacker, they are found by an automated scanner. You do not need to be an interesting target or hold valuable data; a public IP address with port 3389 or 22 open is enough. That is why the right mitigation is never "use a longer password" but removing the exposure: access through Bastion, just-in-time access or a private network, so that the port simply does not exist from the internet.
- Architecture mistakes
| Mistake | Symptom | Cost of fixing it late | Prevention |
|---|---|---|---|
| Eternal lift-and-shift | The same machines as always, now in Azure and more expensive | You pay for the cloud without a single one of its advantages, indefinitely | Rehost as the first step, with a modernization plan and a date |
| A stateful monolith that will not scale | Adding instances breaks the user session | Rewriting state management with production running | State outside the process: cache, database, storage |
| A single point of failure | One instance, one zone, one replica | Total outage the day it fails; the emergency mitigation is always worse | Redundancy at the right layer from the design stage |
| Synchronous coupling between services | One slow service takes down the five in front of it | Introducing queues in production means redesigning the flow | A queue or an event whenever the consumer does not need to answer |
| Choosing Kubernetes because it is fashionable | A cluster for two containers and nobody who knows how to run it | Months of cost and complexity; migrating off it is another project | Start with App Service or Container Apps; AKS when the problem calls for it |
| Not designing for failure | No retries, no timeouts, no circuit breakers | Cascading failures and incidents that last hours | Resilience patterns in the shared library, not in each service |
| Over-architecting | Twenty services for a product that has no customers yet | Disproportionate operational cost and an overwhelmed team | Start simple; every new service has to justify its operation |
The last two look like opposites and are the same mistake: not fitting the architecture to the real problem. One errs by omission and the other by excess, and both are detected with the same question — what concrete, measured problem does this piece solve?
Synchronous coupling deserves a drawing, because it is the architecture mistake that causes the most incidents and the easiest one to miss on a badly drawn diagram:
flowchart LR
subgraph BAD["Coupled: the failure propagates"]
W1["Sale"] --> P1["Payments"] --> T1["Boarding passes"] --> M1["Email"]
M1 -.->|"if it takes 30 s"| W1
end
subgraph GOOD["Decoupled: the failure is contained"]
W2["Sale"] --> P2["Payments"]
W2 --> Q["Queue or topic"]
Q --> T2["Boarding passes"]
Q --> FA["Billing"]
end
In the coupled version, a slow email service blocks the sale: the customer gets an error when buying because of a component that did not even need to answer. It is exactly the reason Contoso put sb-contoso-pro between booking confirmation and everything that happens afterwards. The rule is simple and it is applied at design time, not later: if the caller does not need the answer in order to reply to the user, it must not wait for it.
- Operations mistakes
| Mistake | Symptom | Cost of fixing it late | Prevention |
|---|---|---|---|
| Not monitoring | The customer discovers the incidents | Reputation, and a blind reconstruction of what happened | Application Insights and alerts before the first sale |
| Alerting on everything | 200 emails a day that nobody opens | The important alert is lost in the noise: worse than not alerting | Few alerts, actionable, with an owner and a reviewed threshold |
| Not testing the backups | Backups "taken" that nobody has ever restored | Finding out on disaster day that the backup is useless | A verified restore every half-year, in the drill |
| Not documenting | The knowledge lives in one person | Every absence is an operational risk; turnover costs months | Blueprint, decisions and operational runbooks in the repository |
| The manual Friday deployment | An incident on Saturday with nobody available | A lost weekend and damaged trust | A pipeline with a slot, approval and a deployment window |
| No rollback plan | The only way out is to fix forward under pressure | Incidents that last hours instead of minutes | A preproduccion slot, progressive deployment, tested rollback |
| Automating with no safeguards | A badly filtered runbook touches what it should not | Switching production off by mistake, during working hours | Filter by tag, dry run and a limited scope |
Of all of them, the second is the most treacherous because it looks like diligence. A team that alerts on everything believes it is being careful, but the real effect is the opposite: when two hundred notifications arrive a day, the human brain learns to ignore them, and the day the important one arrives nobody reads it any more. Alert fatigue is not fixed by telling people to pay more attention: it is fixed by deleting alerts. A useful criterion for deciding which ones survive: an alert must describe a symptom the user notices and carry a concrete action somebody can take at three in the morning. If it fails either test, it is a dashboard, not an alert.
A second criterion, about the Friday deployment: the problem is not the day, it is the asymmetry between the probability of failure and the availability of whoever can fix it. With rollback tested and measured in seconds — a slot, a progressive deployment — deploying on a Friday stops being dangerous. Banning Fridays is a sticking plaster; the rollback plan is the cure.
- Governance and organizational mistakes
| Mistake | Symptom | Cost of fixing it late | Prevention |
|---|---|---|---|
| No naming convention | test2, vm-final-final, rg-pruebas-juan |
Renaming means recreating many resources; usually it never happens | A written convention with examples in the Bicep template |
| No policy | Every team creates what it wants where it wants | A mass cleanup and conflict with teams that already depend on it | An initiative assigned at the root management group |
| A single subscription for everything | Production and testing mixed together with no limits | Separating later means moving resources and reconfiguring networks | Separate production from non-production before you grow |
| "Temporary" permissions forever | Last summer's intern is still a Contributor | A manual audit of hundreds of assignments | PIM with expiry and periodic access reviews |
| Nobody owning cost | "That's IT's job"; nobody decides | Spending grows unchecked until finance stops it dead | A cost center per tag and a monthly review with owners |
| One team as the bottleneck | Every deployment waits on infrastructure | Frustration, shortcuts and resources created outside the process | A platform with templates and self-service inside guardrails |
The last two are connected and they explain why governance fails even when it exists. If creating a legitimate resource means opening a ticket and waiting five days, people find a way around it: they use the test subscription, they ask for temporary permissions nobody ever removes, or they hand-build what should have been in the template. Governance that only forbids generates evasion; governance that works forbids the dangerous and makes the correct easy, with Bicep templates that already come with the tags, the network and the diagnostics in place. Put another way: if the correct path is not also the easy path, the policy will lose against the project schedule.
- Mistakes with data
| Mistake | Symptom | Cost of fixing it late | Prevention |
|---|---|---|---|
| Choosing the engine out of habit | Everything on the engine the team already knew | A data migration in production, the most expensive project there is | Choose by access pattern, as in module 3 |
| A bad partition key | One hot partition and request throttling | In Cosmos DB it cannot be changed: you have to recreate the container and migrate | High cardinality, aligned with the most frequent query |
| Not planning for growth | Storage fills up or queries degrade | Emergency intervention with the service already degraded | Volume projection and an alert on the trend |
| No data lifecycle | Everything kept forever in the hot tier | A storage bill that grows without end | Tier and expiry rules from the very first container |
| Personal data with no legal basis | Exports to spreadsheets and test environments with real data | Serious regulatory exposure, on top of the technical cost | Anonymize in non-production; validate with the legal team |
| No logical backup | Infrastructure-level backup, but a logical deletion replicates | Unrecoverable data loss despite "having backups" | Retention with point-in-time restore and soft delete |
Two of these mistakes have a property the others do not share: in practice they are irreversible. Changing the partition key of a Cosmos DB container is not a configuration operation, it is creating a new container and migrating the data with the application running; and choosing the wrong engine is corrected with a data migration in production, which is the kind of project that eats quarters. Everything else in this lesson is fixed with money and time; these two are fixed with a project. That is why they are the two decisions that most deserve a formal design review before the first line is written, with the concrete question on the table: what will the most frequent query be two years from now, and does this design serve it well?
Important warning: the processing of personal data is subject to GDPR and to sector-specific regulation. Nothing in this course constitutes legal advice: any decision about exporting, retaining, anonymizing or transferring personal data must be reviewed by the organization's legal or compliance team before it is implemented.
- The four mistakes Contoso did make
No team learns this by reading it. Neither did Contoso: these are the real mistakes in the platform you have built, along with how they were spotted.
| Mistake | What happened | How it was spotted | Correction |
|---|---|---|---|
| The doubled bill | The naive initial estimate was €8,500/month; the real bill for the first quarter came in at ~€17,500/month | Nuria compared the estimate against the bill at quarter end; nobody had an alert configured | Estimate redone at €17,450 with a 15% buffer, budget with alerts at 80% actual and 100% forecast |
| The oversized VM | vm-motor-disponibilidad-dev was born as a quick experiment and sat for a year at 3% CPU |
Advisor flagged it for underutilization; the monthly report brought it into the open | Resized and the workload moved to ca-motor-disponibilidad, with scale to zero |
| The missing tags | The first resources were created with no centro-coste or propietario; the bill could not be split |
On the first attempt at allocation by project, a third of the spend came out as "unassigned" | Manual retro-tagging and the hereda-centro-coste and mandatory-tag policies on mg-contoso |
| The inverted order | Resources were created before the governance hierarchy and the Bicep templates | Writing the templates after the fact surfaced differences between what was deployed and what was declared | A declarative rebuild of the environments and a new rule: nothing is created by hand in production |
It is worth adding a fifth that never became a problem because it was caught in time, and which illustrates how prevention works when it works: while preparing the first purchase of commitments, somebody proposed reserving for three years based on the sizing in place at the time. Nuria asked to wait for three months of stable usage, and the subsequent optimization brought the platform down from €17,800 to €12,550/month. Reserving earlier would have locked in for three years a size that turned out to be 29% above what was needed. The only reason it was not a mistake is that there was a written rule — optimize before committing — and somebody with the authority to invoke it.
What the four have in common: not one of them was a bad technical choice. Cosmos, SQL, App Service and Service Bus were the right pieces. What failed was the ordering and the absence of a mechanism to raise the alarm early: a budget, a monthly report, a policy, a template. It is the most transferable lesson in this module.
And one query worth keeping to hand, the one Marta runs every month to stop the third mistake coming back:
// Resources missing the mandatory tags, by resource group
resources
| where isnull(tags['centro-coste']) or isnull(tags['propietario'])
| project name, type, resourceGroup, location, tags
| summarize untagged = count(), examples = make_list(name, 5) by resourceGroup
| order by untagged desc
- Warning signs
Every family of mistakes emits signals before it turns into an incident or a bill. These are the ones worth watching:
| Family | Early warning sign | What it usually means |
|---|---|---|
| Cost | The bill grows faster than the business; there are untagged resources; nobody can explain the third line item | Waste is already piling up |
| Security | Nobody remembers the last rotation; there are "temporary" exceptions in conditional access; the Defender dashboard has looked the same for months | The posture has degraded without anybody deciding to degrade it |
| Architecture | "The thing is, if you touch that everything breaks"; nobody dares deploy module X | Coupling and a single point of failure |
| Operations | Alerts get silenced as a matter of routine; the same person always does the deployment | Dependence on heroes and noise that hides what matters |
| Governance | Resources appear that nobody claims; there are two ways of creating the same thing | Governance either does not exist or is not enforced |
| Data | Queries getting slower with no code change; spreadsheets with real data doing the rounds | Unplanned growth and regulatory risk |
There are also three cross-cutting signals, belonging to no family, that tend to precede problems in several at once:
- Fear of deploying. If the team postpones deployments or batches them into large releases "to avoid risk", the real cause is that there is no reliable rollback. It predicts long incidents.
- The indispensable person. If there is a task only one person knows how to do, that task is neither automated nor documented. It predicts operational problems as soon as there is a holiday or sick leave.
- The answer "we'll look at that later". Repeated three times about the same subject, it describes a decision taken by omission. It predicts debt in whichever pillar is being postponed.
A general rule that sums up all six: when the answer to "why is this like this?" is "I don't know" or "it's always been like that", there is debt. Not always urgent, but always real, and always cheaper to pay today than a year from now.
Common Mistakes and Tips
On how to use this catalog, which also has its own ways of going wrong:
- Using the list to point fingers. A catalog of mistakes is for prevention, not for auditing people; the moment it becomes a weapon, nobody admits to a problem again.
- Trying to fix everything at once. Prioritize by consequence and by cost of correction: the catastrophic and cheap to fix comes first.
- Confusing a mistake with a trade-off. Not having multi-region active-active is not a mistake if it is written down and decided; it is one if nobody has ever thought about it.
- Fixing the instance and not the cause. Deleting the orphaned disk does not prevent the next one; the monthly query and the mandatory tag do.
- Preventing with documentation alone. What can be prevented with a policy or a template should not depend on somebody remembering to read a guide.
- Tip: when something fails, ask "what mechanism would have caught this earlier?" instead of "who did it?". The first question produces improvements; the second, silence.
- Tip: keep a record of your own incidents and mistakes with the correction applied. It is more useful to your organization than any general list, including this one.
- Tip: review this whole catalog once a year with the team, marking each row green, amber or red. It usually throws up a surprise.
- Tip: when you join a new organization, start with four checks that fit into one morning and reveal most of the serious debt: has any backup been restored? are there secrets in the repositories? who holds permanent Owner? is there a budget with an alert? The answers sketch out the rest of the map.
Exercises
Exercise 1. A company hires you to review its Azure platform and you find: a single subscription with production and testing, three people with permanent Owner, secrets in the application configuration, no tags, no budget, backups configured but never restored, RDP open on two administration machines and a bill of €9,000/month that nobody can explain. Prioritize the interventions: rank the problems by potential consequence divided by cost of correction, justify the order and define what you would do in the first week, the first month and the first quarter.
Exercise 2. Analyze the four mistakes Contoso made and answer: for each one, what concrete mechanism — policy, alert, template, review or query — would have detected it in the first week instead of months later? Then generalize: propose the minimum set of five mechanisms you would install on day one of any new platform so that these mistakes cannot last.
Exercise 3. A team proposes migrating its application to AKS because "that way we're ready to scale". The application is a monolith with state in session, 300 internal users, no peaks, deployed today on two virtual machines. Identify every mistake from this lesson that the proposal contains or would cause, formulate the questions you would ask the team and propose the alternative you would defend, with its justification by pillar.
Solutions
Solution 1: the ordering criterion is potential consequence divided by cost of correction, not theoretical severity. First week — catastrophic and cheap: (1) restore a backup into a separate environment, because "backups never tested" is equivalent to having no backups and the check costs hours; (2) close RDP on the two machines and replace it with Bastion or just-in-time access, because an exposed management port is exploited in an automated way and closing it is immediate; (3) create a budget with alerts on the €9,000 bill, which takes ten minutes and stops blind growth; (4) switch MFA on if it is not already. First month — high impact, medium effort: (5) move the secrets into Key Vault with managed identities, starting with production, with subsequent rotation because they must be considered compromised; (6) reduce the permanent Owners to one break-glass account and move the rest to minimal roles with PIM; (7) enforce mandatory tags by policy and tag what already exists, without which you cannot begin to explain the bill; (8) review the five largest line items on the bill and hunt for orphans and underutilization with Advisor and Resource Graph. First quarter — structural: (9) separate production from non-production into two subscriptions under management groups, with the governance initiative assigned; (10) a deployment pipeline with rollback; (11) alerts and a minimum observability dashboard; (12) document the blueprint and the decisions. Justification of the order: the first week's items avoid irreversible losses — data, identity compromise — at almost zero cost; the month's items remove the most likely exposures; the quarter's items fix the structure, which is the expensive part and the one that needs coordination.
Solution 2: mechanisms that would have detected each mistake within days. The doubled bill: a budget with an alert at 80% against the €8,500 estimate would have fired a warning in the first few weeks, plus Cost Management's anomaly detection; the problem was not estimating badly — estimating badly is normal — it was having no mechanism continuously comparing estimate against reality. The oversized VM: a monthly Advisor review with an assigned owner, or a metric alert on average CPU below a threshold for 14 days; an expiry date by tag on resources created as experiments would also have been enough. The missing tags: a policy in deny mode on centro-coste and propietario at the root management group, plus the monthly Resource Graph query from section 8; the key is that the policy acts at creation time, when correcting costs nothing. The inverted order: blocking manual creation in production — write permissions only for the pipeline's service connection — turns the mistake from detectable into impossible. Minimum set of five mechanisms for day one of any platform: (1) a subscription hierarchy with a policy initiative requiring tags, restricting regions, forbidding public blobs and enforcing HTTPS; (2) a budget with alerts and anomaly detection; (3) managed identities and a secret store as the norm, with secret scanning in the pipeline; (4) infrastructure as code deployed exclusively by pipeline, with no manual write permissions in production; (5) minimum observability with tested backups: one Log Analytics workspace, three actionable alerts and a scheduled test restore. With those five, none of Contoso's four mistakes can last more than a week.
Solution 3: mistakes present or caused. Choosing Kubernetes because it is fashionable — the stated reason, "being ready to scale", describes no measured problem: 300 internal users and no peaks. A stateful monolith that will not scale: session state in memory means horizontal scaling does not work today, so AKS would solve nothing; you would pay for the cluster and still have a single usable instance. Over-architecting: operational complexity — cluster upgrades, networking, quotas, Kubernetes RBAC, its own observability — for a trivial workload. Consequent operations mistakes: nobody on the team runs Kubernetes today, so you add a point of failure whose recovery depends on knowledge that does not exist. Cost: a cluster with permanent nodes almost certainly costs more than the two current machines. Questions for the team: what measured problem does this solve — latency, unavailability, cost, lead time? What scaling is expected and on what growth data? Where does the session live today and who is going to move it out of the process? Who will run the cluster, do the upgrades and be on call? How much does the proposal cost per month against the current situation? The alternative I would defend: containerize the application and deploy it on App Service or Container Apps, after moving the session state into an external store. Justification by pillar: reliability, it genuinely allows several instances and zone redundancy with nothing to operate; operational excellence, deployment with a slot and immediate rollback, with no cluster upgrades; cost, a fraction of AKS and with scale to zero on Container Apps if the load is internal and follows office hours; performance, autoscaling sufficient for an order-of-magnitude growth; security, less surface to administer. And the decisive observation: the valuable work in the proposal — moving the session state out — is exactly the same on both paths, so it is best done first and the destination decided afterwards, with data.
Conclusion
You now have the honest catalog of what goes wrong, organized into six families and always presented with the same structure — mistake, symptom, cost of fixing it late and prevention — because the cost column is the one that convinces an organization to act early. In cost: sizing for the peak, orphans, not tagging, reserving before stabilizing, data transfer out and uncontrolled log ingestion. In security: secrets in the code, Owner for everybody, public blobs, secrets never rotated, optional MFA, open management ports and the Defender dashboard nobody looks at. In architecture: the eternal lift-and-shift, the stateful monolith, the single point of failure, synchronous coupling, Kubernetes as fashion, not designing for failure and its opposite twin, over-architecting. In operations: not monitoring, alerting on everything, not testing the backups, not documenting, the manual Friday deployment and the absence of a rollback plan. In governance: no conventions, no policy, a single subscription, eternal temporary permissions and nobody owning cost. And in data: the engine chosen out of habit, the partition key that in Cosmos DB can no longer be changed, unplanned growth, the absence of a lifecycle and personal data processed with no legal basis — with the warning that this is validated by the legal team, not the technical one.
You have seen the four mistakes Contoso did make — the bill that doubled from €8,500 to €17,500, the development machine at 3% for a year, the tags that arrived late and the inverted order between resources and governance — with the exact way they were spotted and what they have in common: not one of them was a bad technical choice; it was a lack of mechanism and of ordering. And you take away the warning signs by family, with the rule that sums them up: when the answer to "why is this like this?" is "it's always been like that", there is debt waiting.
One matter remains that this module has been circling and that is not technical: Contoso still has systems in Barcelona. Legacy billing, the local directory and fleet maintenance are still in a datacenter whose contract is about to expire, and moving them is not an infrastructure project: it is an organizational change. The next lesson tackles how you migrate an entire organization with the Cloud Adoption Framework — strategy, plan, ready, adopt and govern — with Azure Migrate for the inventory, the six migration strategies, landing zones, waves and their cutover window, data migration, rollback, change management and datacenter decommissioning with its hidden costs.
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
