Skip to main content

Overview

The setup script is the automated way to do Run the Setup (steps A to D) for Azure Savings Analysis. You copy it from the nOps wizard and paste it into Azure Cloud Shell. It sets up the same things you would set up by hand in the Azure portal, with the same names and the same access for nOps. Nothing more. Choose it in the wizard at Run Setup → Run an Azure CLI script. The other choice, Step by step, is the portal walkthrough. Both end at the same place, and you can switch between them at any time.

Use the script if

You (or someone on your team) can run Azure CLI commands, and you’d rather not click through four portal steps.

Use Step by step if

Your organization only allows changes through the Azure portal, or a change ticket has to list each portal action.
In short, the script:
  • Shows what it will do, and what your account is allowed to do, before it changes anything.
  • Does every step your account can do, and skips the ones it can’t (it doesn’t fail on them).
  • Ends with a numbered list of what is left. For each item it says who can do it, where in the Azure portal, and the exact command with your values filled in.
  • Is safe to run again, on any day and by anyone. It checks each step, keeps what is already there, and never creates anything twice.
  • Grants nOps only the access the manual setup asks for.
  • Covers Savings Analysis only. Commitment Management has its own setup.
Before you start: finish Get Started and Grant Admin Consent in the nOps wizard. The script needs the nOps.io enterprise application to exist in your tenant, and consent is what adds it.

What the script sets up

These are the same four parts as the manual setup. The export uses its own Azure identity to write files. When the export is created, Azure gives that identity Storage Blob Data Contributor on the focus-exports container. The script checks for it and, only if it is missing (for example on an export made by hand whose access was later removed), assigns it on the export storage account, as the Azure portal does. This identity belongs to the export in your tenant. It is not nOps.

Exactly the same access as the manual setup

The script gives nOps.io the same three roles at the same scopes as Step by step: It never assigns Owner, Contributor, User Access Administrator, any billing owner or contributor role, or any role at subscription or tenant scope. nOps tests this on every change to the script. For every role ID and what it allows, see Permissions & Resources.

What the script never does

  • It never deletes anything, and never changes a resource it didn’t create.
  • It never replaces an export. If an export named nops-clara-focus-export already writes somewhere else, the script tells you and leaves it alone.
  • It never creates a second storage account, export or role assignment for something that already exists.
  • It never stores or sends your Azure credentials. It runs as you, in your own Azure CLI session.
  • It never reads your cost data or resources itself, and never sends them to nOps.

How it works

  1. You run the script in your own Azure CLI session. Every change is made by your account, so Azure’s activity log shows you made it.
  2. The script reports each step’s result to nOps: done, skipped, needs another role, or the Azure error code with a one-line message. That’s all it sends. It never waits on nOps; if nOps can’t be reached, setup carries on.
  3. nOps checks your tenant on its own, as the nOps.io application, with the read access the script just gave it. The setup page in nOps ticks each part off as Azure shows it.
  4. When every required part is in place, nOps runs Verify for you and turns Savings Analysis on.

One run, step by step


Before you start

Who should run it

The script does what the signed-in account is allowed to do. One person with all the roles below can finish in one run. Otherwise, run it as one person, then have the next person run the same script. See Splitting the work between people. The person who does step 4 also needs to be able to write to the export storage account (for example, Owner on the resource group nops-focus-exports-rg), because the export’s identity gets access to it.

Where to run it

  • First time in Cloud Shell: choose Bash, then No storage account required and any subscription. Nothing is created in your tenant, and the script uses its own export subscription whatever you pick.
  • After pasting, press Enter. Cloud Shell and most terminals hold a multi-line paste until you do. The script then shows what it will do and asks before it changes anything.
  • Pasting works in Cloud Shell, macOS Terminal (zsh) and Linux shells. In PowerShell it doesn’t: save the file and run it with bash instead.
The script checks the Azure CLI version, the tenant you’re signed in to, and that your sign-in hasn’t expired, before it does anything.

What to choose in nOps first

  • Billing account type (Get Started): Microsoft Customer Agreement (MCA) or Enterprise Agreement (EA). For EA, enter the enrollment number.
  • Billing account or billing profiles (MCA only): we recommend the billing account. Choose billing profiles only if your organization gives access per billing profile; then list each profile. See billing scopes.
  • Where it goes (optional, under Change in Run Setup):
    • Management group ID: leave it blank to use the tenant root group.
    • Export subscription ID: leave it blank and the script picks one when it runs (see How the export subscription is picked).
    • Billing account ID (MCA): leave it blank and the script finds it. Enter it only if you can see more than one billing account.

Run it

1

Open the script in nOps

In the nOps wizard, go to Run Setup and choose Run an Azure CLI script. Check Where it goes, and use Change if you want a specific management group or export subscription.
2

Optional: run the preview

Click Copy preview and paste it into Cloud Shell. The preview runs every check and lists exactly what the real script would change. It changes nothing and sends nothing to nOps. Use it for a change review, or to see what your account can and can’t do.
3

Copy the script

Click Copy setup script (or Download). You can also expand Read the script to see every line first. The script has your tenant’s values filled in. From now on, the nOps setup page watches your tenant.
4

Paste it into Azure Cloud Shell

Open Azure Cloud Shell (Bash), paste, and press Enter. The script prints what it will do, what your account can do, and then asks Start the setup now? [Y/n]. Nothing has changed up to this point.
5

Read the summary

The script ends with a summary of what was already in place, what this run did, and, if anything is left, a numbered list of how to finish it. See Reading the output.
6

Finish anything left, then run it again

Do the items in the list yourself, or send the list to the person it names. Then run the same script again: it keeps everything and only does what’s left. Repeat until the summary says Setup is done.
7

nOps finishes on its own

The setup page in nOps ticks off each part as Azure shows it (usually within a few minutes; Azure can take up to about 10 minutes to apply new access). When everything required is found, nOps runs Verify and turns on Savings Analysis. You can also click Already set up? Verify now.

Reading the output

Every line starts with a tag:

The summary

The summary has up to four parts:
  1. Already in place … kept as is: everything the script found and left alone.
  2. Done in this run: everything this run created or assigned.
  3. Not done: what was skipped (your account doesn’t have the role) or failed (Azure returned an error).
  4. To finish setup, do these: one numbered item per thing left. Each item says:
    • What to do, with the names of your resources.
    • Who can do it: the Azure or billing role needed.
    • Easiest: ask that person to run the same script.
    • In the Azure portal: the menu path.
    • With the Azure CLI: the exact command, with your tenant’s values filled in.
Example, from a run by an Azure administrator who isn’t a billing owner:
The script exits with code 0 when setup is done or only needs someone else, and 1 when Azure returned an error.

Running it again

Expect to run the script more than once. A common pattern:
  • Day 1: an Azure administrator runs it. Reader and the storage account are done. The billing steps are listed for a billing owner.
  • Between runs: someone does some items by hand in the portal, or the billing owner gets the script.
  • Day 2: the billing owner runs the same script. It finds everything from day 1 and from the manual work, keeps it, and only does the billing role and the export.
  • Day 3, or any later run: nothing is left. The script changes nothing and says so.

How it avoids creating things twice

The script checks Azure for each item before it creates anything: Every name is fixed: there are no random names or timestamps. A re-run can’t leave behind duplicates that sit unused.

What a re-run never does

  • It doesn’t undo or overwrite anything you did by hand. If you created a role assignment or the export in the portal, it’s found and kept.
  • It doesn’t need a fresh copy of the script. A copy more than 3 days old still sets everything up; it just stops reporting progress to nOps (the script says so once). Copy it again from nOps to see each step’s result on the setup page.
  • It doesn’t start a new storage account in another subscription. If your Azure CLI is now set to a different subscription, the script still finds the existing account and uses it.

Splitting the work between people

  1. Run the script as the person with Azure roles (or the preview, to see who’s needed).
  2. Send the same script (or just the to-do list from its summary) to the person each item names, for example your billing account owner.
  3. They run it. It keeps what’s done and does their part.

Billing account, billing profiles and EA

If you choose MCA but your tenant’s billing account is an Enterprise Agreement, the script says so and tells you to switch the billing account type in nOps.

How the export subscription is picked

