{"id":2609,"date":"2023-07-26T16:19:18","date_gmt":"2023-07-26T15:19:18","guid":{"rendered":"https:\/\/mortenknudsen.net\/?p=2609"},"modified":"2023-07-26T16:27:17","modified_gmt":"2023-07-26T15:27:17","slug":"azure-backup-do-i-have-resources-not-protected-by-backup","status":"publish","type":"post","link":"https:\/\/mortenknudsen.net\/?p=2609","title":{"rendered":"Azure Backup: Do I have resources NOT protected by backup?"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This blog will show you how you can automate an overview using <strong>Kusto queries<\/strong> against <strong>Azure Resource Graph<\/strong> <strong>(ARG)<\/strong> to show specific resources <strong>NOT<\/strong> <strong>being protected<\/strong> by <strong>Azure backup services<\/strong>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As part of Azure Backup services, Microsoft are offering 2 services which will keep your backups in a manageable vault: <strong>Azure Recovery Services Vaults<\/strong> and <strong>Azure Backup Vaults<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Supported data sources by Azure Backups vaults:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-regular has-small-font-size\"><table><tbody><tr><td><strong>Recovery Services Vault<\/strong><\/td><td><strong>Backup Vault<\/strong><\/td><\/tr><tr><td>Azure Virtual machines<br>SQL in Azure VM<br>Azure Files (Azure Storage)<br>SAP HANA in Azure VM<br>Azure Backup Server<br>Azure Backup Agent<br>DPM<\/td><td>&nbsp;Azure Disks<br>&nbsp;Azure Blobs (Azure Storage)<br>&nbsp;Azure Database for PostgreSQL servers<br>&nbsp;Kubernetes Services (Preview)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Of course you can choose to protect a resource by other 3rd party solutions &#8211; or you can choose not to protect it. But things can also be forgotten, if your environment is not managed through automation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to see resources NOT protected using the GUI?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Go into <strong>Azure Backup Center<\/strong>, and choose <strong>Protectable datasources<\/strong> &#8211; and now you can filter data source type and see resources NOT configured for backup.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"491\" src=\"https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/overview-1024x491.jpg\" alt=\"\" class=\"wp-image-2610\" srcset=\"https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/overview-1024x491.jpg 1024w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/overview-300x144.jpg 300w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/overview-768x369.jpg 768w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/overview-1536x737.jpg 1536w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/overview.jpg 1948w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to see resources NOT protected using Kusto query?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">As the data is stored inside Azure Resource Graph (ARG), you can query for the results, which means that you can use it as part of monitoring for non-protected resources.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you continue reading, I have included modified kusto queries, which will cover 4 scenarios:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>Azure VMs with no SQL databases configured for backup<\/td><\/tr><tr><td>Azure Virtual machines not configured for backup<\/td><\/tr><tr><td>Storage accounts with no Azure Blobs configured for backup<\/td><\/tr><tr><td>Managed Kubernetes Clusters with no resources configured for backup<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">You can find more scenarios using the &#8216;Open Query&#8217; in the GUI for the specific workloads you are interested in.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"841\" height=\"231\" src=\"https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query.jpg\" alt=\"\" class=\"wp-image-2611\" srcset=\"https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query.jpg 841w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query-300x82.jpg 300w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query-768x211.jpg 768w\" sizes=\"auto, (max-width: 841px) 100vw, 841px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"412\" src=\"https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query-result-1024x412.jpg\" alt=\"\" class=\"wp-image-2612\" srcset=\"https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query-result-1024x412.jpg 1024w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query-result-300x121.jpg 300w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query-result-768x309.jpg 768w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query-result-1536x617.jpg 1536w, https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/query-result-2048x823.jpg 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Azure VMs with no SQL databases configured for backup<\/h2>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>Resources \n    | where type in~ ('microsoft.compute\/virtualmachines','microsoft.classiccompute\/virtualmachines','microsoft.compute\/virtualmachines\/extensions')\n    | extend armResourceId = id  \n    | where name =~ 'SqlIaasExtension' \n    | where properties.type == 'SqlIaaSAgent' \n    | extend armResourceId = split(armResourceId,'\/extensions\/')&#91;0] \n    | extend name = split(armResourceId, '\/virtualMachines\/')&#91;1]\n    | extend resourceId=tolower(armResourceId) \n    | join kind = leftouter ( RecoveryServicesResources\n            | where type == \"microsoft.recoveryservices\/vaults\/backupfabrics\/protectioncontainers\/protecteditems\"\n            | where properties.backupManagementType == \"AzureWorkload\"\n            | where properties.workloadType in~ (\"SQLDataBase\")\n            | project resourceId = tolower(tostring(properties.sourceResourceId)), backupItemid = id, isBackedUp = isnotempty(id) )\n        on resourceId\n    | extend isProtected = isnotempty(backupItemid) | where (isProtected == (0))\n    | join kind=inner (resourcecontainers\n            | where type == \"microsoft.resources\/subscriptions\"\n            | project subscriptionId, subscriptionName=name )\n        on $left.subscriptionId == $right.subscriptionId\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Azure Virtual machines not configured for backup<\/h2>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>Resources \n| where type in~ ('microsoft.compute\/virtualmachines','microsoft.classiccompute\/virtualmachines') \n| extend armResourceId = id  \n| extend resourceId=tolower(armResourceId)\n| join kind = leftouter ( RecoveryServicesResources\n        | where type == \"microsoft.recoveryservices\/vaults\/backupfabrics\/protectioncontainers\/protecteditems\"\n        | where properties.backupManagementType == \"AzureIaasVM\"\n        | where properties.workloadType in~ (\"VM\")\n        | project resourceId = tolower(tostring(properties.sourceResourceId)), backupItemid = id, isBackedUp = isnotempty(id) )\n    on resourceId\n| extend isProtected = isnotempty(backupItemid) \n| where (isProtected == (0))\n| join kind=inner (resourcecontainers\n        | where type == \"microsoft.resources\/subscriptions\"\n        | project subscriptionId, subscriptionName=name )\n    on $left.subscriptionId == $right.subscriptionId<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Storage accounts with no Azure Blobs configured for backup<\/h2>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>Resources \n| where type in~ ('microsoft.storage\/storageAccounts') \n| extend armResourceId = id  \n| where properties.isHnsEnabled != true \n| where properties.isNfsV3Enabled != true \n| where kind =~ 'StorageV2' and isnotnull(sku) and sku.tier =~ 'Standard'\n| extend resourceId=tolower(armResourceId) \n| extend extendedLocationName=extendedLocation.name \n| join kind = leftouter ( RecoveryServicesResources\n        | where type in~ (\"microsoft.dataprotection\/backupvaults\/backupinstances\", \"microsoft.dataprotection\/backupvaults\/deletedbackupinstances\")\n        | where properties.dataSourceInfo.datasourceType == \"Microsoft.Storage\/storageAccounts\/blobServices\"\n        | project resourceId = tolower(tostring(properties.dataSourceInfo.resourceID)), backupItemid = id, isBackedUp = isnotempty(id) ) \n    on resourceId\n| extend isProtected = isnotempty(backupItemid) | where (isProtected == (0))\n| join kind=inner (resourcecontainers\n        | where type == \"microsoft.resources\/subscriptions\"\n        | project subscriptionId, subscriptionName=name )\n    on $left.subscriptionId == $right.subscriptionId<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Managed Kubernetes Clusters with no resources configured for backup<\/h2>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>Resources \n| where type in~ ('Microsoft.ContainerService\/managedClusters') \n| extend armResourceId = id   \n| extend resourceId=tolower(armResourceId) \n| extend extendedLocationName=extendedLocation.name \n| join kind = leftouter ( RecoveryServicesResources\n        | where type in~ (\"microsoft.dataprotection\/backupvaults\/backupinstances\", \"microsoft.dataprotection\/backupvaults\/deletedbackupinstances\")\n        | where properties.dataSourceInfo.datasourceType == \"Microsoft.ContainerService\/managedClusters\"\n        | project resourceId = tolower(tostring(properties.dataSourceSetInfo.resourceID)), backupItemid = id, isBackedUp = isnotempty(id) ) \n    on resourceId\n| summarize backupInstancesCountByServer = count(isBackedUp) by resourceId, id, subscriptionId, name, resourceGroup, location, tostring(tags)  \n| where backupInstancesCountByServer == 0 \n| join kind=inner (resourcecontainers\n        | where type == \"microsoft.resources\/subscriptions\"\n        | project subscriptionId, subscriptionName=name )\n    on $left.subscriptionId == $right.subscriptionId<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This blog will show you how you can automate an overview using Kusto queries against Azure Resource Graph (ARG) to &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Azure Backup: Do I have resources NOT protected by backup?\" class=\"read-more button\" href=\"https:\/\/mortenknudsen.net\/?p=2609#more-2609\" aria-label=\"Read more about Azure Backup: Do I have resources NOT protected by backup?\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":2616,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"ngg_post_thumbnail":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[154,55,153,151,152,134,60],"tags":[],"class_list":["post-2609","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-automation","category-azure","category-azure-resource-graph","category-backup","category-kusto","category-mvpbuzz","category-scripting","infinite-scroll-item","resize-featured-image"],"featured_image_src":"https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/backup-restore.jpg","author_info":{"display_name":"Morten Knudsen","author_link":"https:\/\/mortenknudsen.net\/?author=1"},"jetpack_featured_media_url":"https:\/\/mortenknudsen.net\/wp-content\/uploads\/2023\/07\/backup-restore.jpg","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=\/wp\/v2\/posts\/2609","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2609"}],"version-history":[{"count":4,"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=\/wp\/v2\/posts\/2609\/revisions"}],"predecessor-version":[{"id":2618,"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=\/wp\/v2\/posts\/2609\/revisions\/2618"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=\/wp\/v2\/media\/2616"}],"wp:attachment":[{"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2609"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2609"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mortenknudsen.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2609"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}