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

  1. Why a catalog of mistakes
  2. Cost mistakes
  3. Security mistakes
  4. Architecture mistakes
  5. Operations mistakes
  6. Governance and organizational mistakes
  7. Mistakes with data
  8. The four mistakes Contoso did make
  9. Warning signs
  10. Common Mistakes and Tips
  11. Exercises
  12. Conclusion

  1. 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"]

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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.

  1. 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

  1. 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

Module 2: Core Azure Services

Module 3: Azure Databases

Module 4: Security in Azure

Module 5: Azure DevOps

Module 6: Advanced Azure Services

Module 7: Monitoring and Management

Module 8: Cost Management and Optimization

Module 9: Case Studies and Best Practices

© Copyright 2026. All rights reserved