If you leave Export subscription ID blank, the script picks the first that applies:
  1. The subscription where the export storage account already is (from an earlier run).
  2. Your Azure CLI’s current subscription, if your account can create resources there.
  3. The first subscription where your account can create resources.
It only picks a subscription under the management group you connected, because that’s where nOps has Reader: a storage account anywhere else would be invisible to nOps. If the storage account from an earlier run is outside the group, the script keeps it and adds a to-do: give nOps.io Reader on that storage account only. If your account can’t create resources in any subscription under the group, it uses one it can see there and lists the storage step for someone with Owner there. It prints the subscription it chose. To use another one, run az account set --subscription <ID> and run the script again (before the storage account exists), or enter it under Change in nOps. After setup, nOps finds the storage account by its name and saves the subscription.

What the script sends to nOps

Only step results, so the setup page can show progress and why something failed:
  • The step name and its result (started, done, needs another role, skipped, failed).
  • The Azure error code, such as AuthorizationFailed, and a one-line message.
  • A run ID and the script version.
It sends no credentials, tokens, resource contents, cost data or personal data. The script authenticates to nOps with a single-purpose token that can only post step results for your integration, expires after 3 days, and is stored by nOps only as a hash. To turn reporting off, set REPORT_URL="" at the top of the script. The preview never sends anything.

Troubleshooting

Before any change is made

Run it in Azure Cloud Shell, or install the Azure CLI and sign in with az login --tenant <your tenant ID>.
Run az upgrade, or use Azure Cloud Shell (always current). Older versions name things differently, and nOps.io would look missing.
Run az login --tenant <the tenant ID the script shows>, then run the script again. In Cloud Shell, you may need to switch directory first (Cloud Shell → Settings → Switch directory).
Your sign-in timed out, or your organization requires multi-factor authentication again. Run az login --tenant <your tenant ID> and run the script again.
Admin consent hasn’t been granted in this tenant, or the nOps.io enterprise application was deleted. Finish Grant Admin Consent in the nOps wizard (a Global Administrator or Privileged Role Administrator), then run the script again.
Your account has no access to the export subscription. Sign in as someone who has, or enter a subscription you can see under Change in nOps.
A note, not an error: your account can’t see that management group, so assigning Reader there will probably need someone else. Check the ID under Change in nOps (leave it blank for the tenant root group).

During the steps

Your account doesn’t have that role. The step is skipped and listed at the end with who can do it, the portal path and the exact command. Ask that person to do it, or to run the same script.
Azure refused the change. Same fix as above. If you do hold the role, it may have been granted in the last few minutes: wait 5 to 10 minutes and run the script again.
A policy in your tenant doesn’t allow the resource as the script creates it (for example, a required tag, a location restriction, or storage settings). The Azure error above the line names the policy. Ask your cloud team to allow it or exempt the nops-focus-exports-rg resource group, then run the script again.
The storage account from an earlier setup exists in another subscription. Storage account names are unique across Azure, so it can’t be created again. In the Azure portal, search Storage accounts for the name and note its subscription. In nOps, enter that subscription under Change, copy the script again and run it. If you can’t see it, it’s in a subscription your account can’t access: ask an Azure administrator.
The export subscription hasn’t finished registering a resource provider. The script registers them and waits, but registration can need Contributor on the subscription. Run the az provider register … command from the to-do list (or Subscriptions → your subscription → Resource providers → Register), wait a few minutes, and run the script again.
Azure is still creating nOps.io’s identity (right after consent) or the export’s identity. The script already retries for about a minute. Wait a few minutes and run it again.
Your account can see more than one MCA billing account, so the script doesn’t guess. In the Azure portal, open Cost Management + Billing → Billing scopes, open the account nOps should analyze, and copy its ID from Properties. Enter it under Billing account ID in nOps, copy the script again and run it.
nOps is set to MCA, but your billing account is EA. In nOps, go back to Get Started, choose Enterprise Agreement, enter your enrollment number, copy the script again and run it.
Your account only sees another kind of billing account (for example pay-as-you-go, or a CSP partner’s). That isn’t supported by Savings Analysis. Contact nOps support.
Your account has no billing role. Steps 3 and 4 need a billing owner: ask them to run the same script.
An export with nOps’s name already exists and writes somewhere else. The script never changes exports it didn’t create. In Cost Management → Exports (at that billing scope), either edit it to write to the nOps storage account, container focus-exports, or delete it, then run the script again.
An export with nOps’s name already exists but exports another kind of cost data. The script never changes exports it didn’t create. If nobody needs it, delete it in Cost Management → Exports (at that billing scope), then run the script again to create the FOCUS export.
A FOCUS export already delivers to the nOps storage account, but into another container, which nOps doesn’t read. Edit it in Cost Management → Exports to use container focus-exports, then run the script again.
The export exists but its schedule is inactive, so no new cost files arrive. Turn it back on in Cost Management → Exports (schedule Active, daily), then run the script again.
The script couldn’t list the existing exports, so it didn’t create one (it could have replaced someone else’s). Usually this means your account has no billing access there. Ask a billing owner to run the script, or follow the portal steps in the to-do list.
Azure has no billing profile with that ID in your billing account, so the script skipped it and set up the others. Check the ID in the Azure portal (Cost Management + Billing → Billing scopes → your billing account → Billing profiles → the profile → Properties), correct it under Billing profiles in nOps, copy the script again and run it.
A note: runs from an earlier run of the script are still in progress. Azure finishes them on its own.
Azure didn’t accept the run request (usually because the export’s storage access is still applying). The export runs daily on its own. Running the script again later retries the history runs.
A note, followed by the reason:
  • this copy of the script is more than 3 days old: copy it again from nOps.
  • this machine couldn’t reach nOps: a firewall or proxy blocks the machine from reaching nOps. Azure Cloud Shell can always reach it.
  • this copy has sent too many reports: copy it again from nOps.
