├── images ├── row-overview.png ├── row-resources.png ├── row-statistics.png ├── row-managed-disks.png ├── add-role-assignment.png ├── byo-grafana-import-dashboard-01.png ├── byo-grafana-import-dashboard-02.png ├── managed-grafana-managed-identity.png ├── byo-grafana-service-principal-login.png ├── managed-grafana-import-dashboard-01.png ├── managed-grafana-import-dashboard-02.png └── managed-gragana-managed-identity-login.png ├── CHANGELOG.md ├── .github ├── CODE_OF_CONDUCT.md ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── LICENSE.md ├── CONTRIBUTING.md └── README.md /images/row-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/row-overview.png -------------------------------------------------------------------------------- /images/row-resources.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/row-resources.png -------------------------------------------------------------------------------- /images/row-statistics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/row-statistics.png -------------------------------------------------------------------------------- /images/row-managed-disks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/row-managed-disks.png -------------------------------------------------------------------------------- /images/add-role-assignment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/add-role-assignment.png -------------------------------------------------------------------------------- /images/byo-grafana-import-dashboard-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/byo-grafana-import-dashboard-01.png -------------------------------------------------------------------------------- /images/byo-grafana-import-dashboard-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/byo-grafana-import-dashboard-02.png -------------------------------------------------------------------------------- /images/managed-grafana-managed-identity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/managed-grafana-managed-identity.png -------------------------------------------------------------------------------- /images/byo-grafana-service-principal-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/byo-grafana-service-principal-login.png -------------------------------------------------------------------------------- /images/managed-grafana-import-dashboard-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/managed-grafana-import-dashboard-01.png -------------------------------------------------------------------------------- /images/managed-grafana-import-dashboard-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/managed-grafana-import-dashboard-02.png -------------------------------------------------------------------------------- /images/managed-gragana-managed-identity-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-orphan-resources-grafana-dashboard/HEAD/images/managed-gragana-managed-identity-login.png -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [project-title] Changelog 2 | 3 | 4 | # x.y.z (yyyy-mm-dd) 5 | 6 | *Features* 7 | * ... 8 | 9 | *Bug Fixes* 10 | * ... 11 | 12 | *Breaking Changes* 13 | * ... 14 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | > Please provide us with the following information: 5 | > --------------------------------------------------------------- 6 | 7 | ### This issue is for a: (mark with an `x`) 8 | ``` 9 | - [ ] bug report -> please search issues before submitting 10 | - [ ] feature request 11 | - [ ] documentation issue or request 12 | - [ ] regression (a behavior that used to work and stopped in a new release) 13 | ``` 14 | 15 | ### Minimal steps to reproduce 16 | > 17 | 18 | ### Any log messages given by the failure 19 | > 20 | 21 | ### Expected/desired behavior 22 | > 23 | 24 | ### OS and Version? 25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?) 26 | 27 | ### Versions 28 | > 29 | 30 | ### Mention any other details that might be useful 31 | 32 | > --------------------------------------------------------------- 33 | > Thanks! We'll be in touch soon. 34 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Purpose 2 | 3 | * ... 4 | 5 | ## Does this introduce a breaking change? 6 | 7 | ``` 8 | [ ] Yes 9 | [ ] No 10 | ``` 11 | 12 | ## Pull Request Type 13 | What kind of change does this Pull Request introduce? 14 | 15 | 16 | ``` 17 | [ ] Bugfix 18 | [ ] Feature 19 | [ ] Code style update (formatting, local variables) 20 | [ ] Refactoring (no functional changes, no api changes) 21 | [ ] Documentation content changes 22 | [ ] Other... Please describe: 23 | ``` 24 | 25 | ## How to Test 26 | * Get the code 27 | 28 | ``` 29 | git clone [repo-address] 30 | cd [repo-name] 31 | git checkout [branch-name] 32 | npm install 33 | ``` 34 | 35 | * Test the code 36 | 37 | ``` 38 | ``` 39 | 40 | ## What to Check 41 | Verify that the following are valid 42 | * ... 43 | 44 | ## Other Information 45 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to [project-title] 2 | 3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 5 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 6 | 7 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 8 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 9 | provided by the bot. You will only need to do this once across all repos using our CLA. 10 | 11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 14 | 15 | - [Code of Conduct](#coc) 16 | - [Issues and Bugs](#issue) 17 | - [Feature Requests](#feature) 18 | - [Submission Guidelines](#submit) 19 | 20 | ## Code of Conduct 21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 22 | 23 | ## Found an Issue? 24 | If you find a bug in the source code or a mistake in the documentation, you can help us by 25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can 26 | [submit a Pull Request](#submit-pr) with a fix. 27 | 28 | ## Want a Feature? 29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub 30 | Repository. If you would like to *implement* a new feature, please submit an issue with 31 | a proposal for your work first, to be sure that we can use it. 32 | 33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr). 34 | 35 | ## Submission Guidelines 36 | 37 | ### Submitting an Issue 38 | Before you submit an issue, search the archive, maybe your question was already answered. 39 | 40 | If your issue appears to be a bug, and hasn't been reported, open a new issue. 41 | Help us to maximize the effort we can spend fixing issues and adding new 42 | features, by not reporting duplicate issues. Providing the following information will increase the 43 | chances of your issue being dealt with quickly: 44 | 45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps 46 | * **Version** - what version is affected (e.g. 0.1.2) 47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you 48 | * **Browsers and Operating System** - is this a problem with all browsers? 49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps 50 | * **Related Issues** - has a similar issue been reported before? 51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be 52 | causing the problem (line of code or commit) 53 | 54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new]. 55 | 56 | ### Submitting a Pull Request (PR) 57 | Before you submit your Pull Request (PR) consider the following guidelines: 58 | 59 | * Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR 60 | that relates to your submission. You don't want to duplicate effort. 61 | 62 | * Make your changes in a new git fork: 63 | 64 | * Commit your changes using a descriptive commit message 65 | * Push your fork to GitHub: 66 | * In GitHub, create a pull request 67 | * If we suggest changes then: 68 | * Make the required updates. 69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request): 70 | 71 | ```shell 72 | git rebase master -i 73 | git push -f 74 | ``` 75 | 76 | That's it! Thank you for your contribution! 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | languages: 4 | - json 5 | products: 6 | - azure 7 | name: Azure Orphan Resources Grafana Dashboard 8 | description: This Grafana dashboard offers a centralized view of Azure orphan resources that can be safely removed to reduce the overall cost of owning your Azure subscriptions. 9 | urlFragment: azure-orphan-resources-grafana-dashboard 10 | --- 11 | 12 | # Azure Orphan Resources Grafana Dashboard 13 | 14 | In cloud computing, it is crucial to follow best practices when building a reliable, high-performing, and secure environment. However, it is equally important to implement a strategy aimed at reducing the total cost of ownership. In this context, this Grafana dashboard offers a centralized view of Azure orphan resources that can be safely removed. By identifying and removing these unnecessary resources, you can effectively decrease the overall cost associated with maintaining their Azure subscriptions and increase the operational efficiency. 15 | 16 | ![Statistics](./images/row-overview.png) 17 | ![Statistics](./images/row-statistics.png) 18 | ![Statistics](./images/row-managed-disks.png) 19 | 20 | This dashboard is influenced by the [Azure Orphaned Resources 2.0](https://github.com/dolevshor/azure-orphan-resources/tree/main) project developed by my colleague Dolev Shor. It incorporates and integrates some of the queries he designed for his Azure workbook, which can be created and utilized within the Azure Portal. You can refer to the [Azure workbook documentation](https://learn.microsoft.com/en-us/azure/azure-monitor/visualize/workbooks-overview) to learn more about creating and utilizing workbooks in the Azure Portal. 21 | 22 | ## Prerequisites 23 | 24 | You can host the Grafana dashboard in Azure Managed Grafana, your own Grafana installation in an AKS cluster, or any Kubernetes cluster with access to the public internet. 25 | 26 | ## Implementation 27 | 28 | The dashboard performs a series of queries using the [Kusto Query Language](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/) and [Azure Resource Graph](https://learn.microsoft.com/en-us/azure/governance/resource-graph/overview) to individuate unused, orphan resources that can be safely removed from your Azure subscriptions without impacting the operability of your cloud hosted workloads. Azure Resource Graph is an Azure service designed to extend Azure Resource Management by providing efficient and performant resource exploration with the ability to query at scale across a given set of subscriptions so that you can effectively govern your environment. 29 | 30 | For more information Azure Resource Graph, you can refer to the following links: 31 | 32 | - [Azure Resource Graph Overview](https://learn.microsoft.com/en-us/azure/governance/resource-graph/overview) 33 | - [Query Resource Changes](https://learn.microsoft.com/en-us/azure/governance/resource-graph/how-to/get-resource-changes) 34 | 35 | Here is the list of the resources currently supported by the dashboard: 36 | 37 | - App Service Plans 38 | - App Service Environments 39 | - Availability Sets 40 | - Managed Disks 41 | - Load Balancers 42 | - Route Tables 43 | - Application Gateways 44 | - Application Gateway WAF Policies 45 | - Front Door WAF Policies 46 | - Traffic Manager Profiles 47 | - Virtual Networks 48 | - Subnets 49 | - Network Interfaces 50 | - Virtual Network Gateways 51 | - Network Security Groups 52 | - NAT Gateways 53 | - Public IP Addresses 54 | - Public IP Prefixes 55 | - IP Groups 56 | - Private DNS Zones 57 | - Private Endpoints 58 | - Private Link Services 59 | - SQL Elastic Pools 60 | - Resource Groups 61 | 62 | Please note that all the resources mentioned above come with an associated cost. Some resources like Availability Sets, Route Tables, Subnets, IP Groups, and Resource Groups are available free of charge. 63 | 64 | ## Importing the dashboard into Azure Managed Grafana 65 | 66 | To import the dashboard into [Azure Managed Grafana](https://learn.microsoft.com/en-us/azure/managed-grafana/overview), follow these steps: 67 | 68 | 1. Go to the Azure Portal and navigate to your Azure Managed Grafana resource. 69 | 2. Click `Identity` under `Settings`. 70 | 3. Ensure that the system-assigned managed identity is enabled. 71 | ![Managed Identity](./images/managed-grafana-managed-identity.png) 72 | 4. Click on the `Azure role assignments` button. 73 | 5. Assign the [Monitoring Reader](https://learn.microsoft.com/en-us/azure/azure-monitor/roles-permissions-security#monitoring-reader) role to the Grafana managed identity, scoped to your Azure subscription or Management Group. 74 | ![Managed Identity](./images/add-role-assignment.png) 75 | 6. Click on the `Endpoint` URL on the `Overview` page of your Azure Managed Grafana resource. 76 | 7. In the Grafana dashboard, go to `Connections` and ensure that you have an `Azure Monitor` datasource. If not, create one and select `Managed Identity` as the authentication mechanism. 77 | 8. Click on the `Load subscriptions` button to test the data source. 78 | 9. Go to `Dashboards`, click on `New`, and then select `Import`. 79 | 10. Upload the dashboard JSON file or copy and paste the JSON code into the textbox, then click the `Load` button. 80 | ![Upload Dashboard to Azure Managed Grafana](./images/managed-grafana-import-dashboard-01.png) 81 | 11. Choose a category for the dashboard and click the `Import` button. 82 | [Upload Dashboard to Azure Managed Grafana](./images/managed-grafana-import-dashboard-02.png) 83 | 84 | ## Importing the Dashboard into a Bring Your Own (BYO) Grafana Installation 85 | 86 | Before importing the dashboard into your own Grafana installation, you need to create a service principal under your Microsoft Azure AD account and assign the [Monitoring Reader](https://learn.microsoft.com/en-us/azure/azure-monitor/roles-permissions-security#monitoring-reader) role to it. Once done, follow these steps: 87 | 88 | 1. In the Grafana dashboard, go to `Connections` and ensure that you have an `Azure Monitor` datasource. If not, create one and specify the `tenant id`, `client Id`, and `client secret` of your service princiapl as shown in the following picture: 89 | ![Service Principal](./images/byo-grafana-service-principal-login.png) 90 | 2. Click on the `Load subscriptions` button to test the data source. 91 | 3. Go to `Dashboards`, click on `New`, and then select `Import`. 92 | 4. Upload the dashboard JSON file or copy and paste the JSON code into the textbox, then click the `Load` button. 93 | ![Upload Dashboard to BYO Grafana](./images/byo-grafana-import-dashboard-01.png) 94 | 5. Choose a category for the dashboard and click the `Import` button. 95 | ![Upload Dashboard to BYO Grafana](./images/byo-grafana-import-dashboard-02.png) 96 | 97 | --------------------------------------------------------------------------------