{"id":523,"date":"2026-04-14T09:11:33","date_gmt":"2026-04-14T09:11:33","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/azure-storage-discovery-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-storage\/"},"modified":"2026-04-14T09:11:33","modified_gmt":"2026-04-14T09:11:33","slug":"azure-storage-discovery-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-storage","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/azure-storage-discovery-tutorial-architecture-pricing-use-cases-and-hands-on-guide-for-storage\/","title":{"rendered":"Azure Storage Discovery Tutorial: Architecture, Pricing, Use Cases, and Hands-On Guide for Storage"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Category<\/h2>\n\n\n\n<p>Storage<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Introduction<\/h2>\n\n\n\n<p>Azure Storage environments can grow quickly: multiple subscriptions, hundreds of storage accounts, mixed SKUs, different network rules, and inconsistent security settings. Teams often reach a point where they can\u2019t confidently answer basic questions such as \u201cWhere do we have storage accounts?\u201d, \u201cWhich ones allow public access?\u201d, \u201cWhich accounts have private endpoints?\u201d, or \u201cWhich storage accounts are missing diagnostics?\u201d.<\/p>\n\n\n\n<p><strong>Azure Storage Discovery<\/strong> (as a practical Azure capability) refers to the set of supported Azure-native methods used to <strong>discover, inventory, and assess Azure Storage resources<\/strong> across scopes (resource group, subscription, management group, tenant). In day-to-day engineering, this is typically implemented using <strong>Azure Resource Graph<\/strong> (inventory\/query), <strong>Azure Policy<\/strong> (audit\/enforce), and <strong>Azure Monitor \/ Log Analytics<\/strong> (operational visibility), optionally complemented by <strong>Microsoft Defender for Cloud<\/strong> (security posture) and <strong>Microsoft Purview<\/strong> (data discovery\/governance at the data layer).<\/p>\n\n\n\n<p>From a technical standpoint, Azure Storage Discovery is primarily a <strong>control-plane discovery workflow<\/strong>: querying Azure Resource Manager (ARM) metadata about storage resources (accounts, configuration, properties, and relationships). Where needed, it can be extended into <strong>data-plane discovery<\/strong> (containers, file shares, tables, queues) using RBAC-enabled calls to Azure Storage APIs\u2014carefully, because data-plane discovery has different permissions, costs, and security implications than control-plane inventory.<\/p>\n\n\n\n<p><strong>What problem it solves:<\/strong> it gives platform, security, and operations teams a reliable way to <strong>find storage resources, understand configuration drift, reduce risk (public exposure, weak network controls), improve governance (tags, policies), and optimize cost<\/strong>\u2014without relying on manual portal clicking or stale spreadsheets.<\/p>\n\n\n\n<blockquote>\n<p>Service-name note (important): As of the latest generally available Azure service catalog up to my knowledge cutoff (2025-08), there is <strong>no standalone Azure product SKU explicitly named \u201cAzure Storage Discovery\u201d<\/strong>. The term is commonly used to describe <strong>storage inventory\/discovery solutions<\/strong> built on top of Azure\u2019s official services (notably Azure Resource Graph, Azure Policy, and Azure Monitor). Verify the latest naming in official Azure docs if Microsoft introduces a first-class product with this exact name.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">2. What is Azure Storage Discovery?<\/h2>\n\n\n\n<p><strong>Official purpose (practical\/operational):<\/strong> Azure Storage Discovery is the practice and implementation pattern of using Azure\u2019s supported management and governance services to <strong>discover and catalog Azure Storage resources and their configurations<\/strong> across your Azure estate.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Core capabilities<\/h3>\n\n\n\n<p>In real Azure environments, \u201cAzure Storage Discovery\u201d usually includes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Inventory:<\/strong> enumerate storage accounts (and optionally data-plane objects like containers and file shares) across one or more subscriptions.<\/li>\n<li><strong>Configuration visibility:<\/strong> retrieve properties such as SKU, replication, secure transfer requirement, minimum TLS version, public network access, blob public access settings, hierarchical namespace, SFTP settings (if enabled), and identity features.<\/li>\n<li><strong>Governance insights:<\/strong> detect missing tags, noncompliant configurations, and drift using policy\/audit.<\/li>\n<li><strong>Operational insights:<\/strong> identify accounts without diagnostics, monitor logs\/metrics, and feed results into dashboards or ticketing.<\/li>\n<li><strong>Security posture checks:<\/strong> highlight risky exposure (public endpoints, permissive firewall rules) and align with compliance requirements.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Major components (typical Azure building blocks)<\/h3>\n\n\n\n<p>Azure Storage Discovery is not one console button\u2014it\u2019s assembled using:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Azure Resource Graph<\/strong> (ARG): fast, read-only queries across resources using Kusto Query Language (KQL).<br\/>\n  Docs: https:\/\/learn.microsoft.com\/azure\/governance\/resource-graph\/overview<\/li>\n<li><strong>Azure Policy<\/strong>: audit\/enforce standards, produce compliance results for storage resources.<br\/>\n  Docs: https:\/\/learn.microsoft.com\/azure\/governance\/policy\/overview<\/li>\n<li><strong>Azure Monitor + Log Analytics<\/strong>: metrics\/logs\/diagnostics for storage accounts and discovery workflows.<br\/>\n  Docs: https:\/\/learn.microsoft.com\/azure\/azure-monitor\/overview<\/li>\n<li>Optional, depending on goals:<\/li>\n<li><strong>Microsoft Defender for Cloud<\/strong> (security recommendations, posture management): https:\/\/learn.microsoft.com\/azure\/defender-for-cloud\/<\/li>\n<li><strong>Microsoft Purview<\/strong> (data cataloging and data discovery inside storage): https:\/\/learn.microsoft.com\/purview\/<\/li>\n<li><strong>Azure Automation \/ Azure Functions \/ Logic Apps<\/strong> to schedule discovery and export results.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Service type and scope<\/h3>\n\n\n\n<p>Because \u201cAzure Storage Discovery\u201d is implemented using Azure management services, its scope is determined by the underlying services:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Azure Resource Graph<\/strong>: queries can span <strong>multiple subscriptions<\/strong> and <strong>management groups<\/strong> (depending on your access). It\u2019s effectively <strong>tenant-wide<\/strong> for users with appropriate permissions.<\/li>\n<li><strong>Azure Policy<\/strong>: can be assigned at <strong>management group<\/strong>, <strong>subscription<\/strong>, <strong>resource group<\/strong>, or <strong>resource<\/strong> scope.<\/li>\n<li><strong>Azure Storage data-plane discovery<\/strong> (containers\/shares): scoped to each storage account and governed by <strong>Azure RBAC data roles<\/strong> or shared keys (shared keys are discouraged).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">How it fits into the Azure ecosystem<\/h3>\n\n\n\n<p>Azure Storage Discovery is a foundational capability for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Cloud Center of Excellence (CCoE)<\/strong> governance<\/li>\n<li><strong>Security and compliance<\/strong> audits<\/li>\n<li><strong>FinOps<\/strong> reporting and cost controls<\/li>\n<li><strong>Platform engineering<\/strong> standardization and guardrails<\/li>\n<li><strong>Ops\/SRE<\/strong> troubleshooting and capacity planning<\/li>\n<\/ul>\n\n\n\n<p>It sits \u201cabove\u201d Azure Storage, using Azure\u2019s control-plane APIs and governance tooling to turn raw resources into an understandable, reportable inventory.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Why use Azure Storage Discovery?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Business reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Risk reduction:<\/strong> quickly identify publicly exposed or misconfigured storage accounts before incidents occur.<\/li>\n<li><strong>Audit readiness:<\/strong> produce repeatable evidence of controls (encryption, network restrictions, logging).<\/li>\n<li><strong>Cost control:<\/strong> find legacy SKUs, unused accounts, and expensive patterns (egress, excessive transactions) and prioritize optimization.<\/li>\n<li><strong>Faster change:<\/strong> standardize and automate discovery instead of manual reviews.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Technical reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Single query surface across subscriptions:<\/strong> Azure Resource Graph can query at scale without writing custom crawlers.<\/li>\n<li><strong>Rich configuration visibility:<\/strong> retrieve ARM properties reliably and consistently.<\/li>\n<li><strong>Automation-friendly:<\/strong> discovery queries can be scheduled, exported, and integrated into CI\/CD or ITSM workflows.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operational reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Inventory accuracy:<\/strong> reduce \u201cunknown\u201d storage accounts created by teams without central oversight.<\/li>\n<li><strong>Drift detection:<\/strong> detect when storage accounts deviate from baseline settings.<\/li>\n<li><strong>Troubleshooting speed:<\/strong> correlate incidents to storage config (network rules, TLS settings, endpoints).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Security\/compliance reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Governance guardrails:<\/strong> Azure Policy can block or audit noncompliant storage configurations.<\/li>\n<li><strong>Least privilege alignment:<\/strong> can use Azure RBAC for read-only discovery and restricted data-plane enumeration.<\/li>\n<li><strong>Logging posture:<\/strong> identify which accounts are missing diagnostics configuration.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Scalability\/performance reasons<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Designed for scale:<\/strong> Azure Resource Graph is optimized for estate-wide resource queries; it\u2019s not the same as iterating subscription-by-subscription with ARM REST calls.<\/li>\n<li><strong>Near-real-time inventory:<\/strong> results reflect current ARM state (subject to platform behavior\u2014verify in official docs for freshness expectations).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When teams should choose it<\/h3>\n\n\n\n<p>Choose an Azure Storage Discovery approach if you need:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Central visibility across many subscriptions<\/li>\n<li>Standard reporting for storage configuration\/security<\/li>\n<li>Repeatable governance and compliance checks<\/li>\n<li>A low-friction way to bootstrap storage inventory<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When they should not choose it<\/h3>\n\n\n\n<p>Avoid overextending \u201cAzure Storage Discovery\u201d patterns when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You need <strong>deep data-level scanning<\/strong> (sensitive data classification inside blobs\/files). Use <strong>Microsoft Purview<\/strong> and\/or security tooling designed for content inspection.<\/li>\n<li>You need <strong>high-frequency real-time eventing<\/strong> on resource changes. Use <strong>Azure Event Grid<\/strong> (resource events) and activity logs rather than periodic inventory queries.<\/li>\n<li>You can\u2019t obtain proper read permissions across subscriptions (discovery will be incomplete).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">4. Where is Azure Storage Discovery used?<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Industries<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Financial services (audit trails, strict network controls)<\/li>\n<li>Healthcare (PHI governance, access restrictions)<\/li>\n<li>Retail\/e-commerce (large data volumes, multi-environment sprawl)<\/li>\n<li>Manufacturing\/IoT (many storage accounts across plants and regions)<\/li>\n<li>SaaS providers (multi-tenant operations, strong security baselines)<\/li>\n<li>Public sector (compliance reporting, standardization)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Team types<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Platform engineering and cloud infrastructure teams<\/li>\n<li>Security operations and governance teams<\/li>\n<li>FinOps \/ cost management teams<\/li>\n<li>SRE\/operations teams<\/li>\n<li>DevOps teams managing landing zones<\/li>\n<li>Internal audit and compliance stakeholders (read-only reporting)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Workloads<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Data lakes on Azure Blob \/ ADLS Gen2<\/li>\n<li>Application storage for web\/mobile backends<\/li>\n<li>Backup\/archival (Blob cool\/archive)<\/li>\n<li>File shares for lift-and-shift workloads<\/li>\n<li>Log\/telemetry storage pipelines<\/li>\n<li>ML datasets and feature stores (storage-backed)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Architectures<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Landing zone architectures using management groups + policy<\/li>\n<li>Hub-and-spoke networks with private endpoints<\/li>\n<li>Multi-region DR designs (GRS\/ZRS variations)<\/li>\n<li>Multi-subscription environments segmented by BU\/environment<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Real-world deployment contexts<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Production:<\/strong> continuous discovery to enforce and audit standards, detect drift, and support incident response.<\/li>\n<li><strong>Dev\/test:<\/strong> periodic discovery to clean up old accounts, enforce tagging, and prevent accidental exposure (like public blob access).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">5. Top Use Cases and Scenarios<\/h2>\n\n\n\n<p>Below are realistic, common use cases implemented with Azure Resource Graph, Azure Policy, and selective data-plane enumeration.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1) Estate-wide inventory of storage accounts<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> You don\u2019t know how many storage accounts exist across all subscriptions, who owns them, or where they are deployed.<\/li>\n<li><strong>Why Azure Storage Discovery fits:<\/strong> Azure Resource Graph can query all storage accounts across multiple subscriptions quickly.<\/li>\n<li><strong>Example scenario:<\/strong> A platform team runs a weekly inventory export to CSV for reporting and ownership validation.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2) Identify storage accounts allowing public blob access<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Public blob access can lead to data exposure if containers are misconfigured.<\/li>\n<li><strong>Why it fits:<\/strong> Storage account properties can indicate whether blob public access is allowed; policy can audit\/deny it.<\/li>\n<li><strong>Example scenario:<\/strong> Security team flags accounts with <code>allowBlobPublicAccess<\/code> enabled and opens remediation tickets.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">3) Find storage accounts with public network access enabled (vs private endpoints)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Corporate policy requires private connectivity (Private Link) for production storage.<\/li>\n<li><strong>Why it fits:<\/strong> ARM properties expose <code>publicNetworkAccess<\/code> and network ACL default actions.<\/li>\n<li><strong>Example scenario:<\/strong> A compliance dashboard lists production subscriptions where storage accounts still allow public endpoints.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4) Tag compliance for cost allocation<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Without tags like <code>CostCenter<\/code>, <code>Application<\/code>, and <code>Owner<\/code>, cost allocation and ownership are unclear.<\/li>\n<li><strong>Why it fits:<\/strong> Resource Graph can report missing tags; Azure Policy can enforce tags on creation.<\/li>\n<li><strong>Example scenario:<\/strong> FinOps tracks untagged accounts and blocks new untagged storage accounts in production.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">5) Detect nonstandard replication\/SKU usage<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Some teams deploy expensive replication (or insufficient resilience) without approval.<\/li>\n<li><strong>Why it fits:<\/strong> Inventory can report SKU\/replication; policy can restrict allowed SKUs by environment.<\/li>\n<li><strong>Example scenario:<\/strong> Production must use ZRS or GRS; dev\/test should use LRS. Discovery reports exceptions.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">6) Find accounts not meeting minimum TLS requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Legacy TLS settings can violate compliance requirements.<\/li>\n<li><strong>Why it fits:<\/strong> Storage account properties include minimum TLS version configuration (where available).<\/li>\n<li><strong>Example scenario:<\/strong> Audit team runs a quarterly TLS posture report and remediates accounts below baseline.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">7) Identify accounts missing diagnostic settings<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Without diagnostics, investigating incidents or performance issues becomes difficult.<\/li>\n<li><strong>Why it fits:<\/strong> Resource Graph can help find whether diagnostic settings exist (depending on resource\/provider visibility); Azure Policy has \u201cDeployIfNotExists\u201d patterns for diagnostics in many services. Verify applicability for Storage in your region and policy set.<\/li>\n<li><strong>Example scenario:<\/strong> Operations requires diagnostic logs to Log Analytics; discovery highlights gaps.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">8) Data-plane enumeration for container\/share exposure<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Even when the account is secure, individual containers might have public access levels (if allowed) or misconfigured permissions.<\/li>\n<li><strong>Why it fits:<\/strong> With RBAC data roles, you can list containers and their public access level.<\/li>\n<li><strong>Example scenario:<\/strong> Security team runs container listing only for flagged accounts, minimizing data-plane API usage.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">9) M&amp;A \/ tenant consolidation discovery<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> After acquisition, you need a quick picture of the acquired Azure Storage footprint.<\/li>\n<li><strong>Why it fits:<\/strong> Resource Graph can inventory across subscriptions once access is granted; results can guide migration plans.<\/li>\n<li><strong>Example scenario:<\/strong> Integration team produces a \u201cstorage accounts by region\/SKU\/network posture\u201d report within days.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">10) Incident response: \u201cwhere could data have been exposed?\u201d<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> You suspect leakage via storage and need to quickly identify potentially exposed endpoints.<\/li>\n<li><strong>Why it fits:<\/strong> Discovery can identify accounts with public network access + permissive firewall + blob public access.<\/li>\n<li><strong>Example scenario:<\/strong> IR team runs a query to prioritize which accounts to lock down immediately.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">11) Standardize identity settings (managed identity \/ key-based access posture)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> Teams use shared keys or SAS patterns inconsistently.<\/li>\n<li><strong>Why it fits:<\/strong> Discovery can highlight configurations and drive adoption of Azure AD-based authorization and managed identities (implementation details vary by workload).<\/li>\n<li><strong>Example scenario:<\/strong> Platform team identifies accounts still relying on shared keys and creates a migration backlog.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">12) Landing zone readiness checks<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> New subscriptions must comply with baseline storage rules before go-live.<\/li>\n<li><strong>Why it fits:<\/strong> A standard discovery pack (queries + policy compliance) becomes a readiness gate.<\/li>\n<li><strong>Example scenario:<\/strong> A release checklist requires \u201c0 noncompliant storage accounts\u201d before production cutover.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">6. Core Features<\/h2>\n\n\n\n<p>Because \u201cAzure Storage Discovery\u201d is implemented with multiple Azure services, the \u201cfeatures\u201d below describe what you can reliably do with those official components.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 1: Cross-subscription storage inventory (control plane)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Lists storage accounts and their ARM properties across many subscriptions.<\/li>\n<li><strong>Why it matters:<\/strong> Removes blind spots in large Azure estates.<\/li>\n<li><strong>Practical benefit:<\/strong> Generate authoritative inventory reports in minutes.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Inventory is only as complete as your access. No permission = not discoverable by you.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 2: Powerful querying and filtering (KQL via Azure Resource Graph)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Uses Kusto Query Language (KQL) to filter by tags, SKU, location, properties, resource group, subscription, etc.<\/li>\n<li><strong>Why it matters:<\/strong> Enables precise reporting (eg \u201cprod subscriptions + publicNetworkAccess enabled\u201d).<\/li>\n<li><strong>Practical benefit:<\/strong> Build reusable query packs for governance and audits.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Resource Graph exposes ARM resource metadata; it does not replace deep monitoring logs or data classification tools.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 3: Exportable reporting (CSV\/JSON) for audits and FinOps<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Outputs query results for spreadsheets, BI, or ticketing.<\/li>\n<li><strong>Why it matters:<\/strong> Auditors and FinOps teams often require exports and evidence snapshots.<\/li>\n<li><strong>Practical benefit:<\/strong> Automate weekly\/monthly exports and store them securely.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Treat exports as sensitive (they may contain resource names, IDs, and topology).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 4: Policy-based audit and enforcement (Azure Policy)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Audits storage accounts against rules (eg public network access disabled) and can deny noncompliant deployments (where policies exist).<\/li>\n<li><strong>Why it matters:<\/strong> Moves from \u201cdetect issues\u201d to \u201cprevent issues\u201d.<\/li>\n<li><strong>Practical benefit:<\/strong> Reduce incidents caused by misconfiguration.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Policy coverage varies by resource type\/property; always test in nonproduction. Some settings may not be enforceable via policy in all scenarios\u2014verify in official docs and policy definitions.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 5: Continuous compliance posture at scale (Policy compliance results)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Produces compliance states and aggregates them by scope.<\/li>\n<li><strong>Why it matters:<\/strong> You need trending and accountability, not one-time snapshots.<\/li>\n<li><strong>Practical benefit:<\/strong> Provide dashboards for leadership and engineering teams.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Compliance evaluation timing is not instantaneous; verify evaluation intervals and triggers in official docs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 6: Optional data-plane discovery (containers\/shares) with Azure RBAC<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Lists containers, optionally their public access level, and other data-plane entities\u2014without using account keys.<\/li>\n<li><strong>Why it matters:<\/strong> Some risks live at the container\/share level.<\/li>\n<li><strong>Practical benefit:<\/strong> Spot-check exposure while maintaining least privilege.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Requires data-plane permissions (<code>Storage Blob Data Reader\/Contributor<\/code> etc.) and may incur transaction costs. Avoid scanning huge estates too frequently.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 7: Activity logging for \u201cwho changed what\u201d (Azure Activity Log)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Shows management-plane changes to storage accounts (create\/update\/delete, network rule changes).<\/li>\n<li><strong>Why it matters:<\/strong> Critical for forensic and change management.<\/li>\n<li><strong>Practical benefit:<\/strong> Trace changes back to identities and deployments.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Activity Log retention is limited unless exported to Log Analytics\/Event Hub\/Storage. Verify retention defaults in your tenant.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 8: Operational monitoring integration (Azure Monitor metrics\/logs)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Enables performance\/availability monitoring and alerting for storage.<\/li>\n<li><strong>Why it matters:<\/strong> Discovery and inventory are stronger when paired with runtime signals.<\/li>\n<li><strong>Practical benefit:<\/strong> Detect spikes in transactions, throttling, or egress patterns that influence cost and reliability.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Logs\/diagnostics can materially increase cost depending on volume and retention.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 9: Automation hooks (Functions\/Automation\/DevOps pipelines)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Schedules discovery runs, exports results, and opens issues automatically.<\/li>\n<li><strong>Why it matters:<\/strong> Manual inventory goes stale.<\/li>\n<li><strong>Practical benefit:<\/strong> Continuous governance without constant human effort.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Automation accounts\/functions need secure identity, least privilege, and secret management.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Feature 10: Optional data governance discovery (Microsoft Purview)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>What it does:<\/strong> Scans and catalogs data assets inside Azure Storage (schemas, classifications).<\/li>\n<li><strong>Why it matters:<\/strong> \u201cDiscovery of storage accounts\u201d is different from \u201cdiscovery of data.\u201d<\/li>\n<li><strong>Practical benefit:<\/strong> Meet data governance requirements and enable data search\/catalog.<\/li>\n<li><strong>Limitations\/caveats:<\/strong> Purview scans have their own pricing and setup complexity; not required for basic storage account inventory.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">7. Architecture and How It Works<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">High-level architecture<\/h3>\n\n\n\n<p>An Azure Storage Discovery solution typically follows this flow:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Control-plane inventory:<\/strong> Query ARM resource metadata using Azure Resource Graph.<\/li>\n<li><strong>Governance checks:<\/strong> Evaluate storage resources with Azure Policy (audit\/deny\/deployIfNotExists).<\/li>\n<li><strong>Optional enrichment:<\/strong>\n   &#8211; Data-plane enumeration for flagged accounts (containers\/shares)\n   &#8211; Security posture signals from Defender for Cloud<\/li>\n<li><strong>Reporting:<\/strong> Export results to Storage\/Log Analytics\/Power BI or ticketing.<\/li>\n<li><strong>Operations:<\/strong> Monitor discovery job runs, failures, and compliance trends.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Request\/data\/control flow<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Control plane:<\/strong> You query resource metadata (<code>Microsoft.Storage\/storageAccounts<\/code>) through Azure Resource Graph, which reads from Azure Resource Manager\u2019s indexed resource graph.<\/li>\n<li><strong>Data plane:<\/strong> For container listing, your identity calls Azure Storage endpoints (<code>https:\/\/&lt;account&gt;.blob.core.windows.net<\/code>) using Azure AD auth (RBAC) if configured and permitted.<\/li>\n<li><strong>Governance:<\/strong> Azure Policy evaluates resource configurations against definitions and produces compliance states. Some policies can deny or deploy settings automatically (where supported).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Integrations with related services<\/h3>\n\n\n\n<p>Common integrations include:\n&#8211; <strong>Azure Resource Graph<\/strong> + <strong>Azure Policy<\/strong> for compliance at scale\n&#8211; <strong>Azure Monitor \/ Log Analytics<\/strong> for trend and alerting\n&#8211; <strong>Microsoft Defender for Cloud<\/strong> for security recommendations\n&#8211; <strong>Microsoft Purview<\/strong> for data cataloging\/discovery\n&#8211; <strong>Power BI<\/strong> for dashboards (export discovery results)\n&#8211; <strong>ITSM<\/strong> tools (ServiceNow\/Jira) via Logic Apps for remediation workflows<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dependency services<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure Resource Manager (ARM)<\/li>\n<li>Azure Resource Graph<\/li>\n<li>Azure Storage resource provider (<code>Microsoft.Storage<\/code>)<\/li>\n<li>Azure AD (Microsoft Entra ID) for authentication and RBAC<\/li>\n<li>Optional: Log Analytics workspace, Defender for Cloud, Purview<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Security\/authentication model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Control plane (ARM\/ARG):<\/strong> governed by Azure RBAC roles like Reader\/Contributor at subscription\/resource group scope.<\/li>\n<li><strong>Data plane (Blob\/File\/Queue\/Table):<\/strong> governed by <strong>Storage data-plane roles<\/strong> such as:<\/li>\n<li><code>Storage Blob Data Reader<\/code><\/li>\n<li><code>Storage Blob Data Contributor<\/code><\/li>\n<li><code>Storage File Data SMB Share Reader<\/code> \/ Contributor (use case-dependent)<\/li>\n<li>Avoid using account keys for discovery where possible.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Networking model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure Resource Graph is a management-plane service accessed over Azure public endpoints.<\/li>\n<li>Data-plane enumeration hits storage endpoints; network rules (firewall, private endpoints) may block access from your client unless you run discovery from within an allowed network (eg, Azure VM in the VNet, VPN\/ExpressRoute, or private endpoint connectivity patterns).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Monitoring\/logging\/governance considerations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Discovery job logging:<\/strong> Log discovery runs (start\/end, counts, failures) to Log Analytics.<\/li>\n<li><strong>Activity Log export:<\/strong> Export subscription Activity Logs to a central workspace for retention and correlation.<\/li>\n<li><strong>Policy compliance dashboards:<\/strong> Use policy compliance views and export if needed.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Simple architecture diagram (Mermaid)<\/h3>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart LR\n  U[Engineer \/ Automation Identity] --&gt;|KQL Query| ARG[Azure Resource Graph]\n  ARG --&gt;|Inventory Results| REP[Report Export: CSV\/JSON]\n  U --&gt;|Assign\/Audit| POL[Azure Policy]\n  POL --&gt;|Compliance State| DASH[Compliance Dashboard]\n  U --&gt;|Optional: List containers| BLOB[Azure Storage Blob Endpoint]\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Production-style architecture diagram (Mermaid)<\/h3>\n\n\n\n<pre><code class=\"language-mermaid\">flowchart TB\n  subgraph Mgmt[Management Group \/ Multi-Subscription Scope]\n    ARG[Azure Resource Graph]\n    POL[Azure Policy Assignments]\n    ACT[Azure Activity Log]\n  end\n\n  subgraph Ops[Operations &amp; Security]\n    LA[Log Analytics Workspace]\n    MON[Azure Monitor Alerts]\n    DF[Microsoft Defender for Cloud (optional)]\n    PBI[Power BI \/ Workbook]\n    ITSM[ITSM \/ Ticketing (optional)]\n  end\n\n  subgraph Automate[Automation]\n    FUNC[Azure Function \/ Automation Runbook]\n    MI[Managed Identity]\n    KV[Azure Key Vault (optional)]\n  end\n\n  subgraph StorageEstate[Azure Storage Estate]\n    SA[(Storage Accounts)]\n    PE[Private Endpoints (optional)]\n  end\n\n  FUNC --&gt;|Uses| MI\n  FUNC --&gt;|KQL| ARG\n  FUNC --&gt;|Policy compliance read| POL\n  FUNC --&gt;|Writes logs| LA\n  ACT --&gt;|Export| LA\n  LA --&gt; PBI\n  LA --&gt; MON\n  DF --&gt; LA\n  FUNC --&gt;|Create tickets| ITSM\n\n  FUNC --&gt;|Optional data-plane enumerate (RBAC)| SA\n  SA --- PE\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">8. Prerequisites<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Account\/subscription\/tenant requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An active <strong>Azure subscription<\/strong>.<\/li>\n<li>Access to the subscriptions you want to discover.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Permissions \/ IAM roles<\/h3>\n\n\n\n<p>Minimum recommended permissions for this tutorial:\n&#8211; <strong>Reader<\/strong> on the resource group or subscription (for control-plane discovery).\n&#8211; If you perform <strong>data-plane container listing<\/strong> using Azure AD auth:\n  &#8211; <code>Storage Blob Data Contributor<\/code> (for creating containers) or\n  &#8211; <code>Storage Blob Data Reader<\/code> (for listing containers)\n  assigned at the storage account scope.<\/p>\n\n\n\n<p>For policy steps (optional in this lab):\n&#8211; Permissions to create policy assignments at the target scope. Exact built-in role requirements vary by organization; verify in official docs:\n  https:\/\/learn.microsoft.com\/azure\/governance\/policy\/assign-policy-portal<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Billing requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You will create Azure Storage accounts (low-cost SKUs are available).<\/li>\n<li>Azure Resource Graph queries generally do not have a direct line-item cost, but verify in official docs and your enterprise agreements.<\/li>\n<li>Optional logging to Log Analytics incurs ingestion\/retention costs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Tools needed<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure CLI installed: https:\/\/learn.microsoft.com\/cli\/azure\/install-azure-cli<\/li>\n<li>Azure CLI logged in: <code>az login<\/code><\/li>\n<li>Azure CLI Resource Graph extension:<\/li>\n<li>Install: <code>az extension add --name resource-graph<\/code><\/li>\n<li>Docs: https:\/\/learn.microsoft.com\/azure\/governance\/resource-graph\/first-query-azurecli<\/li>\n<\/ul>\n\n\n\n<p>Optional:\n&#8211; <code>jq<\/code> for JSON parsing (nice-to-have, not required).\n&#8211; PowerShell if you prefer exporting to CSV.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Region availability<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure Storage is regional.<\/li>\n<li>Azure Resource Graph is an Azure service available broadly; verify any sovereign cloud constraints in official docs.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Quotas\/limits<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Storage account limits and naming rules apply (globally unique names).<\/li>\n<li>Resource Graph query limits (page size, throttling) exist\u2014verify current limits:\n  https:\/\/learn.microsoft.com\/azure\/governance\/resource-graph\/concepts\/query-language#limits<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisite services<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Microsoft.Storage resource provider (usually registered by default).<\/li>\n<li>Microsoft Entra ID (Azure AD) for RBAC-based access.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">9. Pricing \/ Cost<\/h2>\n\n\n\n<p>Because \u201cAzure Storage Discovery\u201d is a solution pattern, costs come from the underlying services you use.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pricing dimensions (what you actually pay for)<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Azure Storage (direct costs)<\/strong>\n   &#8211; Storage capacity (GB\/TB stored)\n   &#8211; Replication option (LRS\/ZRS\/GRS\/GZRS as applicable)\n   &#8211; Access tier (Hot\/Cool\/Archive for Blob)\n   &#8211; Transactions (read\/write\/list), which matter if you do data-plane discovery at scale\n   &#8211; Data retrieval (eg, Archive rehydration)\n   &#8211; <strong>Data transfer (egress)<\/strong> out of Azure regions or to the internet<\/li>\n<\/ol>\n\n\n\n<p>Official pricing: https:\/\/azure.microsoft.com\/pricing\/details\/storage\/<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li><strong>Azure Monitor \/ Log Analytics (indirect costs)<\/strong>\n   &#8211; Log ingestion volume\n   &#8211; Retention period\n   &#8211; Queries (depending on your plan\/features)\n   &#8211; Diagnostics settings for Storage can generate significant logs at scale<\/li>\n<\/ol>\n\n\n\n<p>Official pricing: https:\/\/azure.microsoft.com\/pricing\/details\/monitor\/<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li>\n<p><strong>Automation costs (optional)<\/strong>\n   &#8211; Azure Functions (execution, memory), Automation, Logic Apps runs\n   &#8211; Storage for results (if you store reports)\n   &#8211; Key Vault operations (if used)<\/p>\n<\/li>\n<li>\n<p><strong>Security\/governance add-ons (optional)<\/strong>\n   &#8211; Microsoft Defender for Cloud plans (subscription\/resource-based pricing)\n     https:\/\/azure.microsoft.com\/pricing\/details\/defender-for-cloud\/\n   &#8211; Microsoft Purview pricing for scanning\/catalog features\n     https:\/\/azure.microsoft.com\/pricing\/details\/microsoft-purview\/<\/p>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Free tier \/ no-cost elements (verify in official docs)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Azure Resource Graph<\/strong> is generally consumed as part of Azure management experience; it is not typically billed like a metered compute service. Still, verify current billing stance in official docs and your contract.<\/li>\n<li><strong>Azure Policy<\/strong> does not typically have a direct per-policy charge; it is part of Azure governance. Verify for your cloud\/region (especially sovereign clouds).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Primary cost drivers<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>How often you run discovery<\/strong> (daily vs hourly).<\/li>\n<li><strong>Whether you enumerate data-plane objects<\/strong> (container listing across thousands of accounts can create transaction costs and throttling).<\/li>\n<li><strong>How much monitoring\/diagnostic logging you enable<\/strong> and retention duration.<\/li>\n<li><strong>Cross-region data movement<\/strong> (exporting results to centralized regions, or egress to on-prem).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Hidden\/indirect costs to watch<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Log Analytics ingestion<\/strong> from Storage diagnostics can become a top cost item.<\/li>\n<li><strong>Data-plane listing<\/strong> operations are billable transactions for Storage.<\/li>\n<li><strong>Private endpoint\/DNS architecture<\/strong> to allow discovery from secure networks may require additional infrastructure (private DNS zones, VM\/jumpbox).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Network\/data transfer implications<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Control-plane queries (Resource Graph) don\u2019t enumerate storage data and typically don\u2019t drive storage egress.<\/li>\n<li>Data-plane enumeration from outside the region or outside Azure can incur network egress (and may be blocked by firewall rules).<\/li>\n<li>Exporting discovery results to external systems (SIEM, BI) can incur egress.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">How to optimize cost<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prefer <strong>control-plane discovery<\/strong> first; only perform data-plane discovery for <strong>flagged<\/strong> accounts.<\/li>\n<li>Reduce discovery frequency for stable environments (weekly\/monthly) and increase only for sensitive scopes.<\/li>\n<li>Filter queries to only relevant subscriptions\/management groups.<\/li>\n<li>For logging:<\/li>\n<li>Send only needed categories<\/li>\n<li>Set retention to what you need for compliance<\/li>\n<li>Consider archiving older logs to lower-cost storage (design depends on requirements)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Example low-cost starter estimate (no fabricated numbers)<\/h3>\n\n\n\n<p>A low-cost starter setup typically includes:\n&#8211; A small number of Standard storage accounts (LRS) for testing\n&#8211; Occasional Azure Resource Graph queries (no separate compute infrastructure)\n&#8211; No continuous high-volume diagnostics<\/p>\n\n\n\n<p>Your main charges will likely be <strong>Storage capacity + transactions<\/strong> for what you create in the lab. Use the Azure Pricing Calculator to estimate for your region:\nhttps:\/\/azure.microsoft.com\/pricing\/calculator\/<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Example production cost considerations<\/h3>\n\n\n\n<p>In production, cost is dominated by:\n&#8211; Number of storage accounts and diagnostic settings volume\n&#8211; Log Analytics ingestion\/retention\n&#8211; Any continuous scanning or data-plane enumeration at scale\n&#8211; Defender for Cloud\/Purview usage (if enabled)<\/p>\n\n\n\n<p>A good FinOps practice is to treat discovery as a <strong>governance workload<\/strong> and assign a cost center to it, with budgets and alerts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">10. Step-by-Step Hands-On Tutorial<\/h2>\n\n\n\n<p>This lab builds a small, realistic Azure Storage Discovery workflow:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create two storage accounts with different security-related properties.<\/li>\n<li>Use Azure Resource Graph to discover and report storage accounts and key configuration fields.<\/li>\n<li>Optionally enumerate blob containers using Azure AD authentication (RBAC).<\/li>\n<li>Validate results and clean up.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Objective<\/h3>\n\n\n\n<p>Create a repeatable Azure Storage Discovery baseline using <strong>Azure CLI + Azure Resource Graph<\/strong>, and learn how to expand from control-plane inventory to selective data-plane enumeration.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab Overview<\/h3>\n\n\n\n<p>You will:\n1. Create a resource group and two storage accounts.\n2. Assign yourself RBAC data-plane permissions for container operations.\n3. Create a couple of blob containers.\n4. Run Azure Resource Graph queries to discover storage accounts and review security posture fields.\n5. Export results and validate.\n6. Clean up all resources.<\/p>\n\n\n\n<p><strong>Expected time:<\/strong> 30\u201360 minutes<br\/>\n<strong>Cost:<\/strong> Low, but not free (storage account resources). Delete afterwards.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Sign in, select subscription, and install prerequisites<\/h3>\n\n\n\n<p>1) Sign in:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az login\n<\/code><\/pre>\n\n\n\n<p>2) Choose the subscription:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az account show --output table\naz account set --subscription \"&lt;YOUR_SUBSCRIPTION_ID_OR_NAME&gt;\"\n<\/code><\/pre>\n\n\n\n<p>3) Install the Azure Resource Graph extension:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az extension add --name resource-graph\naz extension show --name resource-graph --output table\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> Azure CLI is authenticated, and the <code>resource-graph<\/code> extension is installed.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Create a resource group<\/h3>\n\n\n\n<p>Pick a region where you are allowed to deploy Azure Storage (example uses <code>eastus<\/code>).<\/p>\n\n\n\n<pre><code class=\"language-bash\">RG=\"rg-azure-storage-discovery-lab\"\nLOC=\"eastus\"\n\naz group create --name \"$RG\" --location \"$LOC\" --output table\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> A resource group exists for the lab.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create two storage accounts with different settings<\/h3>\n\n\n\n<p>Storage account names must be globally unique and 3\u201324 lowercase letters and numbers.<\/p>\n\n\n\n<pre><code class=\"language-bash\">RAND=$RANDOM\nSA1=\"sadiscoverylab${RAND}a\"\nSA2=\"sadiscoverylab${RAND}b\"\n<\/code><\/pre>\n\n\n\n<p>Create the first storage account (baseline):<\/p>\n\n\n\n<pre><code class=\"language-bash\">az storage account create \\\n  --name \"$SA1\" \\\n  --resource-group \"$RG\" \\\n  --location \"$LOC\" \\\n  --sku Standard_LRS \\\n  --kind StorageV2 \\\n  --min-tls-version TLS1_2 \\\n  --https-only true \\\n  --allow-blob-public-access false \\\n  --output table\n<\/code><\/pre>\n\n\n\n<p>Create the second storage account with a different posture (for comparison). The exact flags available can vary by API version\/region; if any flag fails, remove it and proceed, then inspect properties via Resource Graph.<\/p>\n\n\n\n<pre><code class=\"language-bash\">az storage account create \\\n  --name \"$SA2\" \\\n  --resource-group \"$RG\" \\\n  --location \"$LOC\" \\\n  --sku Standard_LRS \\\n  --kind StorageV2 \\\n  --min-tls-version TLS1_2 \\\n  --https-only true \\\n  --allow-blob-public-access true \\\n  --output table\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> Two storage accounts are created. One disallows blob public access; the other allows it (for demonstration).<\/p>\n\n\n\n<p><strong>Verification:<\/strong><\/p>\n\n\n\n<pre><code class=\"language-bash\">az storage account show --name \"$SA1\" --resource-group \"$RG\" --query \"{name:name, allowBlobPublicAccess:properties.allowBlobPublicAccess, publicNetworkAccess:properties.publicNetworkAccess}\" -o jsonc\naz storage account show --name \"$SA2\" --resource-group \"$RG\" --query \"{name:name, allowBlobPublicAccess:properties.allowBlobPublicAccess, publicNetworkAccess:properties.publicNetworkAccess}\" -o jsonc\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Assign yourself data-plane RBAC for blob container operations<\/h3>\n\n\n\n<p>To create\/list containers using <code>--auth-mode login<\/code>, your signed-in identity needs a Storage Blob data role on the storage account.<\/p>\n\n\n\n<p>Get your user object id (works in many tenants; if it fails due to directory restrictions, use an alternate method approved by your admin):<\/p>\n\n\n\n<pre><code class=\"language-bash\">MYOID=$(az ad signed-in-user show --query id -o tsv)\necho \"$MYOID\"\n<\/code><\/pre>\n\n\n\n<p>Assign <code>Storage Blob Data Contributor<\/code> on both storage accounts:<\/p>\n\n\n\n<pre><code class=\"language-bash\">SUBID=$(az account show --query id -o tsv)\n\nSA1_SCOPE=\"\/subscriptions\/$SUBID\/resourceGroups\/$RG\/providers\/Microsoft.Storage\/storageAccounts\/$SA1\"\nSA2_SCOPE=\"\/subscriptions\/$SUBID\/resourceGroups\/$RG\/providers\/Microsoft.Storage\/storageAccounts\/$SA2\"\n\naz role assignment create --assignee-object-id \"$MYOID\" --assignee-principal-type User \\\n  --role \"Storage Blob Data Contributor\" --scope \"$SA1_SCOPE\"\n\naz role assignment create --assignee-object-id \"$MYOID\" --assignee-principal-type User \\\n  --role \"Storage Blob Data Contributor\" --scope \"$SA2_SCOPE\"\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> RBAC assignments are created.<\/p>\n\n\n\n<p><strong>Important caveat:<\/strong> RBAC propagation can take a few minutes. If container commands fail immediately, wait 5\u201310 minutes and retry.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Create blob containers (data-plane) in each account<\/h3>\n\n\n\n<p>Create a couple of containers using Azure AD auth:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az storage container create --account-name \"$SA1\" --name \"private-data\" --auth-mode login --output table\naz storage container create --account-name \"$SA2\" --name \"public-test\" --auth-mode login --output table\n<\/code><\/pre>\n\n\n\n<p>Optionally set a container public access level on the second account (this will only work if the account allows blob public access; and many orgs block this intentionally):<\/p>\n\n\n\n<pre><code class=\"language-bash\">az storage container set-permission \\\n  --account-name \"$SA2\" \\\n  --name \"public-test\" \\\n  --public-access blob \\\n  --auth-mode login\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> Containers exist. The second container may be configured for public access (depending on account settings and tenant policy).<\/p>\n\n\n\n<p><strong>Verification:<\/strong><\/p>\n\n\n\n<pre><code class=\"language-bash\">az storage container list --account-name \"$SA1\" --auth-mode login --query \"[].{name:name, publicAccess:properties.publicAccess}\" -o table\naz storage container list --account-name \"$SA2\" --auth-mode login --query \"[].{name:name, publicAccess:properties.publicAccess}\" -o table\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Run Azure Resource Graph queries (control-plane discovery)<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">6A) List storage accounts in your accessible scope<\/h4>\n\n\n\n<pre><code class=\"language-bash\">az graph query -q \"\nResources\n| where type =~ 'microsoft.storage\/storageaccounts'\n| project name, resourceGroup, location, subscriptionId\n| order by name asc\n\" -o table\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> You see both storage accounts listed.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">6B) Discover security-relevant properties<\/h4>\n\n\n\n<p>This query projects common storage security\/network fields. Some fields might be null depending on account type, API version, or feature availability\u2014interpret null carefully and confirm with <code>az storage account show<\/code> when needed.<\/p>\n\n\n\n<pre><code class=\"language-bash\">az graph query -q \"\nResources\n| where type =~ 'microsoft.storage\/storageaccounts'\n| extend props = properties\n| project\n    name,\n    resourceGroup,\n    location,\n    sku = tostring(sku.name),\n    kind = tostring(kind),\n    httpsOnly = tostring(props.supportsHttpsTrafficOnly),\n    minTls = tostring(props.minimumTlsVersion),\n    allowBlobPublicAccess = tostring(props.allowBlobPublicAccess),\n    publicNetworkAccess = tostring(props.publicNetworkAccess)\n| order by name asc\n\" -o table\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> A table showing key properties for both accounts, including the difference in <code>allowBlobPublicAccess<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">6C) Filter to potentially risky accounts (example)<\/h4>\n\n\n\n<p>Example: find accounts that both allow blob public access and have public network access enabled (interpretation depends on your environment\u2019s baseline).<\/p>\n\n\n\n<pre><code class=\"language-bash\">az graph query -q \"\nResources\n| where type =~ 'microsoft.storage\/storageaccounts'\n| extend props = properties\n| where tostring(props.allowBlobPublicAccess) =~ 'true'\n| project name, resourceGroup, location, publicNetworkAccess=tostring(props.publicNetworkAccess)\n\" -o table\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> The second account (if created with blob public access allowed) appears.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Step 7: Export discovery results for reporting<\/h3>\n\n\n\n<p>Export JSON results:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az graph query -q \"\nResources\n| where type =~ 'microsoft.storage\/storageaccounts'\n| extend props = properties\n| project name, resourceGroup, location, sku=tostring(sku.name), allowBlobPublicAccess=tostring(props.allowBlobPublicAccess)\n| order by name asc\n\" -o jsonc &gt; storage-discovery-results.json\n<\/code><\/pre>\n\n\n\n<p>If you have <code>jq<\/code>, you can convert to a simple CSV-like output:<\/p>\n\n\n\n<pre><code class=\"language-bash\">cat storage-discovery-results.json | jq -r '.data[] | [.name,.resourceGroup,.location,.sku,.allowBlobPublicAccess] | @csv' &gt; storage-discovery-results.csv\n<\/code><\/pre>\n\n\n\n<p><strong>Expected outcome:<\/strong> You have a local export suitable for sharing (handle securely).<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Validation<\/h3>\n\n\n\n<p>Use this checklist:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Control-plane discovery works:<\/strong> Resource Graph lists both storage accounts.<\/li>\n<li><strong>Properties appear as expected:<\/strong><\/li>\n<li><code>allowBlobPublicAccess<\/code> differs between the two accounts (if supported by your API\/region).<\/li>\n<li><code>supportsHttpsTrafficOnly<\/code> is <code>true<\/code>.<\/li>\n<li><code>minimumTlsVersion<\/code> is <code>TLS1_2<\/code> (if surfaced).<\/li>\n<li><strong>Optional data-plane discovery works:<\/strong> <code>az storage container list --auth-mode login<\/code> returns container lists.<\/li>\n<\/ul>\n\n\n\n<p>If any field is blank\/null in Resource Graph but present in <code>az storage account show<\/code>, trust the direct ARM call for that property and verify whether ARG projection for that field is supported in your environment.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Troubleshooting<\/h3>\n\n\n\n<p>Common errors and practical fixes:<\/p>\n\n\n\n<p>1) <strong><code>az: error: unrecognized arguments: --allow-blob-public-access<\/code><\/strong>\n&#8211; Your CLI\/API profile may not support that parameter in the current context.\n&#8211; Fix: remove the flag and proceed; then inspect available properties with:\n  <code>bash\n  az storage account create -h\n  az storage account show --name \"$SA1\" --resource-group \"$RG\" -o jsonc<\/code><\/p>\n\n\n\n<p>2) <strong>Resource Graph extension not found<\/strong>\n&#8211; Fix:\n  <code>bash\n  az extension add --name resource-graph\n  az extension update --name resource-graph<\/code><\/p>\n\n\n\n<p>3) <strong><code>AuthorizationFailed<\/code> when running <code>az graph query<\/code><\/strong>\n&#8211; Cause: you don\u2019t have Reader (or equivalent) on the subscription(s) being queried.\n&#8211; Fix: request at least Reader on target subscriptions\/resource groups.<\/p>\n\n\n\n<p>4) <strong><code>AuthorizationPermissionMismatch<\/code> or 403 when listing containers<\/strong>\n&#8211; Cause: missing data-plane RBAC role or RBAC propagation delay.\n&#8211; Fix:\n  &#8211; Wait 5\u201310 minutes\n  &#8211; Confirm role assignment:\n    <code>bash\n    az role assignment list --scope \"$SA1_SCOPE\" --assignee-object-id \"$MYOID\" -o table<\/code>\n  &#8211; Ensure you used <code>--auth-mode login<\/code> (Azure AD auth), not account keys.<\/p>\n\n\n\n<p>5) <strong>Container public access setting fails<\/strong>\n&#8211; Your org policy may block it, or the storage account does not allow blob public access.\n&#8211; Fix: treat that as a success from a security perspective; proceed without public containers.<\/p>\n\n\n\n<hr class=\"wp-block-separator\" \/>\n\n\n\n<h3 class=\"wp-block-heading\">Cleanup<\/h3>\n\n\n\n<p>Delete the resource group and everything in it:<\/p>\n\n\n\n<pre><code class=\"language-bash\">az group delete --name \"$RG\" --yes --no-wait\n<\/code><\/pre>\n\n\n\n<p>Verify deletion (optional):<\/p>\n\n\n\n<pre><code class=\"language-bash\">az group exists --name \"$RG\"\n<\/code><\/pre>\n\n\n\n<p>Also remove local files (optional):<\/p>\n\n\n\n<pre><code class=\"language-bash\">rm -f storage-discovery-results.json storage-discovery-results.csv\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">11. Best Practices<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Architecture best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Start with control-plane discovery<\/strong> (Resource Graph) for broad coverage, then selectively deepen into data-plane enumeration only where necessary.<\/li>\n<li>Build a <strong>standard query pack<\/strong> (KQL snippets) for common questions:<\/li>\n<li>exposure (public endpoints, blob public access)<\/li>\n<li>encryption settings visibility<\/li>\n<li>replication\/SKU and region placement<\/li>\n<li>tag compliance and ownership<\/li>\n<li>Use <strong>management groups<\/strong> to structure discovery and apply policies consistently across the estate.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">IAM\/security best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use <strong>least privilege<\/strong>:<\/li>\n<li>Reader for inventory queries<\/li>\n<li>Data-plane roles only when needed and scoped narrowly<\/li>\n<li>Prefer <strong>Azure AD auth<\/strong> (<code>--auth-mode login<\/code>) over account keys\/SAS for discovery scripts.<\/li>\n<li>Use <strong>managed identities<\/strong> for automated discovery jobs, not user credentials.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Cost best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Avoid enumerating containers\/shares across all accounts frequently; it increases <strong>transactions<\/strong> and may trigger throttling.<\/li>\n<li>Keep Log Analytics retention aligned with compliance needs; don\u2019t retain everything forever by default.<\/li>\n<li>Filter discovery scope (management group\/subscriptions) instead of running tenant-wide queries unnecessarily.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Performance best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use Resource Graph to avoid slow subscription-by-subscription ARM crawling.<\/li>\n<li>Keep queries efficient:<\/li>\n<li>project only necessary fields<\/li>\n<li>filter early<\/li>\n<li>avoid heavy string parsing unless required<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Reliability best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Make discovery automation idempotent and tolerant of partial failures:<\/li>\n<li>handle \u201caccess denied\u201d per subscription gracefully<\/li>\n<li>retry with backoff on transient errors<\/li>\n<li>Version-control your query pack and policy assignments.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Operations best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Log discovery run metadata:<\/li>\n<li>start\/end time, duration<\/li>\n<li>number of accounts discovered<\/li>\n<li>number flagged per rule<\/li>\n<li>errors per subscription<\/li>\n<li>Create alerting for:<\/li>\n<li>discovery job failures<\/li>\n<li>sudden spikes in number of flagged accounts<\/li>\n<li>Maintain an ownership map (tags + CMDB) so findings route to the right team.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Governance\/tagging\/naming best practices<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enforce minimal tags: <code>Owner<\/code>, <code>Application<\/code>, <code>Environment<\/code>, <code>CostCenter<\/code>, <code>DataClassification<\/code>.<\/li>\n<li>Standardize naming patterns per environment and region.<\/li>\n<li>Use Azure Policy initiatives (policy sets) for storage baselines where available.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">12. Security Considerations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Identity and access model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Control plane:<\/strong> Azure RBAC governs who can read\/modify storage accounts.<\/li>\n<li><strong>Data plane:<\/strong> Storage-specific data roles govern access to blob\/file\/queue\/table data operations.<\/li>\n<li>For discovery automation:<\/li>\n<li>Use a dedicated managed identity.<\/li>\n<li>Assign only the roles it needs (often Reader for ARG + selective data-plane roles for targeted accounts).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Encryption<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure Storage supports encryption at rest (Microsoft-managed keys by default; customer-managed keys optional).<\/li>\n<li>Discovery should capture whether CMK is required by policy for certain data classifications (implementation depends on your requirements).<\/li>\n<li>Verify encryption properties in official docs and your required security baseline:\n  https:\/\/learn.microsoft.com\/azure\/storage\/common\/storage-service-encryption<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Network exposure<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Key discovery checks:<\/li>\n<li>public network access enabled\/disabled<\/li>\n<li>firewall default action<\/li>\n<li>private endpoints presence (relationship discovery may require additional queries)<\/li>\n<li>Data-plane discovery from outside allowed networks may fail (by design). Consider running discovery from a controlled network location if required.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Secrets handling<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Avoid account keys in scripts and CI logs.<\/li>\n<li>If you must use secrets (discouraged), store them in <strong>Azure Key Vault<\/strong> and restrict access tightly.<\/li>\n<li>Prefer Azure AD + managed identity for auth.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Audit\/logging<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enable and centralize:<\/li>\n<li>Azure Activity Logs export (control plane)<\/li>\n<li>Storage diagnostics (data plane operations), where appropriate<\/li>\n<li>Use Log Analytics for queryable audit trails and alerting.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Compliance considerations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Map discovery checks to standards:<\/li>\n<li>CIS benchmarks, ISO 27001, SOC 2 controls<\/li>\n<li>internal baselines (public access disabled, TLS 1.2+, logging enabled)<\/li>\n<li>Ensure discovery exports are handled as potentially sensitive operational data.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Common security mistakes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Running data-plane discovery with account keys stored in plaintext scripts.<\/li>\n<li>Allowing discovery automation identities broad Contributor rights.<\/li>\n<li>Assuming Resource Graph shows \u201ceverything\u201d without validating access boundaries.<\/li>\n<li>Over-logging (collecting sensitive logs without access controls) or under-logging (no forensics).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Secure deployment recommendations<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use management groups and policy baselines.<\/li>\n<li>Require private endpoints for high-sensitivity storage accounts.<\/li>\n<li>Use conditional access and privileged identity management (PIM) for elevated roles.<\/li>\n<li>Segment discovery duties: inventory (Reader) vs remediation (Contributor\/Owner) should be separate identities.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">13. Limitations and Gotchas<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Not a single product:<\/strong> \u201cAzure Storage Discovery\u201d is typically a solution pattern. Capabilities depend on the underlying Azure services you choose.<\/li>\n<li><strong>Permissions define visibility:<\/strong> You cannot discover what you can\u2019t read. Cross-subscription discovery requires consistent RBAC assignments.<\/li>\n<li><strong>ARG shows ARM metadata, not data contents:<\/strong> Resource Graph won\u2019t tell you what files are in a container. For data cataloging, use Microsoft Purview or workload-specific scanning.<\/li>\n<li><strong>Property availability variance:<\/strong> Some ARM properties may be null in Resource Graph or differ by storage account kind\/features. Always verify critical properties with <code>az storage account show<\/code> or ARM REST.<\/li>\n<li><strong>RBAC propagation delays:<\/strong> Data-plane role assignments can take minutes to apply.<\/li>\n<li><strong>Data-plane discovery can be blocked by network rules:<\/strong> Storage firewalls\/private endpoints can prevent listing containers unless you run discovery from an allowed network path.<\/li>\n<li><strong>Transaction costs and throttling:<\/strong> Listing containers\/blobs at scale costs money and can throttle. Keep enumeration targeted.<\/li>\n<li><strong>Policy enforcement differences:<\/strong> Not every desired rule is enforceable with a deny policy; some are audit-only or require deployIfNotExists patterns. Always test.<\/li>\n<li><strong>Export handling:<\/strong> Inventory exports can leak internal topology\/resource naming; treat them as sensitive.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">14. Comparison with Alternatives<\/h2>\n\n\n\n<p>Azure Storage Discovery overlaps with inventory, governance, and data governance. Here\u2019s how it compares.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Option<\/th>\n<th>Best For<\/th>\n<th>Strengths<\/th>\n<th>Weaknesses<\/th>\n<th>When to Choose<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Azure Resource Graph (core of Azure Storage Discovery)<\/strong><\/td>\n<td>Fast inventory across subscriptions<\/td>\n<td>Scales well, KQL power, integrates with Azure Portal\/CLI<\/td>\n<td>Metadata-focused; not data content<\/td>\n<td>You need estate-wide storage account discovery and reporting<\/td>\n<\/tr>\n<tr>\n<td><strong>Azure Policy<\/strong><\/td>\n<td>Governance and compliance<\/td>\n<td>Audit\/deny patterns, compliance dashboards<\/td>\n<td>Not a free-form query engine; coverage varies<\/td>\n<td>You need preventative controls and compliance tracking<\/td>\n<\/tr>\n<tr>\n<td><strong>Azure Monitor + Log Analytics<\/strong><\/td>\n<td>Operational visibility<\/td>\n<td>Alerts, logs, metrics, correlation<\/td>\n<td>Cost can grow; needs tuning<\/td>\n<td>You need runtime signals and centralized logging<\/td>\n<\/tr>\n<tr>\n<td><strong>Microsoft Defender for Cloud<\/strong><\/td>\n<td>Security posture management<\/td>\n<td>Recommendations, secure score, threat protection (plan-dependent)<\/td>\n<td>Added cost; not purely inventory<\/td>\n<td>You need security posture and prioritized remediation guidance<\/td>\n<\/tr>\n<tr>\n<td><strong>Microsoft Purview<\/strong><\/td>\n<td>Data discovery and catalog<\/td>\n<td>Scans data sources, classifications, data catalog<\/td>\n<td>Setup and scanning cost; more complex<\/td>\n<td>You need to discover and govern <em>data assets<\/em>, not just accounts<\/td>\n<\/tr>\n<tr>\n<td><strong>Azure Storage Explorer<\/strong><\/td>\n<td>Interactive per-account exploration<\/td>\n<td>Great UI for ad-hoc browsing<\/td>\n<td>Not estate-wide governance; manual<\/td>\n<td>You need developer\/operator tooling for a small set of accounts<\/td>\n<\/tr>\n<tr>\n<td><strong>AWS: Resource Explorer + Config + S3 Inventory<\/strong><\/td>\n<td>Multi-account AWS discovery<\/td>\n<td>Mature governance ecosystem<\/td>\n<td>Different cloud; not Azure<\/td>\n<td>If your storage estate is on AWS<\/td>\n<\/tr>\n<tr>\n<td><strong>GCP: Cloud Asset Inventory + Org Policy<\/strong><\/td>\n<td>GCP resource discovery<\/td>\n<td>Org-wide inventory<\/td>\n<td>Different cloud; not Azure<\/td>\n<td>If your storage estate is on GCP<\/td>\n<\/tr>\n<tr>\n<td><strong>Open-source: custom scripts (Terraform state, ARM calls)<\/strong><\/td>\n<td>Highly tailored needs<\/td>\n<td>Full control<\/td>\n<td>Maintenance burden, brittle, slower at scale<\/td>\n<td>When built-in tools can\u2019t meet niche requirements and you can staff maintenance<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">15. Real-World Example<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Enterprise example (regulated industry)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> A bank has 40 subscriptions and hundreds of storage accounts. Audit findings show inconsistent network controls and missing ownership tags.<\/li>\n<li><strong>Proposed architecture:<\/strong><\/li>\n<li>Management group hierarchy by environment (prod\/nonprod)<\/li>\n<li>Azure Policy initiative for storage baseline (deny public blob access, require HTTPS, enforce tags)<\/li>\n<li>Azure Resource Graph scheduled queries (weekly) exported to a secure reporting storage account<\/li>\n<li>Central Log Analytics workspace for Activity Log export and discovery run logs<\/li>\n<li>Optional Defender for Cloud for prioritized recommendations<\/li>\n<li><strong>Why Azure Storage Discovery was chosen:<\/strong> It leverages native Azure governance and scales across subscriptions without building a custom crawler.<\/li>\n<li><strong>Expected outcomes:<\/strong><\/li>\n<li>Complete storage inventory within days<\/li>\n<li>Reduced exposure risk (public access eliminated in prod)<\/li>\n<li>Faster audits with repeatable evidence exports<\/li>\n<li>Clear ownership and remediation workflows<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Startup\/small-team example<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Problem:<\/strong> A SaaS startup runs prod and staging in separate subscriptions. Engineers occasionally create storage accounts without tagging, and no one tracks security settings consistently.<\/li>\n<li><strong>Proposed architecture:<\/strong><\/li>\n<li>A small set of Resource Graph queries stored in Git<\/li>\n<li>A lightweight weekly GitHub Actions\/Azure DevOps pipeline that runs <code>az graph query<\/code> and posts results to Teams\/Slack (via webhook) or opens issues<\/li>\n<li>A minimal Azure Policy assignment that enforces tags in production<\/li>\n<li><strong>Why Azure Storage Discovery was chosen:<\/strong> Low operational overhead, no heavy tooling, quick visibility.<\/li>\n<li><strong>Expected outcomes:<\/strong><\/li>\n<li>Reduced sprawl and faster cleanup<\/li>\n<li>Better cost attribution<\/li>\n<li>Fewer security surprises as the team grows<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">16. FAQ<\/h2>\n\n\n\n<p>1) <strong>Is Azure Storage Discovery a standalone Azure product?<\/strong><br\/>\nNot typically. \u201cAzure Storage Discovery\u201d is commonly implemented using Azure Resource Graph + Azure Policy + Azure Monitor, optionally Defender for Cloud and Purview. Verify whether Microsoft has introduced a first-class product with this exact name in current docs.<\/p>\n\n\n\n<p>2) <strong>What\u2019s the difference between discovering storage accounts and discovering data inside them?<\/strong><br\/>\nStorage account discovery is <strong>control-plane<\/strong> inventory (resources and settings). Data discovery is <strong>data-plane<\/strong> (files\/blobs content) and usually requires tools like <strong>Microsoft Purview<\/strong>.<\/p>\n\n\n\n<p>3) <strong>Do I need Contributor permissions to do discovery?<\/strong><br\/>\nNo. For control-plane inventory, <strong>Reader<\/strong> access is usually sufficient. For data-plane enumeration (like listing containers), you need <strong>Storage Blob Data Reader\/Contributor<\/strong> roles.<\/p>\n\n\n\n<p>4) <strong>Can Azure Resource Graph list blob containers?<\/strong><br\/>\nNo. ARG queries ARM metadata about resources. Containers are data-plane entities; list them using Storage APIs\/CLI with data-plane permissions.<\/p>\n\n\n\n<p>5) <strong>Why do some properties show as null in Resource Graph?<\/strong><br\/>\nARG projections can vary, and some properties may not be indexed or returned consistently. For critical checks, confirm with <code>az storage account show<\/code> or ARM REST. Also verify property names and availability in official docs.<\/p>\n\n\n\n<p>6) <strong>How do I discover storage accounts across all subscriptions?<\/strong><br\/>\nEnsure you have Reader access across the subscriptions and query <code>microsoft.storage\/storageaccounts<\/code> with Azure Resource Graph.<\/p>\n\n\n\n<p>7) <strong>How do I limit discovery to production only?<\/strong><br\/>\nUse scoping (management group\/subscription selection) and\/or filter by tags like <code>Environment=prod<\/code> in Resource Graph queries.<\/p>\n\n\n\n<p>8) <strong>Does discovery work if storage accounts use private endpoints only?<\/strong><br\/>\nControl-plane discovery still works. Data-plane discovery (container listing) may fail unless your discovery runner has network access via the private endpoint path.<\/p>\n\n\n\n<p>9) <strong>How often should we run discovery?<\/strong><br\/>\nStart weekly or daily for compliance reporting. Increase frequency only for sensitive environments or when you\u2019re actively remediating drift. Avoid high-frequency data-plane scans.<\/p>\n\n\n\n<p>10) <strong>Can Azure Policy block public blob access?<\/strong><br\/>\nOften yes through built-in or custom policy definitions, but coverage and enforcement capabilities can vary. Always test and verify policy behavior in your tenant.<\/p>\n\n\n\n<p>11) <strong>How do we track \u201cwho changed network rules\u201d on a storage account?<\/strong><br\/>\nUse Azure Activity Log for control-plane changes and export it to Log Analytics for retention and correlation.<\/p>\n\n\n\n<p>12) <strong>Is using storage account keys acceptable for discovery scripts?<\/strong><br\/>\nIt\u2019s strongly discouraged. Prefer Azure AD authentication and managed identities to avoid secret sprawl and improve auditability.<\/p>\n\n\n\n<p>13) <strong>How do we integrate discovery findings into ticketing?<\/strong><br\/>\nUse automation (Functions\/Logic Apps) to run queries, filter results, and create tickets in your ITSM tool with resource IDs and remediation guidance.<\/p>\n\n\n\n<p>14) <strong>Can we use discovery to find \u201cunused\u201d storage accounts?<\/strong><br\/>\nPartially. Discovery can show accounts and tags; \u201cunused\u201d often requires combining inventory with metrics\/logs (transactions over time) and business context.<\/p>\n\n\n\n<p>15) <strong>What\u2019s the fastest way to get started?<\/strong><br\/>\nStart with Azure Resource Graph queries in the Azure Portal Resource Graph Explorer or Azure CLI, then add Azure Policy for enforcement once you understand current posture.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">17. Top Online Resources to Learn Azure Storage Discovery<\/h2>\n\n\n\n<p>Because \u201cAzure Storage Discovery\u201d is implemented via multiple Azure services, the best resources are the official docs for those building blocks.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Resource Type<\/th>\n<th>Name<\/th>\n<th>Why It Is Useful<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Official documentation<\/td>\n<td>Azure Resource Graph Overview \u2014 https:\/\/learn.microsoft.com\/azure\/governance\/resource-graph\/overview<\/td>\n<td>Core service for cross-subscription resource discovery and querying<\/td>\n<\/tr>\n<tr>\n<td>Official tutorial<\/td>\n<td>First query with Azure Resource Graph (Azure CLI) \u2014 https:\/\/learn.microsoft.com\/azure\/governance\/resource-graph\/first-query-azurecli<\/td>\n<td>Step-by-step for executing ARG queries via CLI<\/td>\n<\/tr>\n<tr>\n<td>Official documentation<\/td>\n<td>Azure Policy Overview \u2014 https:\/\/learn.microsoft.com\/azure\/governance\/policy\/overview<\/td>\n<td>Governance and compliance engine to audit\/enforce storage standards<\/td>\n<\/tr>\n<tr>\n<td>Official guidance<\/td>\n<td>Assign a policy (Portal) \u2014 https:\/\/learn.microsoft.com\/azure\/governance\/policy\/assign-policy-portal<\/td>\n<td>Practical steps to apply policies at the right scope<\/td>\n<\/tr>\n<tr>\n<td>Official documentation<\/td>\n<td>Azure Storage security baseline (concepts vary by service) \u2014 start at https:\/\/learn.microsoft.com\/azure\/storage\/<\/td>\n<td>Entry point for storage security, networking, and configuration references<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure Storage pricing \u2014 https:\/\/azure.microsoft.com\/pricing\/details\/storage\/<\/td>\n<td>Understand storage capacity, transaction, and transfer costs<\/td>\n<\/tr>\n<tr>\n<td>Official pricing<\/td>\n<td>Azure Monitor pricing \u2014 https:\/\/azure.microsoft.com\/pricing\/details\/monitor\/<\/td>\n<td>Understand log ingestion\/retention costs which affect discovery operations<\/td>\n<\/tr>\n<tr>\n<td>Official documentation<\/td>\n<td>Azure Monitor overview \u2014 https:\/\/learn.microsoft.com\/azure\/azure-monitor\/overview<\/td>\n<td>Operational monitoring foundation (logs\/metrics\/alerts)<\/td>\n<\/tr>\n<tr>\n<td>Official security<\/td>\n<td>Microsoft Defender for Cloud docs \u2014 https:\/\/learn.microsoft.com\/azure\/defender-for-cloud\/<\/td>\n<td>Security posture management and recommendations (optional)<\/td>\n<\/tr>\n<tr>\n<td>Official data governance<\/td>\n<td>Microsoft Purview documentation \u2014 https:\/\/learn.microsoft.com\/purview\/<\/td>\n<td>Data catalog and data discovery inside storage (optional)<\/td>\n<\/tr>\n<tr>\n<td>Tooling<\/td>\n<td>Azure Storage Explorer \u2014 https:\/\/learn.microsoft.com\/azure\/storage\/common\/storage-explorer<\/td>\n<td>Practical GUI tool for per-account exploration (not estate-wide discovery)<\/td>\n<\/tr>\n<tr>\n<td>Architecture guidance<\/td>\n<td>Azure Architecture Center \u2014 https:\/\/learn.microsoft.com\/azure\/architecture\/<\/td>\n<td>Patterns and reference architectures that influence storage governance decisions<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">18. Training and Certification Providers<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Institute<\/th>\n<th>Suitable Audience<\/th>\n<th>Likely Learning Focus<\/th>\n<th>Mode<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>DevOpsSchool.com<\/td>\n<td>DevOps engineers, SREs, platform teams<\/td>\n<td>Azure operations, DevOps practices, automation, governance fundamentals<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>ScmGalaxy.com<\/td>\n<td>Beginners to intermediate engineers<\/td>\n<td>SCM\/DevOps concepts, CI\/CD, cloud fundamentals<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.scmgalaxy.com\/<\/td>\n<\/tr>\n<tr>\n<td>CLoudOpsNow.in<\/td>\n<td>Cloud operations teams<\/td>\n<td>CloudOps practices, monitoring, operational readiness<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.cloudopsnow.in\/<\/td>\n<\/tr>\n<tr>\n<td>SreSchool.com<\/td>\n<td>SREs and reliability-focused teams<\/td>\n<td>SRE practices, monitoring, incident response, reliability engineering<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.sreschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>AiOpsSchool.com<\/td>\n<td>Ops teams adopting automation<\/td>\n<td>AIOps concepts, automation, monitoring\/alerting workflows<\/td>\n<td>Check website<\/td>\n<td>https:\/\/www.aiopsschool.com\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">19. Top Trainers<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Platform\/Site<\/th>\n<th>Likely Specialization<\/th>\n<th>Suitable Audience<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>RajeshKumar.xyz<\/td>\n<td>DevOps\/cloud training content (verify current offerings)<\/td>\n<td>Engineers seeking guided learning<\/td>\n<td>https:\/\/rajeshkumar.xyz\/<\/td>\n<\/tr>\n<tr>\n<td>devopstrainer.in<\/td>\n<td>DevOps training and coaching (verify specialization)<\/td>\n<td>Beginners to intermediate DevOps learners<\/td>\n<td>https:\/\/www.devopstrainer.in\/<\/td>\n<\/tr>\n<tr>\n<td>devopsfreelancer.com<\/td>\n<td>Freelance DevOps guidance (verify services)<\/td>\n<td>Teams needing short-term help or mentoring<\/td>\n<td>https:\/\/www.devopsfreelancer.com\/<\/td>\n<\/tr>\n<tr>\n<td>devopssupport.in<\/td>\n<td>DevOps support\/training resources (verify current scope)<\/td>\n<td>Ops teams needing practical support<\/td>\n<td>https:\/\/www.devopssupport.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">20. Top Consulting Companies<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Company Name<\/th>\n<th>Likely Service Area<\/th>\n<th>Where They May Help<\/th>\n<th>Consulting Use Case Examples<\/th>\n<th>Website URL<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>cotocus.com<\/td>\n<td>Cloud\/DevOps consulting (verify exact portfolio)<\/td>\n<td>Cloud architecture, automation, governance implementations<\/td>\n<td>Implement Resource Graph reporting + policy baselines; set up monitoring exports<\/td>\n<td>https:\/\/www.cotocus.com\/<\/td>\n<\/tr>\n<tr>\n<td>DevOpsSchool.com<\/td>\n<td>DevOps\/cloud consulting and training (verify service catalog)<\/td>\n<td>DevOps transformation, platform engineering support<\/td>\n<td>Build discovery automation pipelines; implement tagging\/policy governance<\/td>\n<td>https:\/\/www.devopsschool.com\/<\/td>\n<\/tr>\n<tr>\n<td>DEVOPSCONSULTING.IN<\/td>\n<td>DevOps consulting (verify scope)<\/td>\n<td>DevOps processes, CI\/CD, operations improvements<\/td>\n<td>Create operational dashboards; automate compliance reporting for storage<\/td>\n<td>https:\/\/www.devopsconsulting.in\/<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">21. Career and Learning Roadmap<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What to learn before this service<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure fundamentals: subscriptions, resource groups, regions<\/li>\n<li>Azure Storage basics: storage accounts, Blob\/File, replication options, access tiers<\/li>\n<li>Azure identity and access: RBAC scopes, role assignments, managed identities<\/li>\n<li>Networking basics: private endpoints, firewall rules, DNS basics<\/li>\n<li>Azure CLI basics (or PowerShell)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">What to learn after this service<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Azure Policy authoring (custom definitions), initiatives, and remediation tasks<\/li>\n<li>Azure Monitor deep dive: diagnostic settings, workbooks, alerting strategy<\/li>\n<li>Microsoft Defender for Cloud recommendations and regulatory compliance<\/li>\n<li>Microsoft Purview for data discovery, cataloging, and classification<\/li>\n<li>Automation patterns: Functions\/Logic Apps, CI\/CD for governance as code<\/li>\n<li>FinOps practices: budgets, tagging strategy, cost anomaly detection<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Job roles that use it<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Cloud engineer \/ platform engineer<\/li>\n<li>DevOps engineer<\/li>\n<li>Site Reliability Engineer (SRE)<\/li>\n<li>Cloud security engineer \/ governance specialist<\/li>\n<li>FinOps analyst (in partnership with engineering)<\/li>\n<li>Solutions architect<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Certification path (Azure)<\/h3>\n\n\n\n<p>Relevant Microsoft certifications (verify latest names\/requirements):\n&#8211; Azure Fundamentals (AZ-900)\n&#8211; Azure Administrator (AZ-104)\n&#8211; Azure Security Engineer (AZ-500)\n&#8211; Azure Solutions Architect Expert (AZ-305)\n&#8211; Specialty data governance\/security credentials depending on your track (Purview-related content appears across data\/security learning paths; verify current official certification options)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Project ideas for practice<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Build a \u201cStorage Discovery Dashboard\u201d:<\/li>\n<li>ARG queries + export to Log Analytics custom table (or CSV in a secured storage account)<\/li>\n<li>Workbook\/Power BI dashboard for posture<\/li>\n<li>Implement a storage baseline:<\/li>\n<li>Tags enforcement<\/li>\n<li>HTTPS-only and TLS baseline<\/li>\n<li>Deny blob public access in production<\/li>\n<li>Create a remediation pipeline:<\/li>\n<li>Discover noncompliant accounts<\/li>\n<li>Open tickets with clear remediation steps<\/li>\n<li>Validate closure via compliance re-check<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">22. Glossary<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Azure Storage Account:<\/strong> The top-level Azure resource that provides Blob, File, Queue, and Table services.<\/li>\n<li><strong>Control Plane:<\/strong> Management layer (ARM) used to create\/configure resources (eg, storage account properties).<\/li>\n<li><strong>Data Plane:<\/strong> Service endpoints used to access data (eg, listing blobs in a container).<\/li>\n<li><strong>Azure Resource Manager (ARM):<\/strong> The management API layer for Azure resources.<\/li>\n<li><strong>Azure Resource Graph (ARG):<\/strong> Service for fast querying of ARM resource metadata across subscriptions using KQL.<\/li>\n<li><strong>Kusto Query Language (KQL):<\/strong> Query language used by ARG (and Azure Data Explorer\/Log Analytics).<\/li>\n<li><strong>Azure Policy:<\/strong> Governance service to audit\/enforce rules on Azure resources.<\/li>\n<li><strong>RBAC (Role-Based Access Control):<\/strong> Authorization model in Azure assigning roles at scopes.<\/li>\n<li><strong>Managed Identity:<\/strong> An Azure AD identity for Azure services (no stored credentials) used to access resources securely.<\/li>\n<li><strong>Private Endpoint \/ Private Link:<\/strong> Private IP network interface for accessing Azure services privately from a VNet.<\/li>\n<li><strong>Diagnostic Settings:<\/strong> Configuration to send resource logs\/metrics to destinations like Log Analytics, Event Hubs, or Storage.<\/li>\n<li><strong>Log Analytics Workspace:<\/strong> Azure Monitor component storing logs for query and analysis.<\/li>\n<li><strong>Public Network Access:<\/strong> Setting controlling whether a resource is accessible via public endpoints.<\/li>\n<li><strong>Blob Public Access:<\/strong> Capability allowing containers\/blobs to be publicly readable if configured.<\/li>\n<li><strong>SKU\/Replication (LRS\/ZRS\/GRS):<\/strong> Storage redundancy options impacting durability, availability, and cost.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">23. Summary<\/h2>\n\n\n\n<p>Azure Storage Discovery (Azure) is the practical, Azure-native approach to <strong>discovering and inventorying Azure Storage resources<\/strong>\u2014most commonly implemented with <strong>Azure Resource Graph<\/strong> for fast estate-wide queries, <strong>Azure Policy<\/strong> for audit\/enforcement, and <strong>Azure Monitor<\/strong> for operational visibility. It matters because storage sprawl and misconfiguration are common, and teams need repeatable ways to identify exposure risks, enforce governance (tags, network rules, TLS), and control cost.<\/p>\n\n\n\n<p>Cost-wise, the biggest drivers are usually <strong>Storage transactions<\/strong> if you do heavy data-plane enumeration and <strong>Log Analytics ingestion\/retention<\/strong> if you enable extensive diagnostics. Security-wise, the key is separating control-plane vs data-plane permissions, using <strong>least privilege<\/strong>, and preferring <strong>Azure AD + managed identities<\/strong> over account keys.<\/p>\n\n\n\n<p>Use Azure Storage Discovery when you need scalable inventory, compliance, and operational insight across subscriptions. Next, deepen your implementation by productionizing a query pack, adding policy initiatives for storage baselines, and optionally integrating Defender for Cloud and Purview depending on whether your goal is security posture management or data governance.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Storage<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[40,7],"tags":[],"class_list":["post-523","post","type-post","status-publish","format-standard","hentry","category-azure","category-storage"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/523","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=523"}],"version-history":[{"count":0,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/523\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=523"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=523"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=523"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}