Back to blog

What we'd review in the first 48 hours of inheriting an Azure environment

A senior Azure assessment does not start by replacing tools. It starts by identifying what sustains production, where risk sits and what can recover.

You inherit an Azure environment that has been growing for two or three years. There are dozens, perhaps hundreds, of resources. Terraform exists, although nobody can say exactly what it controls. Several pipelines run, Azure Monitor is enabled, backup jobs are green and Defender for Cloud has a substantial recommendation queue. The application works. The invoice arrives every month.

Nothing appears to be on fire. Yet one essential question is unanswered: what would actually happen if a critical component failed tomorrow?

We would not spend the first 48 hours modernising the platform, migrating services or deploying Kubernetes. Nor would we remediate whichever warning happens to be at the top of a portal. Our initial job is to build a sufficiently accurate map of the production system: criticality, dependencies, exposure, operability and risk.

An initial Azure infrastructure assessment is not a contest to produce one hundred findings. It should establish what sustains production, who can change it, what is public, what can be rebuilt, what can be recovered, which signals exist during an incident and where money is going. Understand first, prioritise second, change third.

Before opening Azure: understand what we operate

A technical assessment should not begin by browsing Azure Portal at random. We first speak to the people who build, operate and own the product. Which services generate revenue? Which customers depend on them? What SLOs or contractual commitments exist? Which environments contain real data? When does demand peak? We also ask about maintenance windows, regulatory obligations, external dependencies and recent material incidents.

The reason is simple: an Azure resource is not inherently critical; it inherits criticality from the service it supports. A small, neglected VM might matter more than an entire cluster if it runs the only agent processing payments or resolving internal DNS. A low-throughput Storage Account might contain the documents without which the business cannot operate.

The first worrying signal is often not a particular technology choice. It is a mismatch between the business and technical maps. If sales promises one-hour recovery while operations expects production restoration to take a day, a risk already exists even when every resource is healthy.

We do not redesign yet. We agree a short list of workloads, owners, dependencies and service objectives. That business inventory becomes the context against which every technical finding is assessed.

The first 2 hours: build the map

We start with the Microsoft Entra ID tenant: administrative identities, Global Administrators, personal accounts, guests, service accounts, MFA, Conditional Access, service principals and managed identities. Two hours cannot produce a complete identity review. It can reveal obvious risks and show us where the environment’s roots of trust sit.

We then walk through management groups, subscriptions and inherited policy. We look at production and non-production separation, subscription ownership and old subscriptions whose purpose is unclear. Running production, test and sandbox in one subscription is not automatically wrong. It does require an explanation of how isolation, quotas, cost and access control are handled.

Resource Groups expose part of the operating model. We look for grouping by lifecycle, workload or team; shared resources that could be removed alongside temporary components; historical groups without owners; and names that no longer describe what they contain. Imperfect taxonomy is manageable. Unpredictable lifecycle boundaries make change dangerous.

Finally, Azure Resource Graph and the repositories give us a fast inventory of compute, App Service, Functions, Container Apps or AKS; managed databases, Storage, Cosmos DB, messaging, Key Vault, networking and observability. This is not a service catalogue. We are rebuilding relationships: traffic entry, processing, persistence, external integrations and egress.

Discrepancies are particularly informative: resources nobody mentions, critical components absent from diagrams, or an environment labelled dev that receives customer traffic. We do not delete or rename them. We record the unknown and look for evidence in DNS, metrics, Activity Log, configuration and delivery pipelines.

Identity and RBAC: who can do what

In Azure, “it works because it has permission” and “it has precisely the permission it needs” are very different states. We review Owner, Contributor and User Access Administrator assignments; custom roles; scope and inheritance; direct user assignments versus groups; unused identities; and credentials approaching expiry. Where PIM exists, we verify which privileges are eligible, which remain permanently active and how activation is governed and reviewed.

Scope matters as much as role. A pipeline that only deploys one Resource Group should not be subscription-wide Contributor for convenience. It may run safely for years, but a leaked credential or modified workflow would have an unnecessarily large blast radius. The target is an identity per responsibility, the least capable role at the narrowest practical scope, and workload federation or managed identity instead of durable secrets where supported.

We also distinguish control-plane and data-plane access. Contributor on a Storage Account does not necessarily grant blob reading; a data role can expose information even if its holder barely manages resources. Custom roles containing wildcards, assignments to individuals and service principals without owners are all signs of debt.

Applying least privilege does not mean revoking production access mid-assessment and risking a release. We capture dependencies, propose the target model, test with a controlled identity and reduce permissions progressively. Moving quickly without evidence can create a different incident from the one we intended to prevent.

What is exposed to the Internet

