Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 224 additions & 0 deletions cloud-access/azure-rbac.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
---
title: 'Azure RBAC Custom Roles'
description: 'How to set up Azure custom roles for OpenOps Benchmark using RBAC'
icon: 'microsoft'
---

import JoinCommunity from '/snippets/join-community.mdx'

OpenOps provides Azure custom role definitions to create RBAC roles in your Azure subscriptions with the necessary permissions to run benchmark assessments and collect cost optimization data.

## Available Custom Roles

### OpenOps Azure Benchmark Reader

Creates the `OpenOps Azure Benchmark Reader` custom role with read-only permissions for running Azure cost optimization benchmarks. This role includes:

* **Compute resources**: Virtual machines, managed disks, snapshots, and images
* **Networking**: Network interfaces and public IP addresses
* **App Services**: Web apps, App Service Plans, and App Service Environments
* **Databases**: Azure SQL servers, databases, and elastic pools
* **Cost and billing**: Cost Management queries, consumption usage details, and billing properties
* **Monitoring**: Azure Monitor metrics
* **Optimization**: Azure Advisor recommendations and metadata

**[Download Bicep template](https://openops.s3.us-east-2.amazonaws.com/OpenOpsAzureBenchmarkReader.role-definition.bicep)** | **[Download JSON template](https://openops.s3.us-east-2.amazonaws.com/OpenOpsAzureBenchmarkReader.role-definition.json)**

**Parameters:** AssignableScopes (required)

## Installation Steps

Before creating the custom role, you must configure the `AssignableScopes` parameter to specify where this role can be assigned.

### Configure AssignableScopes

Choose the appropriate scope for your deployment:

<AccordionGroup>
<Accordion title="Single subscription">
**JSON:**
```json
"AssignableScopes": [
"/subscriptions/11111111-1111-1111-1111-111111111111"
]
```

**Bicep parameter:**
```bash
--parameters assignableScopes='["/subscriptions/11111111-1111-1111-1111-111111111111"]'
```
</Accordion>

<Accordion title="Multiple subscriptions">
Use this when you want the role available in specific subscriptions but not across the entire management group.

**JSON:**
```json
"AssignableScopes": [
"/subscriptions/11111111-1111-1111-1111-111111111111",
"/subscriptions/22222222-2222-2222-2222-222222222222",
"/subscriptions/33333333-3333-3333-3333-333333333333"
]
```

**Bicep parameter:**
```bash
--parameters assignableScopes='["/subscriptions/11111111-1111-1111-1111-111111111111","/subscriptions/22222222-2222-2222-2222-222222222222","/subscriptions/33333333-3333-3333-3333-333333333333"]'
```
</Accordion>

<Accordion title="Management group" id="management-group-scope">
Use this only if you want the custom role available across the entire management group scope.

**JSON:**
```json
"AssignableScopes": [
"/providers/Microsoft.Management/managementGroups/my-management-group"
]
```

**Bicep parameter:**
```bash
--parameters assignableScopes='["/providers/Microsoft.Management/managementGroups/my-management-group"]'
```
</Accordion>
</AccordionGroup>

### Option 1: Deploy with Bicep (Recommended)

1. Update the `assignableScopes` parameter in the command below with your subscription ID(s):

```bash
az deployment sub create \
--name openops-azure-benchmark-reader-role \
--location westus2 \
--template-file "./OpenOps Azure Benchmark Reader.role-definition.bicep" \
--parameters assignableScopes='["/subscriptions/<subscription-id>"]'
```

2. For multiple subscriptions:

```bash
az deployment sub create \
--name openops-azure-benchmark-reader-role \
--location westus2 \
--template-file "./OpenOps Azure Benchmark Reader.role-definition.bicep" \
--parameters assignableScopes='["/subscriptions/sub-1","/subscriptions/sub-2"]'
```

**Notes:**
* This is a subscription-scoped deployment. For management group scope, see the [management group configuration](#management-group-scope) above

### Option 2: Deploy with Azure CLI and JSON

1. Edit the `AssignableScopes` field in `OpenOps Azure Benchmark Reader.role-definition.json` with your subscription ID(s).

2. Create the role:

```bash
az role definition create \
--role-definition "./OpenOps Azure Benchmark Reader.role-definition.json"
```

3. To update an existing role:

```bash
az role definition update \
--role-definition "./OpenOps Azure Benchmark Reader.role-definition.json"
```

## Assign the Role to a Service Principal

After creating the custom role, assign it to the service principal that OpenOps uses to connect to Azure.

### Assign at subscription scope

```bash
az role assignment create \
--assignee-object-id "<service-principal-object-id>" \
--assignee-principal-type ServicePrincipal \
--role "OpenOps Azure Benchmark Reader" \
--scope "/subscriptions/11111111-1111-1111-1111-111111111111"
```

### Assign in multiple subscriptions

Run the assignment once per subscription:

```bash
az role assignment create \
--assignee-object-id "<service-principal-object-id>" \
--assignee-principal-type ServicePrincipal \
--role "OpenOps Azure Benchmark Reader" \
--scope "/subscriptions/11111111-1111-1111-1111-111111111111"
```

```bash
az role assignment create \
--assignee-object-id "<service-principal-object-id>" \
--assignee-principal-type ServicePrincipal \
--role "OpenOps Azure Benchmark Reader" \
--scope "/subscriptions/22222222-2222-2222-2222-222222222222"
```

### Assign at management group scope

```bash
az role assignment create \
--assignee-object-id "<service-principal-object-id>" \
--assignee-principal-type ServicePrincipal \
--role "OpenOps Azure Benchmark Reader" \
--scope "/providers/Microsoft.Management/managementGroups/my-management-group"
```

## Verification

Verify the role definition was created:

```bash
az role definition list \
--name "OpenOps Azure Benchmark Reader" \
-o json
```

Check role assignments for your service principal:

```bash
az role assignment list \
--assignee "<service-principal-object-id>" \
--all \
-o table
```

## Cost Management Access

For subscription-scope cost queries, the role includes `Microsoft.CostManagement/query/action` for the POST query API.

Azure Cost Management access commonly requires related read permissions in billing and cost surfaces. This role includes:

* `Microsoft.CostManagement/query/action`
* `Microsoft.CostManagement/*/read`
* `Microsoft.Consumption/*/read`
* `Microsoft.Billing/billingPeriods/read`
* `Microsoft.Billing/billingProperty/read`
* `Microsoft.Resources/subscriptions/read`
* `Microsoft.Resources/subscriptions/resourceGroups/read`

<Note>
If you update the role and still get `RBACAccessDenied`, wait a few minutes and retry. Azure RBAC propagation is not always immediate.

For subscriptions under EA or certain billing setups, cost visibility may also depend on billing-side settings such as view charges access.
</Note>

## Important Notes

* `AssignableScopes` is required for all Azure custom roles
* A management group is above subscriptions in the Azure hierarchy
* If you use multiple subscriptions in `AssignableScopes`, the role is limited to those subscriptions only
* Role creation requires permission to manage custom roles for every scope listed in `AssignableScopes`

## Modification

You're welcome to download and modify the role definition according to your needs. Note that some OpenOps benchmark workflows may not function properly if required permissions are removed.

<JoinCommunity />
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
targetScope = 'subscription'

@description('Scopes where this custom role can be assigned. Defaults to the current subscription.')
param assignableScopes array = [
subscription().id
]

var roleDefinitionGuid = '97fd4ee5-cfe4-4d11-a798-2d9d8a4f153f'
var roleName = 'OpenOps Azure Benchmark Reader'
var roleDescription = 'Read-only benchmark, cost, and Azure Advisor recommendation role for OpenOps Azure Benchmark.'
var actions = [
'Microsoft.Advisor/metadata/read'
'Microsoft.Advisor/recommendations/read'
'Microsoft.Billing/billingPeriods/read'
'Microsoft.Billing/billingProperty/read'
'Microsoft.Compute/disks/read'
'Microsoft.Compute/images/read'
'Microsoft.Compute/snapshots/read'
'Microsoft.Compute/virtualMachines/read'
'Microsoft.Consumption/*/read'
'Microsoft.CostManagement/*/read'
'Microsoft.CostManagement/query/action'
'Microsoft.Insights/metrics/read'
'Microsoft.Network/networkInterfaces/read'
'Microsoft.Network/publicIPAddresses/read'
'Microsoft.Resources/subscriptions/read'
'Microsoft.Resources/subscriptions/resourceGroups/read'
'Microsoft.Sql/servers/databases/read'
'Microsoft.Sql/servers/elasticPools/read'
'Microsoft.Sql/servers/read'
'Microsoft.Web/hostingEnvironments/read'
'Microsoft.Web/serverfarms/read'
'Microsoft.Web/sites/read'
]

resource customRole 'Microsoft.Authorization/roleDefinitions@2022-04-01' = {
name: roleDefinitionGuid
properties: {
roleName: roleName
description: roleDescription
type: 'CustomRole'
permissions: [
{
actions: actions
notActions: []
dataActions: []
notDataActions: []
}
]
assignableScopes: assignableScopes
}
}

output roleDefinitionId string = roleDefinitionGuid
output roleDefinitionResourceId string = customRole.id
output roleDefinitionName string = customRole.properties.roleName
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"Name": "OpenOps Azure Benchmark Reader",
"IsCustom": true,
"Description": "Read-only benchmark, cost, and Azure Advisor recommendation role for OpenOps Azure Benchmark.",
"Actions": [
"Microsoft.Advisor/metadata/read",
"Microsoft.Advisor/recommendations/read",
"Microsoft.Billing/billingPeriods/read",
"Microsoft.Billing/billingProperty/read",
"Microsoft.Compute/disks/read",
"Microsoft.Compute/images/read",
"Microsoft.Compute/snapshots/read",
"Microsoft.Compute/virtualMachines/read",
"Microsoft.Consumption/*/read",
"Microsoft.CostManagement/*/read",
"Microsoft.CostManagement/query/action",
"Microsoft.Insights/metrics/read",
"Microsoft.Network/networkInterfaces/read",
"Microsoft.Network/publicIPAddresses/read",
"Microsoft.Resources/subscriptions/read",
"Microsoft.Resources/subscriptions/resourceGroups/read",
"Microsoft.Sql/servers/databases/read",
"Microsoft.Sql/servers/elasticPools/read",
"Microsoft.Sql/servers/read",
"Microsoft.Web/hostingEnvironments/read",
"Microsoft.Web/serverfarms/read",
"Microsoft.Web/sites/read"
],
"NotActions": [],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/<subscription-id>"
]
}
9 changes: 8 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@
"getting-started/user-management"
]
},
{
"group": "FinOps Benchmark",
"pages": [
"finops-benchmark/overview"
]
},
{
"group": "Workflow Management",
"pages": [
Expand All @@ -61,7 +67,8 @@
"pages": [
"cloud-access/supported-cloud-providers",
"cloud-access/access-levels-permissions",
"cloud-access/aws-cf-role-stack"
"cloud-access/aws-cf-role-stack",
"cloud-access/azure-rbac"
]
},
{
Expand Down
55 changes: 55 additions & 0 deletions finops-benchmark/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: 'Benchmark'
description: 'Automated cloud assessment that computes a cost efficiency score and a breakdown of savings opportunities.'
icon: 'chart-column'
---

import JoinCommunity from '/snippets/join-community.mdx'

**Benchmark** helps you run an **automated cloud assessment** across the provider you use with OpenOps. You choose your connection, scope, and which cost and efficiency checks to include. OpenOps automatically creates the workflows, runs them, and collects findings so you can prioritize savings and cleanup in one place.


## What you get

* A **library of checks** tuned to your selected provider - for example utilization and waste, rightsizing, and savings across compute, storage, databases, and related services.
* A **benchmark report** in [Analytics](/reporting-analytics/analytics) so you can review KPIs and trends.

## Running a benchmark

1. Click **Run a Benchmark** on the OpenOps home page to start.
2. Select your **cloud provider**. If you have no connection yet, create one when prompted.
![Benchmark wizard — select cloud provider](/images/benchmark-wizard-provider.png)

3. Choose the **connection** the benchmark should use.
![Benchmark wizard — choose connection](/images/benchmark-wizard-connection.png)
<Note>
For **AWS**, OpenOps must be able to assume a role that includes the **read-only permissions** defined in the Benchmark CloudFormation stack. Use the link beside this step in the wizard to open the stack details. If that role is missing or incomplete, benchmark workflows can fail. For installation steps and templates, see [AWS CloudFormation role stacks](/cloud-access/aws-cf-role-stack).
</Note>
<Note>
For **Azure**, OpenOps must be able to use a service principal with the **OpenOps Azure Benchmark Reader** custom role assigned at the appropriate scope (subscription or management group). This role includes read-only permissions for compute, networking, databases, cost management, and Azure Advisor. If the role is not assigned or lacks required permissions, benchmark workflows can fail. For installation steps and role definitions, see [Azure RBAC custom roles](/cloud-access/azure-rbac).
</Note>

4. Select **accounts or subscriptions** and **regions** to include.
![Benchmark wizard — accounts and regions](/images/benchmark-wizard-regions.png)

5. Choose the **benchmark workflows** that correspond to the cost and efficiency checks you want this run to perform.
![Benchmark wizard — select workflows](/images/benchmark-wizard-workflows.png)

6. Click **Run** to execute the benchmark.
7. When the run completes, open the benchmark report from the link in the wizard.


## Benchmark report

![Benchmark report](../images/benchmark-report.png)

After a successful run, the **benchmark report** is built from benchmark opportunities and cost data from your chosen cloud provider. You will see:

* **Summary metrics**: For example estimated monthly savings from open opportunities, total opportunity count, a **unified cost efficiency** metric (savings versus monthly cost context), and **monthly amortized cost over time**.
* **Top opportunities to address**: A ranked view you can use to focus on the largest items first.
* **Breakdown of savings**: Charts such as savings **by service**, **by region**, and **by account** so you can see where optimization potential clusters.

Charts are **cross-linked**: Choose a service, region, or account in one chart to filter the rest of the dashboard. A short note on the dashboard reminds you that you can filter using those dimensions.


<JoinCommunity />
Binary file added images/benchmark-report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/benchmark-wizard-connection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/benchmark-wizard-provider.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/benchmark-wizard-regions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/benchmark-wizard-workflows.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading