It adds the nOps.io enterprise application (a service principal) to your Microsoft Entra ID tenant. It also approves the app’s permissions for your whole organization, so no one else is asked to approve them.Microsoft’s consent screen shows the app nOps.io from nOps Inc (a verified publisher). It lists these permissions:
Permission
What Microsoft says it allows
Access Azure Resource Manager as organization users
Allows the application to access Azure Resource Manager acting as users in the organization
Read directory data
Allows the app to read data in your organization’s directory, such as users, groups and apps
Sign in and read user profile
Allows users to sign-in to the app, and allows the app to read the profile of signed-in users. It also allows the app to read basic company information of signed-in users
The screen also says that if you accept, the app gets access to the specified resources for all users in your organization, and no one else will be prompted to review these permissions.Consent by itself gives nOps no access to your subscriptions, billing, or storage. nOps only gets Azure access from the roles you assign in Run the Setup.nOps never signs in as your users. When Microsoft sends you back to nOps, nOps only learns your tenant ID and whether you accepted. After that, nOps connects with the app’s own identity, using only the roles you assign.You need Global Administrator or Privileged Role Administrator to grant consent. To stop nOps’s access later, delete or disable the nOps.io enterprise application in Microsoft Entra ID → Enterprise applications. You can also remove the role assignments you made during setup.
Why does nOps need Reader on the management group?
A role you assign on a management group applies to every subscription under it, including subscriptions you add later. With Reader there, nOps can see all your subscriptions and their resources, with no setup on each subscription.Reader is read-only. nOps can’t create, change, or delete anything. It can’t read data inside storage accounts, and it can’t read Key Vault secrets.To cover everything, use your tenant root management group. Its ID is your tenant ID.
Why does nOps need a reader role at the billing account level?
You create the FOCUS export at your billing account (MCA) or enrollment (EA). nOps uses Billing account reader (MCA) or EnrollmentReader (EA) to find your billing account and billing profiles, and to check that the FOCUS export exists and runs.These roles are read-only. nOps can’t change billing settings or make purchases. For MCA, one assignment at the billing account covers every billing profile, including profiles you add later.
Should I connect the billing account or specific billing profiles?
We recommend the billing account. One Billing account reader assignment covers every billing profile, including profiles you add later, and you only need one FOCUS export.Choose billing profiles only if your organization gives access per billing profile. In that case:
You need a Billing profile owner for each profile.
Each profile needs its own FOCUS export.
Billing profiles you don’t add aren’t included in Savings Analysis.
Billing profiles apply to MCA only. EA always connects at the enrollment.
I'm a Global Administrator. Can I do the billing steps myself?
MCA: Yes. First, give yourself Billing account owner. In Cost Management + Billing, open Billing scopes, select the box to view all billing accounts, and open your billing account. Then go to Access control (IAM) → Add, choose Billing account owner, and add yourself. Microsoft explains this in Elevate access to manage billing accounts.
EA: No. A Global Administrator can’t give themselves EA billing roles. An Enterprise Administrator has to do the EA billing steps.
My billing account has some billing profiles from a CSP partner and some that are MCA. Does that change onboarding?
No. The setup steps are the same. A mix of CSP and MCA billing profiles under your billing account doesn’t change anything in onboarding.You still need a billing account of your own (EA or MCA). Tenants billed only through a CSP partner aren’t supported.
Why does nOps use FOCUS exports?
FOCUS (FinOps Open Cost and Usage Specification) is an open standard format for cost data. Azure writes a daily FOCUS export to a storage account you own, and nOps reads those files.One export at the billing account covers every subscription and billing profile in it. It includes amortized costs for reservations and savings plans, and the discounts you receive. The files stay in your storage account, and you control them.
Why does nOps need roles for the usage (FOCUS) export?
There are two sides:
The person who sets up the export needs a billing role at the billing scope, because that’s where the export is created. They also need rights to create a storage account in the export subscription, such as Owner or Contributor.
nOps needs the billing reader role to find the export and check that it runs daily. It also needs Storage Blob Data Owner on that one storage account to read the export files.
The storage role applies only to that storage account, which only holds the export files.
What resources do I create during setup?
You create these yourself in the Azure portal, in Step C. nOps doesn’t create them.
A resource group named nops-focus-exports-rg
A storage account named nopsfocus + the first 15 characters of your tenant ID (without dashes), with a container named focus-exports
A FOCUS cost export with the prefix nops-clara, at your billing account (MCA), your enrollment (EA), or each billing profile you connect
You choose the region when you create the storage account. These resources cost only the storage for the export files.
Can I use an existing storage account instead?
No. Create the new storage account the wizard names in Step C. A dedicated storage account keeps the export files on their own, and the Storage Blob Data Owner role you give nOps.io applies to that storage account only.
What if my organization restricts storage account network access?
If your organization uses Azure Policy to enforce storage account firewalls, allow the nOps IP addresses on the FOCUS export storage account.
Go to the storage account > Security + networking > Networking
Under Firewall, add the nOps IP addresses: 44.246.45.84, 52.11.53.164, and 52.39.155.200
Make sure “Allow Azure services on the trusted services list” is checked
Click Save
How often is billing data refreshed?
FOCUS cost exports run daily. Cost data is typically available within 24-48 hours of the export run. Your first Run now includes the current month, and the backfill runs in Step C add the previous three months.
How long does it take for Azure role assignments to propagate?
Azure role assignments typically take 2-5 minutes to take effect. In some cases, it can take up to 10 minutes. If verification fails right after you finish setup, wait a few minutes and try again.
Supported Billing Account Types: nOps supports Enterprise Agreement (EA) and Microsoft Customer Agreement (MCA) billing accounts only. If you have a Pay-As-You-Go (MOSP) subscription, please contact your Microsoft account representative to upgrade to an EA or MCA billing account before proceeding.
Savings Analysis does not allow purchasing reservations or savings plans. To enable automated commitment purchasing, complete this setup first, then follow the Commitment Management Setup guide.
EA only: Your EA enrollment number. In Cost Management + Billing, select your EA billing account and copy the Billing account ID from Settings > Properties
Your Management Group ID (or your tenant ID, to cover every subscription)
A subscription to hold the storage account for the FOCUS export
The three roles listed under Required access. Different people often hold them, so you may need help from other teams
The nOps Azure Savings Analysis wizard has 4 steps:
Get Started — Name your integration, pick your billing account type, and confirm your team has the required access
Grant Admin Consent — Add the nOps.io app to your Microsoft Entra ID tenant
Run Setup — Assign roles and create the FOCUS cost export in the Azure portal (Steps A–D)
Before you begin: make sure your organization has its own EA or MCA billing account. Tenants billed only through a CSP partner aren’t supported. The wizard’s Before you begin box shows how to run Microsoft’s CSP eligibility check. You can also run the nOps onboarding qualifier, a read-only script that classifies each billing account (EA / MCA / Reseller / CSP) and gives a PASS / FAIL verdict.
Provide a friendly name for this integration (e.g., “Production Azure Environment”). This name helps you identify the integration in the nOps dashboard.
3
Select Your Billing Account Type
Choose EA (Enterprise Agreement) or MCA (Microsoft Customer Agreement). This decides which billing steps you follow later.If you are unsure which type you have, see Understanding Billing Account Types.
4
Enter Your EA Enrollment Number (EA only)
If you selected EA, enter your EA enrollment number. You need it to continue.Find it in Azure Portal > Cost Management + Billing: select your EA billing account and copy the Billing account ID from Settings > Properties. For an EA, this is your numeric enrollment number. MCA users skip this step.
5
Check the Required Access List
The wizard lists the three roles your team needs (described in Required access below). Tick each one you have, or know who has. You can continue once all three are ticked.
nOps gets:Billing account reader (MCA), Billing profile reader on each selected profile, or EnrollmentReader (EA), plus a FOCUS export at that billing scope
Owner (an Azure RBAC role) on the management group and on the export subscription
nOps gets:Reader on the management group and Storage Blob Data Owner on the export storage account
User Access Administrator can do the role assignments in Steps B and D but can’t create the storage account in Step C, so pair it with Contributor on the export subscription
MCA: billing account or billing profilesBy default, the wizard shows nOps connects at your billing account (recommended). If you only have access to specific billing profiles, click Only have access to specific billing profiles? and then Connect billing profiles instead. You’ll need a Billing profile owner for each profile, and each profile gets its own FOCUS export. To switch back, click Use the billing account instead (recommended).EA always connects at the enrollment, so there’s no billing profile option.
MCA: are you a Global Administrator? You can give yourself Billing account owner first. In Cost Management + Billing, open Billing scopes, select the box to view all billing accounts, and open your billing account. Then go to Access control (IAM) → Add → Billing account owner, and add yourself. See Microsoft’s guide, Elevate access to manage billing accounts.This doesn’t work for EA. An Enterprise Administrator has to do the EA billing steps.
Admin consent adds the nOps.io enterprise application (a service principal) to your Microsoft Entra ID tenant. You need to do this before you can assign any roles to nOps.
1
Click Grant Admin Consent
In the nOps wizard, click the Grant Admin Consent button. Microsoft’s sign-in page opens.
2
Sign In with an Admin Account
Sign in with an account that has the Global Administrator or Privileged Role Administrator role in Microsoft Entra ID.
3
Review and Accept Permissions
Microsoft shows the app nOps.io from nOps Inc (a verified publisher) and the permissions it asks for. Review them and click Accept.
4
Return to nOps
Microsoft sends you back to the nOps wizard. Your Azure Tenant ID now shows, which confirms that consent was granted.
Consent adds the nOps.io enterprise application to your tenant and approves its permissions for your whole organization, so no one else is asked to approve them. For the full list of permissions, see What does Grant Admin Consent do? in the FAQs.
Consent by itself gives nOps no access to your subscriptions, billing, or storage. nOps only gets Azure access from the roles you assign in Run the Setup.
nOps never signs in as your users. It connects with the app’s own identity, using only the roles you assign.
What is an enterprise application? It’s how an app from another organization appears in your Microsoft Entra ID tenant. It’s also called a service principal. Consent adds it to your tenant. It isn’t an app registration: the nOps app registration lives in nOps’s own tenant, not yours.
Don’t delete the nOps.io enterprise application after you grant consent. If you delete it, nOps loses access and you’ll need to grant admin consent again from the wizard.
You do this part in the Azure portal. It has four parts, A to D. Only the EA billing role in Step A needs the Azure CLI.
The nOps wizard walks you through the same steps (labeled A through D), with your own values filled in. Follow along in the wizard or use the steps below.
Prefer a script? In the wizard, choose Run an Azure CLI script to do steps A to D with one script in Azure Cloud Shell. It sets up the same things with the same access, can be run again safely, and lists anything your account can’t do with how to finish it. See Setup Script (Azure CLI).
Step
What you do
Why nOps needs it
A. Billing role
Give nOps.io a billing reader role
To find your billing account and billing profiles, and check your FOCUS export
B. Reader
Give nOps.io Reader on your management group
To see your subscriptions and their resources
C. FOCUS cost export
Create a daily FOCUS cost export and its storage account
So Azure writes your cost data to a storage account you own
D. Storage Blob Data Owner
Give nOps.io Storage Blob Data Owner on that storage account
Follow only the tab that matches your billing account type and how you connect it.
MCA: billing account (recommended)
MCA: billing profiles
Enterprise Agreement (EA)
You need Billing account owner on the MCA billing account. Azure RBAC Owner doesn’t include billing roles. If you’re a Global Administrator, you can give yourself Billing account owner first (see the tip under Required access). If you can’t, ask your Billing account owner to do this step. To see who holds this role, go to Cost Management + Billing → select your billing account → Access control (IAM).
1
Open Your Billing Account
Go to Cost Management + Billing in the Azure portal and select your Microsoft Customer Agreement billing account.
2
Assign Billing account reader
Click Access control (IAM) in the left menu.
Click Add at the top.
Select the role Billing account reader.
Search for “nOps.io” and select it.
Click Review + assign (or Save).
Use this tab only if your organization gives access per billing profile. Billing profiles you don’t add aren’t included in Savings Analysis.
You need Billing profile owner on each billing profile you add. If you don’t have it, ask the Billing profile owner of that profile to do this step.
1
Enter Your Billing Account and Billing Profile IDs
In the nOps wizard, enter your billing account ID and the billing profile ID of each profile you want to connect.
Billing profile ID: open Billing profiles → select the profile → Properties
2
Assign Billing profile reader on Each Profile
Do this on each billing profile you entered:
In Cost Management + Billing, open your billing account → Billing profiles → select the profile.
Click Access control (IAM) → Add.
Select the role Billing profile reader.
Search for “nOps.io” and select it.
Click Review + assign (or Save).
You must be an Enterprise Administrator on the EA enrollment to complete this step. Microsoft requires enrollment write access to assign EnrollmentReader to a service principal, so Enterprise Administrator (read only), Department Administrator, and Account Owner cannot do it. Global Administrator and Azure RBAC Owner don’t include EA billing roles, and a Global Administrator can’t give themselves one. If you don’t have this role, ask an Enterprise Administrator to run the script below. Check who holds it in Cost Management + Billing → select your EA billing account → Access control (IAM).
Microsoft only supports assigning EA billing roles (such as EnrollmentReader) to a service principal through the REST API, not the Azure portal. Run the script below in Azure Cloud Shell (Bash, not PowerShell) or a local terminal with the Azure CLI installed. You run this script yourself. nOps doesn’t assign billing roles.
1
Sign in to Azure CLI
Open Azure Cloud Shell (Bash) or run az login in your local terminal.
2
Run the EnrollmentReader assignment script
Copy and run the following script. Replace <app-client-id>, <enrollment-number>, and <tenant-id> with your values (the nOps wizard pre-fills these in its generated script):
# Assign EnrollmentReader role to nOps service principal# Run in Azure Cloud Shell (Bash, not PowerShell) or a local terminal with Azure CLINOPS_APP_CLIENT_ID="<app-client-id>"# Look up the nOps service principal Object IDNOPS_SP_OBJECT_ID=$(az ad sp show --id "$NOPS_APP_CLIENT_ID" --query "id" -o tsv 2>/dev/null || true)if [ -z "$NOPS_SP_OBJECT_ID" ]; then echo "ERROR: nOps service principal not found. Complete the Admin Consent step first." exit 1fiecho "Found nOps service principal: $NOPS_SP_OBJECT_ID"ROLE_ASSIGNMENT_GUID=$(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid)az rest --method PUT \ --url "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/<enrollment-number>/billingRoleAssignments/${ROLE_ASSIGNMENT_GUID}?api-version=2024-04-01" \ --body '{ "properties": { "principalId": "'"$NOPS_SP_OBJECT_ID"'", "principalTenantId": "<tenant-id>", "roleDefinitionId": "/providers/Microsoft.Billing/billingAccounts/<enrollment-number>/billingRoleDefinitions/24f8edb6-1668-4659-b5e2-40bb5f3a7d7e" } }'echo "Done. A 200 OK response confirms the EnrollmentReader role was assigned."
The nOps wizard generates a ready-to-run script with all values pre-filled (App Client ID, enrollment number, and tenant ID). Copy it directly from the wizard for the easiest experience.
Fallback: If az ad sp show fails, you can find the service principal manually: az ad sp list --filter "startswith(displayName, 'nops')" --query "[].{name:displayName, objectId:id}" -o table and use the objectId value.
A 200 OK response confirms the role was assigned. Service principal role assignments on an EA enrollment are not shown in the Azure portal, so use the nOps Verify step to confirm access. If you have more than one EA billing account, repeat the script for each enrollment.
Assign Reader on the management group that holds the subscriptions you want in Savings Analysis. You need Owner or User Access Administrator on that management group.
1
Enter Your Management Group ID
In the nOps wizard, enter the Management Group ID. To cover every subscription, click Use tenant root. Your tenant ID is the ID of the root management group.Find your management groups in Azure Portal > Management Groups.
2
Open the Management Group
Go to Management Groups in the Azure portal and select the management group.
3
Open Access Control
Click Access control (IAM) in the left menu, then click Add > Add role assignment.
4
Select the Role
On the Role tab, search for and select Reader, then click Next.
5
Assign to nOps.io
On the Members tab, set “Assign access to” to “User, group, or service principal” (not “Managed identity”).
Click ”+ Select members”.
Search for “nOps.io” by name and select it.
Click Select.
Click Review + assign.
Repeat only if your subscriptions are split across separate management groups.
In the nOps wizard, enter the subscription that will hold the export’s storage account. Choose the subscription with the most spend.To create the storage account, you need Owner or Contributor on this subscription.
2
Register Resource Providers
Make sure these resource providers are registered on that subscription: Microsoft.Storage, Microsoft.CostManagement, and Microsoft.CostManagementExports.Go to Subscriptions → select the subscription → Settings → Resource providers, and click Register on any that aren’t registered. Most subscriptions already have these registered. If a provider already shows “Registered”, no action is needed.
3
Open Exports and Set the Scope
Go to Cost Management > Exports in the Azure portal. At the top, click Change scope if needed, and select:
MCA billing account: your Microsoft Customer Agreement billing account
EA: your EA enrollment (the same enrollment number you entered in the nOps wizard, e.g., 12345678)
MCA billing profiles: one of your billing profiles. You’ll create a separate export for each profile
4
Create the Export
Click + Create.
Basics tab: Select the “Cost and usage (FOCUS)” template.
Datasets tab: Set the export prefix to nops-clara. The template sets the frequency to Daily.
MCA billing profiles only: use the prefix the nOps wizard shows for that profile. It’s nops-clara- followed by letters and digits from the billing profile ID, in lowercase. This keeps the exports from overwriting each other.
Destination tab:
Storage type: Azure blob storage
Subscription: the subscription you entered in the nOps wizard
Storage account: Click Create new
Resource group: create a new one named nops-focus-exports-rg
Name: nopsfocus + the first 15 characters of your tenant ID, without dashes
Region: any region you choose
Container: focus-exports
Directory: nops-clara
Format: Parquet
Compression type: Snappy
File partitioning: checked
Overwrite data: checked
Click Review + create, then Create.
5
Run the Export and Backfill 3 Months
Open the export and click Run now to trigger the first export.
Click Export selected dates to backfill the previous 3 months, one run per month:
Run 1: Start date = first day of three months ago, End date = last day of three months ago
Run 2: Start date = first day of two months ago, End date = last day of two months ago
Run 3: Start date = first day of previous month, End date = last day of previous month
Data will be available within a few hours.
MCA billing profiles: repeat these export steps for each billing profile you connect, with that profile’s prefix. After the first profile, select the storage account you already created instead of creating a new one.
The nOps wizard shows the exact storage account name, resource group, container, and directory you need. Copy these values from the wizard so they match what nOps checks in Verify.
You must be an Owner or User Access Administrator on the storage account to assign Storage Blob Data Owner.
1
Open the Storage Account
Search for “Storage accounts” in the Azure portal’s top search bar, then select the storage account you created in Step C (e.g., nopsfocus<tenant-prefix>).
2
Assign Storage Blob Data Owner
Go to Access control (IAM) → Add → Add role assignment.
Under Job function roles, select Storage Blob Data Owner.
Select User, group, or service principal.
Search for and select nOps.io.
Click Review + assign.
3
Configure Firewall (if applicable)
If your organization restricts storage account network access (through Azure Policy or manual settings):
Go to the storage account > Security + networking > Networking
Under Firewall, add the nOps IP addresses: 44.246.45.84, 52.11.53.164, and 52.39.155.200
Make sure “Allow Azure services on the trusted services list” is checked
Click Save
Skip this step if your storage account allows public network access (the default). nOps reads the export files from outside Azure, so if a firewall is on, it must allow the nOps IP addresses.
Azure role assignments can take 2-5 minutes to propagate. If verification fails right after you assign roles, wait a few minutes and try again.
nOps checks that each part of the setup is in place.
1
Click Verify Permissions
Click the Verify Permissions button. nOps checks:
Reader — nOps can list your subscriptions
Billing role — nOps has Billing account reader (MCA), Billing profile reader (MCA billing profiles), or EnrollmentReader (EA)
FOCUS export — a FOCUS export exists at the right billing scope
Storage Blob Data Owner — nOps can list the export container
If you connected billing profiles, nOps checks Billing profile reader and a FOCUS export on each profile. It skips a profile’s export check until that profile’s billing role is in place.
2
Review Results
The wizard shows a pass or fail result for each check. When they all pass, you’ll see “Savings Analysis Verified” with the number of connected subscriptions.
Verification Failed? — If some checks don’t pass yet:
Wait a few more minutes. Azure role assignments can take time to propagate
Check that each role was assigned to nOps.io at the right scope: the billing role (Step A), Reader on the management group (Step B), and Storage Blob Data Owner on the storage account (Step D)
Check that the FOCUS export exists at your billing account, enrollment, or each billing profile you connected (Step C)
Once the Savings Analysis integration is verified, nOps begins ingesting your cost data and generating optimization recommendations.To enable automated purchasing and management of Azure Reservations and Savings Plans, you can upgrade your integration to the Commitment Management tier:
Azure Commitment Management Setup
Configure nOps to manage Azure Reservations and Savings Plans on your behalf, including automated purchasing and optimization.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"nOps Documentation","description":"nOps cloud cost optimization platform: platform guides, cloud provider onboarding, and more.","colors":{"primary":"#0071EA","light":"#3399FF","dark":"#0056B3"},"logo":{"light":"https://mintcdn.com/nopsio/soDze3u_2cvKfXf7/logo/light.svg?fit=max\u0026auto=format\u0026n=soDze3u_2cvKfXf7\u0026q=85\u0026s=52543d77f0daf2d0e4763930bdc46fe6","dark":"https://mintcdn.com/nopsio/soDze3u_2cvKfXf7/logo/dark.svg?fit=max\u0026auto=format\u0026n=soDze3u_2cvKfXf7\u0026q=85\u0026s=0ef246577335b94b314a9ea2acf070e4","href":"https://clara.nops.io"},"favicon":"https://mintcdn.com/nopsio/soDze3u_2cvKfXf7/favicon.svg?fit=max\u0026auto=format\u0026n=soDze3u_2cvKfXf7\u0026q=85\u0026s=fdd5f561841463f4a4d314cf20927244","api":{"openapi":"openapi.json","playground":{"display":"interactive"},"examples":{"defaults":"required","languages":["curl","python","javascript","go"],"prefill":true},"url":"full"},"appearance":{"default":"dark"},"background":{"decoration":"gradient"},"navbar":{"links":[{"href":"mailto:support@nops.io","label":"Support"}],"primary":{"type":"button","label":"Dashboard","href":"https://clara.nops.io"}},"footer":{"socials":{"linkedin":"https://linkedin.com/company/nops-io","website":"https://nops.io","x":"https://x.com/naborly"},"links":[{"header":"Resources","items":[{"label":"nOps Platform","href":"https://clara.nops.io"},{"label":"Help Center","href":"https://help.nops.io"},{"label":"Blog","href":"https://nops.io/blog"}]},{"header":"Company","items":[{"label":"About nOps","href":"https://nops.io"},{"label":"Contact Support","href":"mailto:support@nops.io"}]}]},"search":{"prompt":"Search nOps docs..."},"fonts":{"heading":{"family":"Poppins","weight":600},"body":{"family":"Inter"}},"styling":{"codeblocks":{"theme":{"light":"github-light","dark":"github-dark"}},"latex":false},"errors":{"404":{"redirect":false,"title":"Page not found","description":"The page you're looking for doesn't exist. [Go back to the docs home](/)."}},"contextual":{"options":["copy","view","download-spec","chatgpt","claude","perplexity","mcp","add-mcp","cursor","vscode"],"display":"header"},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"nopsio","hasAudioNarration":false,"actualSubdomain":"nopsio","customDomains":["help.nops.io"],"gitSource":{"type":"github","owner":"nops-io","repo":"clara","deployBranch":"dev","contentDirectory":"public-docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae55e0a26aa84b3900a0419","collectionId":"0f8274eb-e2cd-40f5-95d6-664224c3446b","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae55e0a26aa84b3900a0419"},"feedback":{"thumbs":true,"agentFeedback":true},"entitlements":{},"buildId":"6ae55e0a26aa84b3900a0419","clientVersion":"0.0.4044","searchFilterCounts":[{"language":"default","tag":"Developers","count":170},{"language":"default","tag":"API Reference","count":164},{"language":"default","tag":"Guides","count":68},{"language":"default","tag":"Seat Tracking","count":42},{"language":"default","tag":"Cost allocation","count":26},{"language":"default","tag":"Budgets","count":24},{"language":"default","tag":"Third-Party Integrations","count":18},{"language":"default","tag":"Cloud provider integrations","count":15},{"language":"default","tag":"Business unit economics","count":14},{"language":"default","tag":"AI","count":9}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":true},"customCss":[],"page":{"pagePath":"azure/integration-setup","slug":"/azure/integration-setup","pageMetadata":{"title":"Microsoft Azure - Savings Analysis Setup","description":"Connect your Azure environment to nOps for read-only cost visibility, resource inventory, optimization recommendations, and daily FOCUS cost exports.","icon":"plug","href":"/azure/integration-setup"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Connect your Azure environment to nOps for read-only cost visibility, resource inventory, optimization recommendations, and daily FOCUS cost exports.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,hr:`hr`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{Accordion,AccordionGroup,Card,CodeBlock,Heading,Info,Step,Steps,Tab,Table,Tabs,Tip,Warning}=_components;if(!Accordion)_missingMdxReference(`Accordion`,true);if(!AccordionGroup)_missingMdxReference(`AccordionGroup`,true);if(!Card)_missingMdxReference(`Card`,true);if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Info)_missingMdxReference(`Info`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);if(!Tip)_missingMdxReference(`Tip`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(Heading,{level:`2`,id:`faqs`,children:`FAQs`}),`\n`,_jsxs(AccordionGroup,{children:[_jsxs(Accordion,{title:`What does Grant Admin Consent do?`,id:`what-does-grant-admin-consent-do`,children:[_jsxs(_components.p,{children:[`It adds the `,_jsx(_components.strong,{children:`nOps.io`}),` enterprise application (a service principal) to your Microsoft Entra ID tenant. It also approves the app’s permissions for your whole organization, so no one else is asked to approve them.`]}),_jsxs(_components.p,{children:[`Microsoft’s consent screen shows the app `,_jsx(_components.strong,{children:`nOps.io`}),` from `,_jsx(_components.strong,{children:`nOps Inc`}),` (a verified publisher). It lists these permissions:`]}),_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Permission`}),_jsx(_components.th,{children:`What Microsoft says it allows`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Access Azure Resource Manager as organization users`}),_jsx(_components.td,{children:`Allows the application to access Azure Resource Manager acting as users in the organization`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Read directory data`}),_jsx(_components.td,{children:`Allows the app to read data in your organization’s directory, such as users, groups and apps`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Sign in and read user profile`}),_jsx(_components.td,{children:`Allows users to sign-in to the app, and allows the app to read the profile of signed-in users. It also allows the app to read basic company information of signed-in users`})]})]})]}),_jsx(_components.p,{children:`The screen also says that if you accept, the app gets access to the specified resources for all users in your organization, and no one else will be prompted to review these permissions.`}),_jsxs(_components.p,{children:[`Consent by itself gives nOps `,_jsx(_components.strong,{children:`no access`}),` to your subscriptions, billing, or storage. nOps only gets Azure access from the roles you assign in `,_jsx(_components.a,{href:`#3-run-the-setup`,children:`Run the Setup`}),`.`]}),_jsx(_components.p,{children:`nOps never signs in as your users. When Microsoft sends you back to nOps, nOps only learns your tenant ID and whether you accepted. After that, nOps connects with the app’s own identity, using only the roles you assign.`}),_jsxs(_components.p,{children:[`You need `,_jsx(_components.strong,{children:`Global Administrator`}),` or `,_jsx(_components.strong,{children:`Privileged Role Administrator`}),` to grant consent. To stop nOps’s access later, delete or disable the `,_jsx(_components.strong,{children:`nOps.io`}),` enterprise application in `,_jsx(_components.strong,{children:`Microsoft Entra ID`}),` → `,_jsx(_components.strong,{children:`Enterprise applications`}),`. You can also remove the role assignments you made during setup.`]})]}),_jsxs(Accordion,{title:`Why does nOps need Reader on the management group?`,id:`why-does-nops-need-reader-on-the-management-group`,children:[_jsxs(_components.p,{children:[`A role you assign on a management group applies to every subscription under it, including subscriptions you add later. With `,_jsx(_components.strong,{children:`Reader`}),` there, nOps can see all your subscriptions and their resources, with no setup on each subscription.`]}),_jsx(_components.p,{children:`Reader is read-only. nOps can’t create, change, or delete anything. It can’t read data inside storage accounts, and it can’t read Key Vault secrets.`}),_jsx(_components.p,{children:`To cover everything, use your tenant root management group. Its ID is your tenant ID.`})]}),_jsxs(Accordion,{title:`Why does nOps need a reader role at the billing account level?`,id:`why-does-nops-need-a-reader-role-at-the-billing-account-level`,children:[_jsxs(_components.p,{children:[`You create the FOCUS export at your billing account (MCA) or enrollment (EA). nOps uses `,_jsx(_components.strong,{children:`Billing account reader`}),` (MCA) or `,_jsx(_components.strong,{children:`EnrollmentReader`}),` (EA) to find your billing account and billing profiles, and to check that the FOCUS export exists and runs.`]}),_jsx(_components.p,{children:`These roles are read-only. nOps can’t change billing settings or make purchases. For MCA, one assignment at the billing account covers every billing profile, including profiles you add later.`})]}),_jsxs(Accordion,{title:`Should I connect the billing account or specific billing profiles?`,id:`should-i-connect-the-billing-account-or-specific-billing-profiles`,children:[_jsxs(_components.p,{children:[`We recommend the billing account. One `,_jsx(_components.strong,{children:`Billing account reader`}),` assignment covers every billing profile, including profiles you add later, and you only need one FOCUS export.`]}),_jsx(_components.p,{children:`Choose billing profiles only if your organization gives access per billing profile. In that case:`}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`You need a `,_jsx(_components.strong,{children:`Billing profile owner`}),` for each profile.`]}),`\n`,_jsx(_components.li,{children:`Each profile needs its own FOCUS export.`}),`\n`,_jsx(_components.li,{children:`Billing profiles you don’t add aren’t included in Savings Analysis.`}),`\n`]}),_jsx(_components.p,{children:`Billing profiles apply to MCA only. EA always connects at the enrollment.`})]}),_jsx(Accordion,{title:`I'm a Global Administrator. Can I do the billing steps myself?`,id:`i-m-a-global-administrator-can-i-do-the-billing-steps-myself`,children:_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`MCA:`}),` Yes. First, give yourself `,_jsx(_components.strong,{children:`Billing account owner`}),`. In `,_jsx(_components.a,{href:`https://portal.azure.com/#blade/Microsoft_Azure_GTM/ModernBillingMenuBlade`,children:`Cost Management + Billing`}),`, open `,_jsx(_components.strong,{children:`Billing scopes`}),`, select the box to view all billing accounts, and open your billing account. Then go to `,_jsx(_components.strong,{children:`Access control (IAM)`}),` → `,_jsx(_components.strong,{children:`Add`}),`, choose `,_jsx(_components.strong,{children:`Billing account owner`}),`, and add yourself. Microsoft explains this in `,_jsx(_components.a,{href:`https://learn.microsoft.com/en-us/azure/cost-management-billing/manage/elevate-access-global-admin`,children:`Elevate access to manage billing accounts`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`EA:`}),` No. A Global Administrator can’t give themselves EA billing roles. An `,_jsx(_components.strong,{children:`Enterprise Administrator`}),` has to do the EA billing steps.`]}),`\n`]})}),_jsxs(Accordion,{title:`My billing account has some billing profiles from a CSP partner and some that are MCA. Does that change onboarding?`,id:`my-billing-account-has-some-billing-profiles-from-a-csp-partner-and-some-that-are-mca-does-that-change-onboarding`,children:[_jsx(_components.p,{children:`No. The setup steps are the same. A mix of CSP and MCA billing profiles under your billing account doesn’t change anything in onboarding.`}),_jsx(_components.p,{children:`You still need a billing account of your own (EA or MCA). Tenants billed only through a CSP partner aren’t supported.`})]}),_jsxs(Accordion,{title:`Why does nOps use FOCUS exports?`,id:`why-does-nops-use-focus-exports`,children:[_jsx(_components.p,{children:`FOCUS (FinOps Open Cost and Usage Specification) is an open standard format for cost data. Azure writes a daily FOCUS export to a storage account you own, and nOps reads those files.`}),_jsx(_components.p,{children:`One export at the billing account covers every subscription and billing profile in it. It includes amortized costs for reservations and savings plans, and the discounts you receive. The files stay in your storage account, and you control them.`})]}),_jsxs(Accordion,{title:`Why does nOps need roles for the usage (FOCUS) export?`,id:`why-does-nops-need-roles-for-the-usage-focus-export`,children:[_jsx(_components.p,{children:`There are two sides:`}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The person who sets up the export`}),` needs a billing role at the billing scope, because that’s where the export is created. They also need rights to create a storage account in the export subscription, such as `,_jsx(_components.strong,{children:`Owner`}),` or `,_jsx(_components.strong,{children:`Contributor`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`nOps`}),` needs the billing reader role to find the export and check that it runs daily. It also needs `,_jsx(_components.strong,{children:`Storage Blob Data Owner`}),` on that one storage account to read the export files.`]}),`\n`]}),_jsx(_components.p,{children:`The storage role applies only to that storage account, which only holds the export files.`})]}),_jsxs(Accordion,{title:`What resources do I create during setup?`,id:`what-resources-do-i-create-during-setup`,children:[_jsxs(_components.p,{children:[`You create these yourself in the Azure portal, in `,_jsx(_components.a,{href:`#c-focus-cost-export`,children:`Step C`}),`. nOps doesn’t create them.`]}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`A resource group named `,_jsx(_components.code,{children:`nops-focus-exports-rg`})]}),`\n`,_jsxs(_components.li,{children:[`A storage account named `,_jsx(_components.code,{children:`nopsfocus`}),` + the first 15 characters of your tenant ID (without dashes), with a container named `,_jsx(_components.code,{children:`focus-exports`})]}),`\n`,_jsxs(_components.li,{children:[`A FOCUS cost export with the prefix `,_jsx(_components.code,{children:`nops-clara`}),`, at your billing account (MCA), your enrollment (EA), or each billing profile you connect`]}),`\n`]}),_jsx(_components.p,{children:`You choose the region when you create the storage account. These resources cost only the storage for the export files.`})]}),_jsx(Accordion,{title:`Can I use an existing storage account instead?`,id:`can-i-use-an-existing-storage-account-instead`,children:_jsxs(_components.p,{children:[`No. Create the new storage account the wizard names in Step C. A dedicated storage account keeps the export files on their own, and the `,_jsx(_components.strong,{children:`Storage Blob Data Owner`}),` role you give nOps.io applies to that storage account only.`]})}),_jsxs(Accordion,{title:`What if my organization restricts storage account network access?`,id:`what-if-my-organization-restricts-storage-account-network-access`,children:[_jsx(_components.p,{children:`If your organization uses Azure Policy to enforce storage account firewalls, allow the nOps IP addresses on the FOCUS export storage account.`}),_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Go to the storage account > `,_jsx(_components.strong,{children:`Security + networking`}),` > `,_jsx(_components.strong,{children:`Networking`})]}),`\n`,_jsxs(_components.li,{children:[`Under `,_jsx(_components.strong,{children:`Firewall`}),`, add the nOps IP addresses: `,_jsx(_components.code,{children:`44.246.45.84`}),`, `,_jsx(_components.code,{children:`52.11.53.164`}),`, and `,_jsx(_components.code,{children:`52.39.155.200`})]}),`\n`,_jsxs(_components.li,{children:[`Make sure `,_jsx(_components.strong,{children:`“Allow Azure services on the trusted services list”`}),` is checked`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Save`})]}),`\n`]})]}),_jsx(Accordion,{title:`How often is billing data refreshed?`,id:`how-often-is-billing-data-refreshed`,children:_jsxs(_components.p,{children:[`FOCUS cost exports run `,_jsx(_components.strong,{children:`daily`}),`. Cost data is typically available within 24-48 hours of the export run. Your first `,_jsx(_components.strong,{children:`Run now`}),` includes the current month, and the backfill runs in Step C add the previous three months.`]})}),_jsx(Accordion,{title:`How long does it take for Azure role assignments to propagate?`,id:`how-long-does-it-take-for-azure-role-assignments-to-propagate`,children:_jsxs(_components.p,{children:[`Azure role assignments typically take `,_jsx(_components.strong,{children:`2-5 minutes`}),` to take effect. In some cases, it can take up to 10 minutes. If verification fails right after you finish setup, wait a few minutes and try again.`]})})]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`overview`,children:`Overview`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Savings Analysis`}),` is the first tier of Azure onboarding. It gives nOps `,_jsx(_components.strong,{children:`read-only`}),` access to your Azure environment for:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Cost visibility across all subscriptions`}),`\n`,_jsx(_components.li,{children:`Resource inventory (VMs, disks, networks)`}),`\n`,_jsx(_components.li,{children:`Optimization recommendations (rightsizing, idle resources)`}),`\n`,_jsx(_components.li,{children:`Daily FOCUS cost exports for cost tracking`}),`\n`]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Supported Billing Account Types:`}),` nOps supports `,_jsx(_components.strong,{children:`Enterprise Agreement (EA)`}),` and `,_jsx(_components.strong,{children:`Microsoft Customer Agreement (MCA)`}),` billing accounts only. If you have a Pay-As-You-Go (MOSP) subscription, please contact your Microsoft account representative to upgrade to an EA or MCA billing account before proceeding.`]})}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[`Savings Analysis does `,_jsx(_components.strong,{children:`not`}),` allow purchasing reservations or savings plans. To enable automated commitment purchasing, complete this setup first, then follow the `,_jsx(_components.a,{href:`/azure/commitment-management-setup`,children:`Commitment Management Setup`}),` guide.`]})}),`\n`,_jsxs(Info,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Prerequisites`}),` — Before you start, review the `,_jsx(_components.a,{href:`/azure/prerequisites`,children:`Azure Integration Prerequisites`}),`. You’ll need:`]}),_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`Your billing account type (EA or MCA)`}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`EA only:`}),` Your EA enrollment number. In `,_jsx(_components.a,{href:`https://portal.azure.com/#blade/Microsoft_Azure_GTM/ModernBillingMenuBlade`,children:`Cost Management + Billing`}),`, select your EA billing account and copy the `,_jsx(_components.strong,{children:`Billing account ID`}),` from `,_jsx(_components.strong,{children:`Settings > Properties`})]}),`\n`,_jsx(_components.li,{children:`Your Management Group ID (or your tenant ID, to cover every subscription)`}),`\n`,_jsx(_components.li,{children:`A subscription to hold the storage account for the FOCUS export`}),`\n`,_jsxs(_components.li,{children:[`The three roles listed under `,_jsx(_components.a,{href:`#required-access`,children:`Required access`}),`. Different people often hold them, so you may need help from other teams`]}),`\n`]})]}),`\n`,_jsx(_components.p,{children:`The nOps Azure Savings Analysis wizard has 4 steps:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Get Started`}),` — Name your integration, pick your billing account type, and confirm your team has the required access`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Grant Admin Consent`}),` — Add the nOps.io app to your Microsoft Entra ID tenant`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Run Setup`}),` — Assign roles and create the FOCUS cost export in the Azure portal (Steps A–D)`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Verify`}),` — nOps checks that everything is in place`]}),`\n`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`1-get-started`,children:`1. Get Started`}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Before you begin:`}),` make sure your organization has its own EA or MCA billing account. Tenants billed only through a CSP partner aren’t supported. The wizard’s `,_jsx(_components.strong,{children:`Before you begin`}),` box shows how to run `,_jsx(_components.a,{href:`/azure/prerequisites#how-to-check-for-csp-subscriptions`,children:`Microsoft’s CSP eligibility check`}),`. You can also run the `,_jsx(_components.a,{href:`/azure/prerequisites#recommended-run-the-nops-onboarding-qualifier`,children:`nOps onboarding qualifier`}),`, a read-only script that classifies each billing account (`,_jsx(_components.strong,{children:`EA / MCA / Reseller / CSP`}),`) and gives a `,_jsx(_components.strong,{children:`PASS / FAIL`}),` verdict.`]})}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Open Cloud Provider Integrations`,children:_jsxs(_components.p,{children:[`Log in to `,_jsx(_components.strong,{children:`nOps`}),` and go to `,_jsx(_components.a,{href:`https://clara.nops.io/settings`,children:_jsx(_components.strong,{children:`Settings > Cloud Provider Integrations`})}),`. Scroll down to the `,_jsx(_components.strong,{children:`Add a provider`}),` section and click the `,_jsx(_components.strong,{children:`Microsoft Azure`}),` card.`]})}),_jsx(Step,{title:`Enter an Integration Name`,children:_jsx(_components.p,{children:`Provide a friendly name for this integration (e.g., “Production Azure Environment”). This name helps you identify the integration in the nOps dashboard.`})}),_jsxs(Step,{title:`Select Your Billing Account Type`,children:[_jsxs(_components.p,{children:[`Choose `,_jsx(_components.strong,{children:`EA`}),` (Enterprise Agreement) or `,_jsx(_components.strong,{children:`MCA`}),` (Microsoft Customer Agreement). This decides which billing steps you follow later.`]}),_jsxs(_components.p,{children:[`If you are unsure which type you have, see `,_jsx(_components.a,{href:`/azure/prerequisites#1-understanding-billing-account-types`,children:`Understanding Billing Account Types`}),`.`]})]}),_jsxs(Step,{title:`Enter Your EA Enrollment Number (EA only)`,children:[_jsxs(_components.p,{children:[`If you selected `,_jsx(_components.strong,{children:`EA`}),`, enter your `,_jsx(_components.strong,{children:`EA enrollment number`}),`. You need it to continue.`]}),_jsxs(_components.p,{children:[`Find it in `,_jsx(_components.a,{href:`https://portal.azure.com/#blade/Microsoft_Azure_GTM/ModernBillingMenuBlade`,children:`Azure Portal > Cost Management + Billing`}),`: select your EA billing account and copy the `,_jsx(_components.strong,{children:`Billing account ID`}),` from `,_jsx(_components.strong,{children:`Settings > Properties`}),`. For an EA, this is your numeric enrollment number. MCA users skip this step.`]})]}),_jsx(Step,{title:`Check the Required Access List`,children:_jsxs(_components.p,{children:[`The wizard lists the three roles your team needs (described in `,_jsx(_components.a,{href:`#required-access`,children:`Required access`}),` below). Tick each one you have, or know who has. You can continue once all three are ticked.`]})}),_jsx(Step,{title:`Click Continue`,children:_jsxs(_components.p,{children:[`Click `,_jsx(_components.strong,{children:`Continue`}),` to move on to Grant Admin Consent.`]})})]}),`\n`,_jsx(Heading,{level:`3`,id:`required-access`,children:`Required Access`}),`\n`,_jsx(_components.p,{children:`Setup needs three roles. Different people often hold them, so check who on your team has each one before you start.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Global Administrator`}),` or `,_jsx(_components.strong,{children:`Privileged Role Administrator`}),` (a Microsoft Entra ID role)`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Used for:`}),` `,_jsx(_components.a,{href:`#2-grant-admin-consent`,children:`Grant Admin Consent`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`nOps gets:`}),` its app, the `,_jsx(_components.strong,{children:`nOps.io`}),` enterprise application, in your tenant`]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`A billing role`}),` (separate from Microsoft Entra ID roles and Azure RBAC roles)`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`MCA billing account (default):`}),` `,_jsx(_components.strong,{children:`Billing account owner`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`MCA billing profiles option:`}),` `,_jsx(_components.strong,{children:`Billing profile owner`}),` on each profile`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`EA:`}),` `,_jsx(_components.strong,{children:`Enterprise Administrator`}),`. `,_jsx(_components.strong,{children:`Enterprise Administrator (read only)`}),` can’t do it, and neither can Department Administrator or Account Owner`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Used for:`}),` Run Setup `,_jsx(_components.a,{href:`#a-billing-role`,children:`Step A`}),` and `,_jsx(_components.a,{href:`#c-focus-cost-export`,children:`Step C`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`nOps gets:`}),` `,_jsx(_components.strong,{children:`Billing account reader`}),` (MCA), `,_jsx(_components.strong,{children:`Billing profile reader`}),` on each selected profile, or `,_jsx(_components.strong,{children:`EnrollmentReader`}),` (EA), plus a FOCUS export at that billing scope`]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Owner`}),` (an Azure RBAC role) on the management group and on the export subscription`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Used for:`}),` Run Setup Steps `,_jsx(_components.a,{href:`#b-reader-on-the-management-group`,children:`B`}),`, `,_jsx(_components.a,{href:`#c-focus-cost-export`,children:`C`}),`, and `,_jsx(_components.a,{href:`#d-storage-blob-data-owner`,children:`D`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`nOps gets:`}),` `,_jsx(_components.strong,{children:`Reader`}),` on the management group and `,_jsx(_components.strong,{children:`Storage Blob Data Owner`}),` on the export storage account`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`User Access Administrator`}),` can do the role assignments in Steps B and D but can’t create the storage account in Step C, so pair it with `,_jsx(_components.strong,{children:`Contributor`}),` on the export subscription`]}),`\n`]}),`\n`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`MCA: billing account or billing profiles`})}),`\n`,_jsxs(_components.p,{children:[`By default, the wizard shows `,_jsx(_components.strong,{children:`nOps connects at your billing account (recommended)`}),`. If you only have access to specific billing profiles, click `,_jsx(_components.strong,{children:`Only have access to specific billing profiles?`}),` and then `,_jsx(_components.strong,{children:`Connect billing profiles instead`}),`. You’ll need a Billing profile owner for each profile, and each profile gets its own FOCUS export. To switch back, click `,_jsx(_components.strong,{children:`Use the billing account instead (recommended)`}),`.`]}),`\n`,_jsx(_components.p,{children:`EA always connects at the enrollment, so there’s no billing profile option.`}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`MCA: are you a Global Administrator?`}),` You can give yourself `,_jsx(_components.strong,{children:`Billing account owner`}),` first. In `,_jsx(_components.a,{href:`https://portal.azure.com/#blade/Microsoft_Azure_GTM/ModernBillingMenuBlade`,children:`Cost Management + Billing`}),`, open `,_jsx(_components.strong,{children:`Billing scopes`}),`, select the box to view all billing accounts, and open your billing account. Then go to `,_jsx(_components.strong,{children:`Access control (IAM)`}),` → `,_jsx(_components.strong,{children:`Add`}),` → `,_jsx(_components.strong,{children:`Billing account owner`}),`, and add yourself. See Microsoft’s guide, `,_jsx(_components.a,{href:`https://learn.microsoft.com/en-us/azure/cost-management-billing/manage/elevate-access-global-admin`,children:`Elevate access to manage billing accounts`}),`.`]}),_jsx(_components.p,{children:`This doesn’t work for EA. An Enterprise Administrator has to do the EA billing steps.`})]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`2-grant-admin-consent`,children:`2. Grant Admin Consent`}),`\n`,_jsxs(_components.p,{children:[`Admin consent adds the `,_jsx(_components.strong,{children:`nOps.io`}),` enterprise application (a service principal) to your Microsoft Entra ID tenant. You need to do this before you can assign any roles to nOps.`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Click Grant Admin Consent`,children:_jsxs(_components.p,{children:[`In the nOps wizard, click the `,_jsx(_components.strong,{children:`Grant Admin Consent`}),` button. Microsoft’s sign-in page opens.`]})}),_jsx(Step,{title:`Sign In with an Admin Account`,children:_jsxs(_components.p,{children:[`Sign in with an account that has the `,_jsx(_components.strong,{children:`Global Administrator`}),` or `,_jsx(_components.strong,{children:`Privileged Role Administrator`}),` role in Microsoft Entra ID.`]})}),_jsx(Step,{title:`Review and Accept Permissions`,children:_jsxs(_components.p,{children:[`Microsoft shows the app `,_jsx(_components.strong,{children:`nOps.io`}),` from `,_jsx(_components.strong,{children:`nOps Inc`}),` (a verified publisher) and the permissions it asks for. Review them and click `,_jsx(_components.strong,{children:`Accept`}),`.`]})}),_jsx(Step,{title:`Return to nOps`,children:_jsxs(_components.p,{children:[`Microsoft sends you back to the nOps wizard. Your `,_jsx(_components.strong,{children:`Azure Tenant ID`}),` now shows, which confirms that consent was granted.`]})})]}),`\n`,_jsx(Heading,{level:`3`,id:`understanding-admin-consent`,children:`Understanding Admin Consent`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Consent adds the nOps.io enterprise application to your tenant and approves its permissions for your whole organization, so no one else is asked to approve them. For the full list of permissions, see `,_jsx(_components.strong,{children:`What does Grant Admin Consent do?`}),` in the `,_jsx(_components.a,{href:`#faqs`,children:`FAQs`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Consent by itself gives nOps `,_jsx(_components.strong,{children:`no access`}),` to your subscriptions, billing, or storage. nOps only gets Azure access from the roles you assign in `,_jsx(_components.a,{href:`#3-run-the-setup`,children:`Run the Setup`}),`.`]}),`\n`,_jsx(_components.li,{children:`nOps never signs in as your users. It connects with the app’s own identity, using only the roles you assign.`}),`\n`]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`What is an enterprise application?`}),` It’s how an app from another organization appears in your Microsoft Entra ID tenant. It’s also called a service principal. Consent adds it to your tenant. It isn’t an app registration: the nOps app registration lives in nOps’s own tenant, not yours.`]})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Don’t delete the nOps.io enterprise application`}),` after you grant consent. If you delete it, nOps loses access and you’ll need to grant admin consent again from the wizard.`]})}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`3-run-the-setup`,children:`3. Run the Setup`}),`\n`,_jsxs(_components.p,{children:[`You do this part in the Azure portal. It has four parts, `,_jsx(_components.strong,{children:`A`}),` to `,_jsx(_components.strong,{children:`D`}),`. Only the EA billing role in Step A needs the Azure CLI.`]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[`The nOps wizard walks you through the same steps (labeled `,_jsx(_components.strong,{children:`A`}),` through `,_jsx(_components.strong,{children:`D`}),`), with your own values filled in. Follow along in the wizard or use the steps below.`]})}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Prefer a script?`}),` In the wizard, choose `,_jsx(_components.strong,{children:`Run an Azure CLI script`}),` to do steps A to D with one script in Azure Cloud Shell. It sets up the same things with the same access, can be run again safely, and lists anything your account can’t do with how to finish it. See `,_jsx(_components.a,{href:`/azure/cli-setup`,children:`Setup Script (Azure CLI)`}),`.`]})}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Step`}),_jsx(_components.th,{children:`What you do`}),_jsx(_components.th,{children:`Why nOps needs it`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`A. Billing role`})}),_jsx(_components.td,{children:`Give nOps.io a billing reader role`}),_jsx(_components.td,{children:`To find your billing account and billing profiles, and check your FOCUS export`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`B. Reader`})}),_jsxs(_components.td,{children:[`Give nOps.io `,_jsx(_components.strong,{children:`Reader`}),` on your management group`]}),_jsx(_components.td,{children:`To see your subscriptions and their resources`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`C. FOCUS cost export`})}),_jsx(_components.td,{children:`Create a daily FOCUS cost export and its storage account`}),_jsx(_components.td,{children:`So Azure writes your cost data to a storage account you own`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`D. Storage Blob Data Owner`})}),_jsxs(_components.td,{children:[`Give nOps.io `,_jsx(_components.strong,{children:`Storage Blob Data Owner`}),` on that storage account`]}),_jsx(_components.td,{children:`To read the export files`})]})]})]}),`\n`,_jsxs(_components.p,{children:[`For every role, its ID, and what it allows, see `,_jsx(_components.a,{href:`/azure/permissions-and-resources`,children:`Permissions \u0026 Resources`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`a-billing-role`,children:`A. Billing Role`}),`\n`,_jsxs(_components.p,{children:[`Follow `,_jsx(_components.strong,{children:`only`}),` the tab that matches your billing account type and how you connect it.`]}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`MCA: billing account (recommended)`,id:`mca%3A-billing-account-recommended`,children:[_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`You need Billing account owner`}),` on the MCA billing account. Azure RBAC `,_jsx(_components.strong,{children:`Owner`}),` doesn’t include billing roles. If you’re a `,_jsx(_components.strong,{children:`Global Administrator`}),`, you can give yourself Billing account owner first (see the tip under `,_jsx(_components.a,{href:`#required-access`,children:`Required access`}),`). If you can’t, ask your Billing account owner to do this step. To see who holds this role, go to `,_jsx(_components.a,{href:`https://portal.azure.com/#blade/Microsoft_Azure_GTM/ModernBillingMenuBlade`,children:_jsx(_components.strong,{children:`Cost Management + Billing`})}),` → select your billing account → `,_jsx(_components.strong,{children:`Access control (IAM)`}),`.`]})}),_jsxs(Steps,{children:[_jsx(Step,{title:`Open Your Billing Account`,children:_jsxs(_components.p,{children:[`Go to `,_jsx(_components.a,{href:`https://portal.azure.com/#blade/Microsoft_Azure_GTM/ModernBillingMenuBlade`,children:_jsx(_components.strong,{children:`Cost Management + Billing`})}),` in the Azure portal and select your `,_jsx(_components.strong,{children:`Microsoft Customer Agreement`}),` billing account.`]})}),_jsx(Step,{title:`Assign Billing account reader`,children:_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Access control (IAM)`}),` in the left menu.`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Add`}),` at the top.`]}),`\n`,_jsxs(_components.li,{children:[`Select the role `,_jsx(_components.strong,{children:`Billing account reader`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Search for `,_jsx(_components.strong,{children:`“nOps.io”`}),` and select it.`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Review + assign`}),` (or `,_jsx(_components.strong,{children:`Save`}),`).`]}),`\n`]})})]})]}),_jsxs(Tab,{title:`MCA: billing profiles`,id:`mca%3A-billing-profiles`,children:[_jsx(Info,{children:_jsx(_components.p,{children:`Use this tab only if your organization gives access per billing profile. Billing profiles you don’t add aren’t included in Savings Analysis.`})}),_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`You need Billing profile owner`}),` on each billing profile you add. If you don’t have it, ask the Billing profile owner of that profile to do this step.`]})}),_jsxs(Steps,{children:[_jsxs(Step,{title:`Enter Your Billing Account and Billing Profile IDs`,children:[_jsxs(_components.p,{children:[`In the nOps wizard, enter your `,_jsx(_components.strong,{children:`billing account ID`}),` and the `,_jsx(_components.strong,{children:`billing profile ID`}),` of each profile you want to connect.`]}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Billing account ID:`}),` in `,_jsx(_components.a,{href:`https://portal.azure.com/#blade/Microsoft_Azure_GTM/ModernBillingMenuBlade`,children:_jsx(_components.strong,{children:`Cost Management + Billing`})}),`, open your billing account → `,_jsx(_components.strong,{children:`Properties`})]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Billing profile ID:`}),` open `,_jsx(_components.strong,{children:`Billing profiles`}),` → select the profile → `,_jsx(_components.strong,{children:`Properties`})]}),`\n`]})]}),_jsxs(Step,{title:`Assign Billing profile reader on Each Profile`,children:[_jsxs(_components.p,{children:[`Do this on `,_jsx(_components.strong,{children:`each`}),` billing profile you entered:`]}),_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`In `,_jsx(_components.strong,{children:`Cost Management + Billing`}),`, open your billing account → `,_jsx(_components.strong,{children:`Billing profiles`}),` → select the profile.`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Access control (IAM)`}),` → `,_jsx(_components.strong,{children:`Add`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Select the role `,_jsx(_components.strong,{children:`Billing profile reader`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Search for `,_jsx(_components.strong,{children:`“nOps.io”`}),` and select it.`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Review + assign`}),` (or `,_jsx(_components.strong,{children:`Save`}),`).`]}),`\n`]})]})]})]}),_jsxs(Tab,{title:`Enterprise Agreement (EA)`,id:`enterprise-agreement-ea`,children:[_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`You must be an Enterprise Administrator`}),` on the EA enrollment to complete this step. Microsoft requires enrollment write access to assign EnrollmentReader to a service principal, so `,_jsx(_components.strong,{children:`Enterprise Administrator (read only)`}),`, Department Administrator, and Account Owner cannot do it. Global Administrator and Azure RBAC Owner don’t include EA billing roles, and a Global Administrator can’t give themselves one. If you don’t have this role, ask an Enterprise Administrator to run the script below. Check who holds it in `,_jsx(_components.a,{href:`https://portal.azure.com/#blade/Microsoft_Azure_GTM/ModernBillingMenuBlade`,children:_jsx(_components.strong,{children:`Cost Management + Billing`})}),` → select your EA billing account → `,_jsx(_components.strong,{children:`Access control (IAM)`}),`.`]})}),_jsx(Warning,{children:_jsxs(_components.p,{children:[`Microsoft only supports assigning EA billing roles (such as EnrollmentReader) to a service principal through the REST API, not the Azure portal. Run the script below in `,_jsx(_components.a,{href:`https://shell.azure.com`,children:`Azure Cloud Shell`}),` (Bash, not PowerShell) or a local terminal with the Azure CLI installed. You run this script yourself. nOps doesn’t assign billing roles.`]})}),_jsxs(Steps,{children:[_jsx(Step,{title:`Sign in to Azure CLI`,children:_jsxs(_components.p,{children:[`Open `,_jsx(_components.a,{href:`https://shell.azure.com`,children:`Azure Cloud Shell`}),` (Bash) or run `,_jsx(_components.code,{children:`az login`}),` in your local terminal.`]})}),_jsxs(Step,{title:`Run the EnrollmentReader assignment script`,children:[_jsxs(_components.p,{children:[`Copy and run the following script. Replace `,_jsx(_components.code,{children:`\u003capp-client-id>`}),`, `,_jsx(_components.code,{children:`\u003cenrollment-number>`}),`, and `,_jsx(_components.code,{children:`\u003ctenant-id>`}),` with your values (the nOps wizard pre-fills these in its generated script):`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`28`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`28`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:`# Assign EnrollmentReader role to nOps service principal`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:`# Run in Azure Cloud Shell (Bash, not PowerShell) or a local terminal with Azure CLI`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`NOPS_APP_CLIENT_ID`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`\"\u003capp-client-id>\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:`# Look up the nOps service principal Object ID`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`NOPS_SP_OBJECT_ID`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`$(`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`az`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` ad`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` sp`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` show`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` --id`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`$NOPS_APP_CLIENT_ID`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`\"`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` --query`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"id\"`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` -o`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` tsv`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` 2>`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`/dev/null`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` ||`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` true`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`if`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` [ `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`-z`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`$NOPS_SP_OBJECT_ID`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`\"`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` ]; `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`then`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` echo`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"ERROR: nOps service principal not found. Complete the Admin Consent step first.\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` exit`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` 1`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`fi`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`echo`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"Found nOps service principal: `}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`$NOPS_SP_OBJECT_ID`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`ROLE_ASSIGNMENT_GUID`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`$(`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`uuidgen`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` 2>`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`/dev/null`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` ||`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` cat`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` /proc/sys/kernel/random/uuid`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`az`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` rest`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` --method`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` PUT`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` --url`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:' \"https://management.azure.com/providers/Microsoft.Billing/billingAccounts/\u003cenrollment-number>/billingRoleAssignments/${'}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`ROLE_ASSIGNMENT_GUID`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`}?api-version=2024-04-01\"`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` --body`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` '{`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"properties\": {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"principalId\": \"'\"`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`$NOPS_SP_OBJECT_ID`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`\"'\",`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"principalTenantId\": \"\u003ctenant-id>\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"roleDefinitionId\": \"/providers/Microsoft.Billing/billingAccounts/\u003cenrollment-number>/billingRoleDefinitions/24f8edb6-1668-4659-b5e2-40bb5f3a7d7e\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` }'`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`echo`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"Done. A 200 OK response confirms the EnrollmentReader role was assigned.\"`})]}),`\n`]})})}),_jsx(Tip,{children:_jsx(_components.p,{children:`The nOps wizard generates a ready-to-run script with all values pre-filled (App Client ID, enrollment number, and tenant ID). Copy it directly from the wizard for the easiest experience.`})}),_jsx(Info,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Fallback:`}),` If `,_jsx(_components.code,{children:`az ad sp show`}),` fails, you can find the service principal manually: `,_jsx(_components.code,{children:`az ad sp list --filter \"startswith(displayName, 'nops')\" --query \"[].{name:displayName, objectId:id}\" -o table`}),` and use the `,_jsx(_components.strong,{children:`objectId`}),` value.`]})}),_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`200 OK`}),` response confirms the role was assigned. Service principal role assignments on an EA enrollment are not shown in the Azure portal, so use the nOps `,_jsx(_components.strong,{children:`Verify`}),` step to confirm access. If you have more than one EA billing account, repeat the script for each enrollment.`]})]})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`b-reader-on-the-management-group`,children:`B. Reader on the Management Group`}),`\n`,_jsxs(_components.p,{children:[`Assign `,_jsx(_components.strong,{children:`Reader`}),` on the management group that holds the subscriptions you want in Savings Analysis. You need `,_jsx(_components.strong,{children:`Owner`}),` or `,_jsx(_components.strong,{children:`User Access Administrator`}),` on that management group.`]}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Enter Your Management Group ID`,children:[_jsxs(_components.p,{children:[`In the nOps wizard, enter the `,_jsx(_components.strong,{children:`Management Group ID`}),`. To cover every subscription, click `,_jsx(_components.strong,{children:`Use tenant root`}),`. Your tenant ID is the ID of the root management group.`]}),_jsxs(_components.p,{children:[`Find your management groups in `,_jsx(_components.a,{href:`https://portal.azure.com/#view/Microsoft_Azure_ManagementGroups/ManagementGroupBrowseBlade`,children:`Azure Portal > Management Groups`}),`.`]})]}),_jsx(Step,{title:`Open the Management Group`,children:_jsxs(_components.p,{children:[`Go to `,_jsx(_components.a,{href:`https://portal.azure.com/#view/Microsoft_Azure_ManagementGroups/ManagementGroupBrowseBlade`,children:_jsx(_components.strong,{children:`Management Groups`})}),` in the Azure portal and select the management group.`]})}),_jsx(Step,{title:`Open Access Control`,children:_jsxs(_components.p,{children:[`Click `,_jsx(_components.strong,{children:`Access control (IAM)`}),` in the left menu, then click `,_jsx(_components.strong,{children:`Add`}),` > `,_jsx(_components.strong,{children:`Add role assignment`}),`.`]})}),_jsx(Step,{title:`Select the Role`,children:_jsxs(_components.p,{children:[`On the `,_jsx(_components.strong,{children:`Role`}),` tab, search for and select `,_jsx(_components.strong,{children:`Reader`}),`, then click `,_jsx(_components.strong,{children:`Next`}),`.`]})}),_jsx(Step,{title:`Assign to nOps.io`,children:_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`On the `,_jsx(_components.strong,{children:`Members`}),` tab, set `,_jsx(_components.strong,{children:`“Assign access to”`}),` to `,_jsx(_components.strong,{children:`“User, group, or service principal”`}),` (not “Managed identity”).`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`”+ Select members”`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Search for `,_jsx(_components.strong,{children:`“nOps.io”`}),` by name and select it.`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Select`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Review + assign`}),`.`]}),`\n`]})})]}),`\n`,_jsx(_components.p,{children:`Repeat only if your subscriptions are split across separate management groups.`}),`\n`,_jsx(Heading,{level:`3`,id:`c-focus-cost-export`,children:`C. FOCUS Cost Export`}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Choose the Export Subscription`,children:[_jsx(_components.p,{children:`In the nOps wizard, enter the subscription that will hold the export’s storage account. Choose the subscription with the most spend.`}),_jsxs(_components.p,{children:[`To create the storage account, you need `,_jsx(_components.strong,{children:`Owner`}),` or `,_jsx(_components.strong,{children:`Contributor`}),` on this subscription.`]})]}),_jsxs(Step,{title:`Register Resource Providers`,children:[_jsxs(_components.p,{children:[`Make sure these resource providers are registered on that subscription: `,_jsx(_components.code,{children:`Microsoft.Storage`}),`, `,_jsx(_components.code,{children:`Microsoft.CostManagement`}),`, and `,_jsx(_components.code,{children:`Microsoft.CostManagementExports`}),`.`]}),_jsxs(_components.p,{children:[`Go to `,_jsx(_components.a,{href:`https://portal.azure.com/#view/Microsoft_Azure_Billing/SubscriptionsBlade`,children:_jsx(_components.strong,{children:`Subscriptions`})}),` → select the subscription → `,_jsx(_components.strong,{children:`Settings`}),` → `,_jsx(_components.strong,{children:`Resource providers`}),`, and click `,_jsx(_components.strong,{children:`Register`}),` on any that aren’t registered. Most subscriptions already have these registered. If a provider already shows “Registered”, no action is needed.`]})]}),_jsxs(Step,{title:`Open Exports and Set the Scope`,children:[_jsxs(_components.p,{children:[`Go to `,_jsx(_components.a,{href:`https://portal.azure.com/#view/Microsoft_Azure_CostManagement/Menu/~/exports`,children:_jsx(_components.strong,{children:`Cost Management > Exports`})}),` in the Azure portal. At the top, click `,_jsx(_components.strong,{children:`Change scope`}),` if needed, and select:`]}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`MCA billing account:`}),` your Microsoft Customer Agreement billing account`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`EA:`}),` your EA enrollment (the same enrollment number you entered in the nOps wizard, e.g., `,_jsx(_components.code,{children:`12345678`}),`)`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`MCA billing profiles:`}),` one of your billing profiles. You’ll create a separate export for each profile`]}),`\n`]})]}),_jsx(Step,{title:`Create the Export`,children:_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`+ Create`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Basics`}),` tab: Select the `,_jsx(_components.strong,{children:`“Cost and usage (FOCUS)”`}),` template.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Datasets`}),` tab: Set the export prefix to `,_jsx(_components.code,{children:`nops-clara`}),`. The template sets the frequency to `,_jsx(_components.strong,{children:`Daily`}),`.`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`MCA billing profiles only:`}),` use the prefix the nOps wizard shows for that profile. It’s `,_jsx(_components.code,{children:`nops-clara-`}),` followed by letters and digits from the billing profile ID, in lowercase. This keeps the exports from overwriting each other.`]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Destination`}),` tab:`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Storage type: `,_jsx(_components.strong,{children:`Azure blob storage`})]}),`\n`,_jsx(_components.li,{children:`Subscription: the subscription you entered in the nOps wizard`}),`\n`,_jsxs(_components.li,{children:[`Storage account: Click `,_jsx(_components.strong,{children:`Create new`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Resource group: create a new one named `,_jsx(_components.code,{children:`nops-focus-exports-rg`})]}),`\n`,_jsxs(_components.li,{children:[`Name: `,_jsx(_components.code,{children:`nopsfocus`}),` + the first 15 characters of your tenant ID, without dashes`]}),`\n`,_jsx(_components.li,{children:`Region: any region you choose`}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`Container: `,_jsx(_components.code,{children:`focus-exports`})]}),`\n`,_jsxs(_components.li,{children:[`Directory: `,_jsx(_components.code,{children:`nops-clara`})]}),`\n`,_jsxs(_components.li,{children:[`Format: `,_jsx(_components.strong,{children:`Parquet`})]}),`\n`,_jsxs(_components.li,{children:[`Compression type: `,_jsx(_components.strong,{children:`Snappy`})]}),`\n`,_jsxs(_components.li,{children:[`File partitioning: `,_jsx(_components.strong,{children:`checked`})]}),`\n`,_jsxs(_components.li,{children:[`Overwrite data: `,_jsx(_components.strong,{children:`checked`})]}),`\n`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Review + create`}),`, then `,_jsx(_components.strong,{children:`Create`}),`.`]}),`\n`]})}),_jsxs(Step,{title:`Run the Export and Backfill 3 Months`,children:[_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Open the export and click `,_jsx(_components.strong,{children:`Run now`}),` to trigger the first export.`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Export selected dates`}),` to backfill the previous 3 months, one run per month:`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Run 1:`}),` Start date = first day of three months ago, End date = last day of three months ago`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Run 2:`}),` Start date = first day of two months ago, End date = last day of two months ago`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Run 3:`}),` Start date = first day of previous month, End date = last day of previous month`]}),`\n`]}),`\n`]}),`\n`]}),_jsx(_components.p,{children:`Data will be available within a few hours.`})]})]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`MCA billing profiles:`}),` repeat these export steps for each billing profile you connect, with that profile’s prefix. After the first profile, select the storage account you already created instead of creating a new one.`]})}),`\n`,_jsx(Tip,{children:_jsx(_components.p,{children:`The nOps wizard shows the exact storage account name, resource group, container, and directory you need. Copy these values from the wizard so they match what nOps checks in Verify.`})}),`\n`,_jsx(Heading,{level:`3`,id:`d-storage-blob-data-owner`,children:`D. Storage Blob Data Owner`}),`\n`,_jsxs(_components.p,{children:[`You must be an `,_jsx(_components.strong,{children:`Owner`}),` or `,_jsx(_components.strong,{children:`User Access Administrator`}),` on the storage account to assign Storage Blob Data Owner.`]}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{title:`Open the Storage Account`,children:_jsxs(_components.p,{children:[`Search for `,_jsx(_components.strong,{children:`“Storage accounts”`}),` in the Azure portal’s top search bar, then select the storage account you created in Step C (e.g., `,_jsx(_components.code,{children:`nopsfocus\u003ctenant-prefix>`}),`).`]})}),_jsx(Step,{title:`Assign Storage Blob Data Owner`,children:_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Go to `,_jsx(_components.strong,{children:`Access control (IAM)`}),` → `,_jsx(_components.strong,{children:`Add`}),` → `,_jsx(_components.strong,{children:`Add role assignment`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Under `,_jsx(_components.strong,{children:`Job function roles`}),`, select `,_jsx(_components.strong,{children:`Storage Blob Data Owner`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Select `,_jsx(_components.strong,{children:`User, group, or service principal`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Search for and select `,_jsx(_components.strong,{children:`nOps.io`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Review + assign`}),`.`]}),`\n`]})}),_jsxs(Step,{title:`Configure Firewall (if applicable)`,children:[_jsx(_components.p,{children:`If your organization restricts storage account network access (through Azure Policy or manual settings):`}),_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Go to the storage account > `,_jsx(_components.strong,{children:`Security + networking`}),` > `,_jsx(_components.strong,{children:`Networking`})]}),`\n`,_jsxs(_components.li,{children:[`Under `,_jsx(_components.strong,{children:`Firewall`}),`, add the nOps IP addresses: `,_jsx(_components.code,{children:`44.246.45.84`}),`, `,_jsx(_components.code,{children:`52.11.53.164`}),`, and `,_jsx(_components.code,{children:`52.39.155.200`})]}),`\n`,_jsxs(_components.li,{children:[`Make sure `,_jsx(_components.strong,{children:`“Allow Azure services on the trusted services list”`}),` is checked`]}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Save`})]}),`\n`]}),_jsx(Info,{children:_jsx(_components.p,{children:`Skip this step if your storage account allows public network access (the default). nOps reads the export files from outside Azure, so if a firewall is on, it must allow the nOps IP addresses.`})})]})]}),`\n`,_jsx(Info,{children:_jsxs(_components.p,{children:[`Azure role assignments can take `,_jsx(_components.strong,{children:`2-5 minutes`}),` to propagate. If verification fails right after you assign roles, wait a few minutes and try again.`]})}),`\n`,_jsx(Heading,{level:`3`,id:`finish-in-nops`,children:`Finish in nOps`}),`\n`,_jsxs(_components.p,{children:[`When you’ve completed Steps A through D, return to the nOps wizard and click `,_jsx(_components.strong,{children:`“I’ve completed all steps”`}),` to go to Verify.`]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`4-verify-connection`,children:`4. Verify Connection`}),`\n`,_jsx(_components.p,{children:`nOps checks that each part of the setup is in place.`}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Click Verify Permissions`,children:[_jsxs(_components.p,{children:[`Click the `,_jsx(_components.strong,{children:`Verify Permissions`}),` button. nOps checks:`]}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Reader`}),` — nOps can list your subscriptions`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Billing role`}),` — nOps has Billing account reader (MCA), Billing profile reader (MCA billing profiles), or EnrollmentReader (EA)`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`FOCUS export`}),` — a FOCUS export exists at the right billing scope`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Storage Blob Data Owner`}),` — nOps can list the export container`]}),`\n`]}),_jsxs(_components.p,{children:[`If you connected billing profiles, nOps checks `,_jsx(_components.strong,{children:`Billing profile reader`}),` and a FOCUS export on each profile. It skips a profile’s export check until that profile’s billing role is in place.`]})]}),_jsx(Step,{title:`Review Results`,children:_jsxs(_components.p,{children:[`The wizard shows a pass or fail result for each check. When they all pass, you’ll see `,_jsx(_components.strong,{children:`“Savings Analysis Verified”`}),` with the number of connected subscriptions.`]})})]}),`\n`,_jsxs(Warning,{children:[_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Verification Failed?`}),` — If some checks don’t pass yet:`]}),_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`Wait a few more minutes. Azure role assignments can take time to propagate`}),`\n`,_jsxs(_components.li,{children:[`Check that each role was assigned to `,_jsx(_components.strong,{children:`nOps.io`}),` at the right scope: the billing role (Step A), Reader on the management group (Step B), and Storage Blob Data Owner on the storage account (Step D)`]}),`\n`,_jsx(_components.li,{children:`Check that the FOCUS export exists at your billing account, enrollment, or each billing profile you connected (Step C)`}),`\n`,_jsxs(_components.li,{children:[`Click `,_jsx(_components.strong,{children:`Verify Permissions`}),` to check again`]}),`\n`]})]}),`\n`,_jsx(_components.hr,{}),`\n`,_jsx(Heading,{level:`2`,id:`next-steps`,children:`Next Steps`}),`\n`,_jsx(_components.p,{children:`Once the Savings Analysis integration is verified, nOps begins ingesting your cost data and generating optimization recommendations.`}),`\n`,_jsx(_components.p,{children:`To enable automated purchasing and management of Azure Reservations and Savings Plans, you can upgrade your integration to the Commitment Management tier:`}),`\n`,_jsx(Card,{title:`Azure Commitment Management Setup`,icon:`chart-line`,href:`/azure/commitment-management-setup`,children:_jsx(_components.p,{children:`Configure nOps to manage Azure Reservations and Savings Plans on your behalf, including automated purchasing and optimization.`})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":{"theme":{"light":"github-light","dark":"github-dark"}},"config":{},"pageMetadata":{"title":"Microsoft Azure - Savings Analysis Setup","description":"Connect your Azure environment to nOps for read-only cost visibility, resource inventory, optimization recommendations, and daily FOCUS cost exports.","icon":"plug","href":"/azure/integration-setup"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"FAQs","slug":"faqs","depth":2,"children":[]},{"title":"Overview","slug":"overview","depth":2,"children":[]},{"title":"1. Get Started","slug":"1-get-started","depth":2,"children":[{"title":"Required Access","slug":"required-access","depth":3,"children":[]}]},{"title":"2. Grant Admin Consent","slug":"2-grant-admin-consent","depth":2,"children":[{"title":"Understanding Admin Consent","slug":"understanding-admin-consent","depth":3,"children":[]}]},{"title":"3. Run the Setup","slug":"3-run-the-setup","depth":2,"children":[{"title":"A. Billing Role","slug":"a-billing-role","depth":3,"children":[]},{"title":"B. Reader on the Management Group","slug":"b-reader-on-the-management-group","depth":3,"children":[]},{"title":"C. FOCUS Cost Export","slug":"c-focus-cost-export","depth":3,"children":[]},{"title":"D. Storage Blob Data Owner","slug":"d-storage-blob-data-owner","depth":3,"children":[]},{"title":"Finish in nOps","slug":"finish-in-nops","depth":3,"children":[]}]},{"title":"4. Verify Connection","slug":"4-verify-connection","depth":2,"children":[]},{"title":"Next Steps","slug":"next-steps","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"nopsio","siteName":"nOps Documentation","title":"Microsoft Azure - Savings Analysis Setup - nOps Documentation","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-30T13:34:42.639Z","originalFileLocation":"azure/integration-setup.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Connect your Azure environment to nOps for read-only cost visibility, resource inventory, optimization recommendations, and daily FOCUS cost exports.\">\u003cmeta data-mint-head name=\"application-name\" content=\"nOps Documentation\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Microsoft Azure - Savings Analysis Setup - nOps Documentation\">\u003cmeta data-mint-head property=\"og:description\" content=\"Connect your Azure environment to nOps for read-only cost visibility, resource inventory, optimization recommendations, and daily FOCUS cost exports.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"nOps Documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://help.nops.io/azure/integration-setup\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://nopsio.mintlify.app/_mintlify/api/og/v2?division=Microsoft+Azure\u0026amp;title=Microsoft+Azure+-+Savings+Analysis+Setup\u0026amp;description=Connect+your+Azure+environment+to+nOps+for+read-only+cost+visibility%2C+resource+inventory%2C+optimization+recommendations%2C+and+daily+FOCUS+cost+exports.\u0026amp;theme=1b405a0e606eab946414f3c3\u0026amp;signature=3b26afd5a3779b51ec19f3991249399b2e92314e55060781b7bbd300fd5891ff\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Microsoft Azure - Savings Analysis Setup - nOps Documentation\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Connect your Azure environment to nOps for read-only cost visibility, resource inventory, optimization recommendations, and daily FOCUS cost exports.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://nopsio.mintlify.app/_mintlify/api/og/v2?division=Microsoft+Azure\u0026amp;title=Microsoft+Azure+-+Savings+Analysis+Setup\u0026amp;description=Connect+your+Azure+environment+to+nOps+for+read-only+cost+visibility%2C+resource+inventory%2C+optimization+recommendations%2C+and+daily+FOCUS+cost+exports.\u0026amp;theme=1b405a0e606eab946414f3c3\u0026amp;signature=3b26afd5a3779b51ec19f3991249399b2e92314e55060781b7bbd300fd5891ff\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/nopsio/fqCOsxgCfR4Zn53X/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"nOps Documentation\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0071EA\">\u003clink data-mint-head rel=\"canonical\" href=\"https://help.nops.io/azure/integration-setup\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/azure/integration-setup.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://help.nops.io/#organization\",\"name\":\"nOps Documentation\",\"url\":\"https://help.nops.io\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/nopsio/soDze3u_2cvKfXf7/logo/light.svg?fit=max\u0026auto=format\u0026n=soDze3u_2cvKfXf7\u0026q=85\u0026s=52543d77f0daf2d0e4763930bdc46fe6\"}},{\"@type\":\"WebSite\",\"@id\":\"https://help.nops.io#website\",\"name\":\"nOps Documentation\",\"url\":\"https://help.nops.io\",\"publisher\":{\"@id\":\"https://help.nops.io/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://help.nops.io/azure/integration-setup#webpage\",\"url\":\"https://help.nops.io/azure/integration-setup\",\"name\":\"Microsoft Azure - Savings Analysis Setup\",\"description\":\"Connect your Azure environment to nOps for read-only cost visibility, resource inventory, optimization recommendations, and daily FOCUS cost exports.\",\"dateModified\":\"2026-10-30T13:34:42.639Z\",\"isPartOf\":{\"@id\":\"https://help.nops.io#website\"},\"breadcrumb\":{\"@id\":\"https://help.nops.io/azure/integration-setup#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://help.nops.io/azure/integration-setup#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Cloud provider integrations\",\"item\":\"https://help.nops.io/platform/integrations\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Microsoft Azure\",\"item\":\"https://help.nops.io/azure/prerequisites\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Microsoft Azure - Savings Analysis Setup\",\"item\":\"https://help.nops.io/azure/integration-setup\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://help.nops.io/azure/integration-setup#article\",\"headline\":\"Microsoft Azure - Savings Analysis Setup\",\"name\":\"Microsoft Azure - Savings Analysis Setup\",\"description\":\"Connect your Azure environment to nOps for read-only cost visibility, resource inventory, optimization recommendations, and daily FOCUS cost exports.\",\"url\":\"https://help.nops.io/azure/integration-setup\",\"mainEntityOfPage\":{\"@id\":\"https://help.nops.io/azure/integration-setup#webpage\"},\"dateModified\":\"2026-10-30T13:34:42.639Z\",\"publisher\":{\"@id\":\"https://help.nops.io/#organization\"},\"isPartOf\":{\"@id\":\"https://help.nops.io#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"nOps Documentation\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"nOps Documentation","nav":{"global":null,"tabs":[{"tab":"Guides","groups":[{"group":"Getting Started","pages":[{"title":"Welcome to nOps","sidebarTitle":"Welcome","href":""}]},{"group":"Cloud provider integrations","pages":[{"title":"Integrations","sidebarTitle":"Integrations","href":"/platform/integrations"},{"group":"Amazon Web Services","pages":[{"title":"Amazon Web Services - Integration Setup","icon":"aws","href":"/aws/integration-setup"},{"title":"Amazon Web Services - Commitment Management Setup","icon":"chart-line","href":"/aws/commitment-management-setup"},{"title":"Amazon Web Services - Permissions \u0026 Resources","icon":"shield-check","href":"/aws/permissions-and-resources"}]},{"group":"Google Cloud Platform","pages":[{"title":"Google Cloud Platform - Prerequisites","icon":"list-check","href":"/gcp/prerequisites"},{"title":"Google Cloud Platform - Integration Setup","icon":"plug","href":"/gcp/integration-setup"},{"title":"Google Cloud Platform - Commitment Management Setup","icon":"chart-line","href":"/gcp/commitment-management-setup"},{"title":"Google Cloud Platform - Permissions \u0026 Resources - Savings Analysis","icon":"shield-check","href":"/gcp/permissions-and-resources-sa"},{"title":"Google Cloud Platform - Permissions \u0026 Resources - Commitment Management","icon":"shield-check","href":"/gcp/permissions-and-resources-cm"}]},{"group":"Microsoft Azure","pages":[{"title":"Microsoft Azure - Prerequisites","description":"Understand billing account types, locate your Management Group ID, and prepare your Azure environment for nOps onboarding.","icon":"list-check","href":"/azure/prerequisites"},{"title":"Microsoft Azure - Savings Analysis Setup","icon":"plug","href":"/azure/integration-setup"},{"title":"Microsoft Azure - Setup Script (Azure CLI)","description":"Set up Azure Savings Analysis with one Azure CLI script: what it does, what it needs, how to run it, how to run it again, and how to fix anything it can't do for you.","icon":"terminal","href":"/azure/cli-setup"},{"title":"Microsoft Azure - Commitment Management Setup","icon":"chart-line","href":"/azure/commitment-management-setup"},{"title":"Microsoft Azure - Permissions \u0026 Resources","icon":"shield-check","href":"/azure/permissions-and-resources"},{"title":"Microsoft Azure - Security","icon":"lock-keyhole","href":"/azure/security"}]}]},{"group":"Platform","pages":[{"title":"Home page","sidebarTitle":"Home page","href":"/platform/home"},{"title":"Users and roles","sidebarTitle":"Users and roles","href":"/platform/users"},{"title":"Organizations","sidebarTitle":"Organizations","href":"/platform/organizations"},{"title":"Roles and data scopes","sidebarTitle":"Roles \u0026 data scopes","href":"/platform/roles-and-data-scopes"},{"title":"Notifications","sidebarTitle":"Notifications","href":"/platform/notifications"},{"title":"Issue creation from recommendations","sidebarTitle":"Issue creation","href":"/platform/issue-tracker-notifications"},{"title":"Slack \u0026 Teams Delivery","sidebarTitle":"Slack \u0026 Teams","href":"/platform/slack-and-teams"},{"title":"Security and authentication","sidebarTitle":"Security and auth","href":"/platform/security-and-auth"}]},{"group":"Clara","pages":[{"title":"Ask Clara","sidebarTitle":"Ask Clara","href":"/clara/clara-chat"},{"title":"Canvas","sidebarTitle":"Canvas","href":"/clara/canvas"}]},{"group":"Inform","pages":[{"title":"Inform","href":"/inform/introduction"},{"group":"Explorer","root":{"title":"Explorer","href":"/inform/explorer"},"pages":[{"title":"Explorer Dashboard","href":"/inform/explorer-dashboard"},{"title":"Reports","href":"/inform/reports"}]},{"group":"Recommendations","root":{"title":"Recommendations","href":"/inform/recommendations"},"pages":[{"title":"Supported recommendations","href":"/inform/supported-recommendations"}]},{"title":"Anomalies","href":"/inform/anomalies"},{"title":"MAP Manager","href":"/inform/map-manager"}]},{"group":"AI","pages":[{"title":"Introduction","href":"/ai/introduction"},{"title":"Set up AI seat tracking","href":"/ai/setup"},{"title":"Tracking","href":"/ai/tracking"},{"title":"Requests","href":"/ai/requests"},{"title":"Wallets","href":"/ai/wallets"},{"title":"Budgets","href":"/ai/budgets"},{"title":"Automated Rebalance","href":"/ai/automated-rebalance"},{"title":"AI Recommendations","href":"/ai/recommendations"},{"title":"AI Anomalies","href":"/ai/anomalies"}]},{"group":"Operate","pages":[{"title":"Budgets","href":"/operate/budgets"},{"title":"Business Unit Economics","href":"/operate/business-unit-economics"},{"title":"Cloud \u0026 SaaS Contract Tracker","href":"/operate/contract-tracker"}]},{"group":"Optimize","pages":[{"title":"Commitment Inventory","href":"/optimize/commitment-inventory"}]},{"group":"Third-Party Integrations","pages":[{"title":"Cursor","icon":"key","href":"/integrations/cursor-admin-api"},{"title":"Datadog","icon":"chart-line","href":"/integrations/datadog"},{"title":"MongoDB Atlas","icon":"database","href":"/integrations/mongodb-atlas"},{"title":"Fastly","icon":"globe","href":"/integrations/fastly"},{"title":"Cloudflare","icon":"cloud","href":"/integrations/cloudflare"},{"title":"OpenAI (Platform)","icon":"robot","href":"/integrations/openai"},{"title":"ChatGPT (Enterprise)","icon":"robot","href":"/integrations/openai-enterprise"},{"title":"Anthropic (Platform)","icon":"robot","href":"/integrations/anthropic"},{"title":"Claude.ai (Enterprise)","icon":"robot","href":"/integrations/claude-enterprise"},{"title":"Twilio","icon":"phone","href":"/integrations/twilio"},{"title":"LiteLLM","icon":"route","href":"/integrations/litellm"},{"title":"Atlassian","icon":"key","href":"/integrations/atlassian"},{"title":"GitHub","icon":"key","href":"/integrations/github"},{"title":"GitLab","icon":"key","href":"/integrations/gitlab"},{"title":"Amazon Bedrock","icon":"aws","href":"/integrations/amazon-bedrock"},{"title":"Databricks","icon":"boxes-stacked","href":"/integrations/databricks"},{"title":"Snowflake","icon":"snowflake","href":"/integrations/snowflake"},{"title":"Vercel","icon":"triangle","href":"/integrations/vercel"}]},{"group":"Telemetry","pages":[{"title":"Send OpenTelemetry data to nOps","sidebarTitle":"OpenTelemetry","href":"/telemetry/opentelemetry"}]},{"group":"Plugins","pages":[{"title":"Clara MCP","sidebarTitle":"Clara MCP","href":"/plugins/clara-mcp"},{"title":"Clara Slack Agent","sidebarTitle":"Clara Slack Agent","href":"/plugins/clara-slack-agent"}]},{"group":"Portfolio Portal","pages":[{"title":"Portfolio Portal","sidebarTitle":"Portfolio Portal","href":"/portfolio/introduction"}]},{"group":"Support","pages":[{"title":"nOps Customer Service SLAs","sidebarTitle":"Customer Service SLAs","href":"/support/customer-service-sla"}]}]},{"tab":"Developers","pages":[{"title":"Developers","href":"/developers"}]}]},"basePath":"","title":"Microsoft Azure - Savings Analysis Setup - nOps Documentation","buildId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","deploymentId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","dynamics":[],"chunks":[]}