We build a view of Public IPs, public endpoints, NSGs, service firewalls and ingress paths. We search for 0.0.0.0/0, SSH and RDP, public databases, Storage Accounts, App Services, registries, Key Vault and Azure SQL firewall rules. We then establish whether each exposure is intentional and which compensating controls exist.

Internet → Public IP → VM:22

versus

Engineer → VPN / Bastion / Zero Trust access → private network → VM

“It has a firewall” does not demonstrate isolation. A rule can admit the whole Internet, a historical exception can cover a huge range, and a Private Endpoint does not by itself disable the service’s public network access. Private Link also introduces DNS zones, routes and resolution behaviour that must work from each consuming network.

We do not recommend making everything private on principle. A public web endpoint behind appropriate authentication, WAF and DDoS protection may be exactly right. Private Endpoints add cost and operational complexity; they earn that cost where they reduce a material risk or satisfy a requirement. The finding is not “a Public IP exists”. It is “an administrative interface is public without a reason or proportionate controls”.

Where exposure is critical, the next action is small, reversible containment: narrow the source, remove an administrative port or disable public access after proving the private route. Broader network redesign follows only after that safety step.

Networking: understand it before changing it

We review VNets, address spaces, subnets, peerings, hub-and-spoke topology, VPN or ExpressRoute, Private Link, route tables, Azure Firewall, NSGs, NAT Gateway, DNS and egress. The intended diagram and observed traffic both matter.

Typical warning signs include overlapping ranges, unplanned VNets, a mesh of peerings nobody can reason about, static IP dependencies, different DNS answers depending on origin and uncontrolled outbound access. These appear to be local design choices until they block an acquisition, hybrid connection or second region.

Networking is expensive to correct because it crosses identity, applications, data and third parties. If private DNS is fragile, we do not change a zone during discovery. We document flows, inspect logs where available, test from specific locations and design a staged migration with coexistence. Every dependency path should be visible before we alter it.

Can the infrastructure be rebuilt?

The central question is intentionally uncomfortable:

If this subscription disappeared tomorrow, how much of the platform could we rebuild from Git?

We review Terraform, Bicep, ARM or Pulumi; module boundaries; versions and providers; remote backend, locking and state protection; imports, plans, drift and portal changes. We also inspect DNS, permissions, certificates, diagnostic settings, pipelines, variables and service configuration. These edges frequently remain outside the repository even when core resources are IaC-managed.

Infrastructure created with Terraform is not necessarily reproducible infrastructure. State may be inaccessible, modules may rely on manually copied values, or portal changes may never have reached code. Configuration drift is more than untidiness: it turns every plan into an argument about which system is authoritative.

We do not import an entire subscription in the first 48 hours. We classify coverage and risk, run non-destructive plans where safe and choose a representative workload to test. A brownfield Azure Terraform strategy needs phases, ownership and import criteria, not one enormous commit that nobody can review.

CI/CD: how code reaches production

We follow a real change from commit to production through GitHub Actions, Azure DevOps, GitLab CI or the existing system. We examine branch protection, reviews, environments, approvals, artefacts, image provenance, secrets, runner permissions, promotion and rollback. Is an artefact built once and promoted, or does each environment build something different?

Manual deployments, one-person scripts, static secrets, duplicated pipelines, latest images, unisolated persistent runners and portal-based infrastructure changes all deserve attention. We also ask when rollback was last performed and what it proved. A written procedure that has never run is still a hypothesis.

A green pipeline proves that the pipeline completed. It does not prove that the service is healthy.

We therefore look for smoke tests, health checks, business metrics, progressive delivery and automatic or human criteria that stop a release. If this feedback loop is absent, a first quick win may be to validate one critical transaction after deployment before undertaking a full CI/CD and DevOps redesign.

Secrets and Key Vault: reduce static credentials

We inventory secrets in Key Vault, pipeline variables, .env files, repositories, application configuration and Kubernetes Secrets where relevant. We inspect expiry, rotation, certificates, access policies versus Azure RBAC and managed identity adoption.

The goal is not merely to tick “uses Key Vault”. It is to reduce how many static credentials exist, how many systems can read them and how many people must coordinate their lifecycle. A workload using managed identity to retrieve only the secret it needs removes a bootstrap credential that would otherwise require protection and rotation.

Credentials in Git, secrets shared by several workloads, certificates without owners and expiries capable of stopping production are serious signals. Potentially exposed material is rotated first, after consumers are identified. Automation, application-level separation, data-plane RBAC and deletion protection come next. Blind rotation can cause the same downtime we are trying to avoid.

Backups: green does not mean recoverable