Either way setup carries on, and nOps still checks your tenant directly, so the setup page finishes on its own. Only the per-step results are missing from it.
Azure was busy. The script retries each call up to four times. If it still fails, run the script again a few minutes later: nothing already done is repeated.

On the nOps setup page

Azure can take up to about 10 minutes to apply new access. nOps keeps checking for 30 minutes after you copy the script; click Check now to check again after that.
Wait 10 minutes and click Check now. If it’s still missing, the line under the item shows what the script reported. Run the script again: it repairs what’s missing and keeps the rest.
Open the failing part in Verify. You can switch to Step by step at any time: those steps show the same checks with portal instructions. Then run Verify again.

Undoing the setup

The script never removes anything. To remove what it set up, as someone with the same roles:
  • Reader: Management groups → your management group → Access control (IAM) → Role assignments → remove nOps.io.
  • Storage: delete the resource group nops-focus-exports-rg (this deletes the storage account, the export files and its role assignments).
  • Billing role: Cost Management + Billing → your billing scope → Access control (IAM) → remove nOps.io.
  • Export: Cost Management → Exports (at your billing scope) → delete nops-clara-focus-export. The export’s files stay in the storage account until you delete them or the resource group.
  • To remove all nOps access at once, delete the nOps.io enterprise application in Microsoft Entra ID → Enterprise applications.

FAQs

Yes. In the nOps wizard, expand Read the script, or click Download and open the file. You can also run the preview, which makes no changes and lists exactly what would change.
No. It assigns nOps.io exactly the three roles the manual steps ask for, at the same scopes: Reader on the management group, Storage Blob Data Owner on the one storage account, and the billing reader role. nOps tests this on every change to the script.
No. The script runs in your Azure CLI session, as you. nOps only receives step results (done, needs a role, or an error code).
Yes. When there’s no terminal it doesn’t ask for confirmation. You can also set NOPS_SETUP_YES=1 to skip the question. Run the preview first and review its output in your change process.
The names are fixed because nOps looks for them. The resource group and storage account are tagged managed_by=nOps and purpose=nops-focus-export. If a policy blocks them, the script shows the policy and leaves the rest of the setup in place; ask your cloud team for an exemption for nops-focus-exports-rg.
The script sets up the new one. It doesn’t remove access from the old one; remove it by hand if you no longer want it (see Undoing the setup). The storage account can only exist once: if it already exists, keep using its subscription.
No. Commitment Management is a separate step with its own permissions, done after Savings Analysis is active. See Commitment Management setup.