We inspect Azure Backup, Recovery Services Vault, SQL PITR, PostgreSQL backups, Storage redundancy, snapshots, retention, soft delete, geo-redundancy and immutability where the threat model justifies it. But the decisive indicator is not the latest successful job. It is the latest validated restore.

Backup success ≠ recovery success. We ask when a restore last happened, how long it took, who performed it, whether a runbook exists and how data integrity was checked. The recovery object is not an isolated database; it is the complete service.

RPO states acceptable data loss; RTO states acceptable service unavailability. A backup every 24 hours does not by itself prove RPO = 24 h, because transaction logs or other recovery mechanisms may exist. Nor does a 30-minute database restore prove RTO = 30 min: infrastructure, identity, DNS, secrets, applications, safe event replay and validation remain.

The mature response is a bounded recovery exercise. Restore into isolation, measure end-to-end time, validate a business transaction and record every improvised step. If this risk is already material, Azure continuity and operations should turn the test into a repeatable practice.

Observability: can we understand an incident?

We review Azure Monitor, Log Analytics, Application Insights, Managed Prometheus, Grafana, diagnostic settings, alerts, action groups, dashboards, traces, correlation IDs and synthetic checks. Which alert wakes someone? Which alerts are routinely ignored? How long does it take to get from “the service is slow” to a credible cause?

CPU, memory and resource availability are insufficient if nobody can see customer experience. We look for service signals: error rate, operation latency, queues, saturation, dependency failures and synthetic transactions. We also inspect cardinality, retention and ingestion volume. Excess logs without a diagnostic purpose slow investigations and increase Log Analytics spend.

Monitoring tells us something changed; observability supplies enough context to understand why. The answer is not fifty new alerts. It is a workload health model, a small set of actionable signals with owners and evidence that notifications arrive. SRE and observability should reduce diagnostic time, not accumulate dashboards.

FinOps: follow the money

In Azure Cost Management we inspect cost by subscription, Resource Group, service, region and tag; budgets and alerts; reservations, Savings Plans and Azure Hybrid Benefit where applicable; then compute, databases, disks, Storage, Log Analytics, networking, egress and backup. Trend and usage change matter more than one monthly total.

We look for non-production resources running around the clock, oversized VMs, unattached disks, historical snapshots, databases whose capacity or tier does not match demand, excessive telemetry, orphaned resources and cost with no owner. An apparent anomaly may represent healthy growth, so spend needs a product, customer or capacity context.

FinOps is not reducing the bill at any cost.

A reservation can reduce the rate for stable usage, while an Azure Savings Plan offers more flexibility across eligible dynamic usage; neither removes waste. Cutting redundancy, retention or critical capacity to hit a monthly target merely converts financial cost into operational risk. Decisions balance cost, performance, resilience and delivery speed. If attribution is absent, Azure FinOps starts with ownership and a defensible baseline.

Azure Policy, Defender and governance

We review Azure Policy definitions, initiatives, assignments, exemptions and effects; Defender for Cloud recommendations and Secure Score; regulatory requirements; resource locks; tag, location or SKU policies; and diagnostic settings coverage. We care less about policy count than whether policies prevent, deploy or audit relevant controls without blocking legitimate delivery.

Secure Score is not an audit. It is a useful aggregate signal that directs investigation. Recommendations may be irrelevant, compensating controls may exist, exceptions may be justified and the score cannot know every business risk. In 2026, Azure Portal and Microsoft Defender Portal also expose distinct secure-score experiences; chasing a number without understanding its model can distort priority.

An audit-mode policy that nobody reviews creates compliance theatre. A deny policy introduced without testing existing resources can break delivery. We first group findings by risk and workload, document exceptions with owner and expiry, and test controls. Only then do we progressively move suitable controls from audit to deny or deploy-if-not-exists.

Dependencies and single points of failure

We look for single VMs, database instances without appropriate replicas, zonal dependencies, gateways, NAT, DNS, certificates, integrations and external SaaS. The question that cuts through noise is: which component can stop the complete service, and what really happens when it disappears?

High availability and disaster recovery address different failures. Spreading instances across Availability Zones may tolerate a zone failure, but not necessarily a region failure, logical deletion, compromised credentials or a bad release. Replication can replicate corruption. We test specific failure modes against business objectives, not an abstract ideal architecture.

A discovered SPOF is not always duplicated immediately. We consider likelihood, impact, replacement time and cost. An internal tool might need only a runbook and automated rebuild; the billing path may require redundancy, tested failover and regional design. Proportionate resilience is more operable than indiscriminate duplication.

Bus factor and operability

We establish who can deploy, recover, administer privileged access and explain DNS, networking, Terraform and backups. We review runbooks, ADRs, architecture diagrams, documentation, ownership and escalation paths. This is not an evaluation of individuals. It is an evaluation of whether the system allows a team to operate without private memory.

If the main infrastructure owner were unavailable for two weeks, could the rest of the team keep operating?

Negative answers surface in small tasks: the certificate only one person knows how to renew, a pipeline tied to a personal token, or restore instructions hidden in chat history. The next step is to select high-impact operations, have someone else perform them under supervision and turn gaps into automation or runbooks. Reducing DevOps bus factor is a continuity measure, not criticism of the specialist holding the platform together.

Not everything we find is a problem

A mature assessment does not compete to maximise findings. A Public IP may be justified. One subscription can fit the organisation and required isolation. Avoiding AKS can be an excellent decision. Not deploying Azure Firewall or Private Endpoints everywhere may avoid cost and complexity without materially increasing risk.

A technically less elegant solution may be appropriate when the team understands it, it meets its objectives and it can be operated. The right question is: does this decision still make sense for the business and platform we have today?

Every finding therefore needs evidence, an impact scenario, probability, existing controls and a proportionate recommendation. “It differs from our reference architecture” is not an impact statement. If we cannot explain which failure a proposal prevents, we should not ask the team to implement it.

What should exist after 48 hours

The expected outcome is not a new architecture. It is four practical artefacts: a service and dependency map; a prioritised risk register; quick wins that are small and reversible; and structural issues requiring a project, budget or business decision. We add a fifth category explicitly: unknowns.

Finding Impact Likelihood Priority
Database restore never tested Critical Medium Critical
Administrative interface open to Internet Critical High Critical
Service principal is subscription Contributor High Medium High
Production certificate has no owner and expires soon High High Critical
Critical database has one zonal dependency High Medium High
Terraform drift in production networking High Medium High
Application rollback never rehearsed High Medium High
Alerts have no operational action group Medium High High
Egress and private DNS have no map or owner Medium Medium Medium
Development VMs are oversized Low High Medium
Log retention has no stated purpose Low High Medium
Regional RTO remains unknown Unknown Unknown Investigate

Knowing what we still do not know is part of a good assessment. An unknown with an owner, required evidence and resolution date is more useful than presenting an assumption as a recommendation.

Prioritisation: do not fix 100 things at once

We use a simple operational classification. P0 is immediate risk of data loss, compromise or critical outage and triggers containment. P1 is high risk with an owner and near-term date. P2 is operational debt that reduces team capability without breaking production tomorrow. P3 covers efficiency, cost and experience improvements.

Priority is not severity alone. It includes workload criticality, exposure, compensating controls, likelihood and remediation reversibility. Ten simultaneous P1 tasks are not a priority; they are another backlog. We limit work in progress and validate each change before opening the next group.

The 20 questions every team operating Azure should answer

  1. Which workloads sustain production, and who owns each one?
  2. What happens to the service if an Availability Zone or primary region fails?
  3. What RPO is agreed for each critical data set?
  4. What RTO includes complete restoration, configuration and validation?
  5. When was the last real restore, and what did it prove?
  6. Which resources and configurations are not defined as code?
  7. Who has Owner, User Access Administrator or equivalent privilege, and why?
  8. Which workloads and administrative interfaces are publicly exposed?
  9. How many locations hold static credentials?
  10. Can we rotate them without downtime or fragile manual coordination?
  11. Which alert detects degradation experienced by customers?
  12. What does each product, team and environment cost, and who owns that cost?
  13. Which usage change explains last month’s bill increase?
  14. Can we roll back through the same controlled path used to deploy?
  15. Which critical operation depends on one person?
  16. Which components are single points of failure, and what is their impact?
  17. Which production changes are still performed manually?
  18. How long does it take to move from alert to credible cause?
  19. What proportion of production can be rebuilt from Git into an empty environment?
  20. If Azure suffered a material outage tomorrow, who would decide what to do and from which runbook?

If several answers begin with “we think”, the investigation has already acquired an order. The aim is not to solve all twenty questions in two days. It is to distinguish fact, assumption and unknown.

The first 48 hours should create clarity

After two days, we should understand what is critical, where risk sits, what can break, what can recover, what depends on individuals, where money is spent and what deserves attention first. That clarity tells us whether the next move is containing exposure, rehearsing recovery, narrowing privilege, restoring IaC control or funding a structural project.

The first 48 hours should not produce a new architecture. They should produce clarity.

Infrastructure does not need to be perfect. It needs to be understandable, operable and proportionate to the business it sustains.

Official technical sources

This approach draws on current Microsoft guidance for the Azure Well-Architected Framework, Azure RBAC best practices, Privileged Identity Management, Azure Private Endpoint, Azure Backup reliability, Azure Monitor, Key Vault security, Azure Policy and Defender for Cloud recommendations.