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
Use Step by step if
- 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.
What the script sets up
These are the same four parts as the manual setup.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: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-exportalready 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
- 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.
- 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.
- 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.
- 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.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
bashinstead.
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
Open the script in nOps
Optional: run the preview
Copy the script
Paste it into Azure Cloud Shell
Read the summary
Finish anything left, then run it again
nOps finishes on its own
Reading the output
Every line starts with a tag:The summary
The summary has up to four parts:- Already in place … kept as is: everything the script found and left alone.
- Done in this run: everything this run created or assigned.
- Not done: what was skipped (your account doesn’t have the role) or failed (Azure returned an error).
- 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.
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: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
- Run the script as the person with Azure roles (or the preview, to see who’s needed).
- 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.
- They run it. It keeps what’s done and does their part.
Billing account, billing profiles and EA
How the export subscription is picked
If you leave Export subscription ID blank, the script picks the first that applies:- The subscription where the export storage account already is (from an earlier run).
- Your Azure CLI’s current subscription, if your account can create resources there.
- The first subscription where your account can create resources.
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.
REPORT_URL="" at the top of the script. The preview never sends anything.
Troubleshooting
Before any change is made
The Azure CLI isn't installed here
The Azure CLI isn't installed here
az login --tenant <your tenant ID>.This Azure CLI is version … the script needs 2.37 or later
This Azure CLI is version … the script needs 2.37 or later
az upgrade, or use Azure Cloud Shell (always current). Older versions name things differently, and nOps.io would look missing.You're not signed in / You're signed in to tenant …, but nOps is connected to …
You're not signed in / You're signed in to tenant …, but nOps is connected to …
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 Azure sign-in … has expired or needs to be renewed
Your Azure sign-in … has expired or needs to be renewed
az login --tenant <your tenant ID> and run the script again.nOps.io isn't in this tenant yet
nOps.io isn't in this tenant yet
… can't see subscription … / can't see a subscription in tenant …
… can't see subscription … / can't see a subscription in tenant …
Couldn't read management group …
Couldn't read management group …
During the steps
[needs] … needs Owner or User Access Administrator / needs Billing account owner
[needs] … needs Owner or User Access Administrator / needs Billing account owner
an Azure Policy in your tenant blocked it (RequestDisallowedByPolicy)
an Azure Policy in your tenant blocked it (RequestDisallowedByPolicy)
nops-focus-exports-rg resource group, then run the script again.Storage account name … is already used outside subscription …
Storage account name … is already used outside subscription …
MissingSubscriptionRegistration
MissingSubscriptionRegistration
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.PrincipalNotFound / Azure hasn't finished creating the identity
PrincipalNotFound / Azure hasn't finished creating the identity
You can see … Microsoft Customer Agreement billing accounts
You can see … Microsoft Customer Agreement billing accounts
This tenant's billing account is an Enterprise Agreement
This tenant's billing account is an Enterprise Agreement
nOps sets up Microsoft Customer Agreement and Enterprise Agreement billing accounts …
nOps sets up Microsoft Customer Agreement and Enterprise Agreement billing accounts …
No Microsoft Customer Agreement billing account is visible to …
No Microsoft Customer Agreement billing account is visible to …
An export named nops-clara-focus-export at … writes to another storage account
An export named nops-clara-focus-export at … writes to another storage account
focus-exports, or delete it, then run the script again.An export named nops-clara-focus-export at … exports …, not FOCUS cost
An export named nops-clara-focus-export at … exports …, not FOCUS cost
FOCUS export … writes to container …, not focus-exports
FOCUS export … writes to container …, not focus-exports
focus-exports, then run the script again.FOCUS export … is turned off
FOCUS export … is turned off
Couldn't read the exports at …, so nothing was changed there
Couldn't read the exports at …, so nothing was changed there
Billing profile … wasn't found in billing account …
Billing profile … wasn't found in billing account …
Runs of … already queued
Runs of … already queued
Couldn't start … for (a month). Run this script again later to retry
Couldn't start … for (a month). Run this script again later to retry
Couldn't send progress to nOps
Couldn't send progress to nOps
- 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.
On the nOps setup page
An item shows as waiting
An item shows as waiting
An item shows as not found after the script said done
An item shows as not found after the script said done
Verify fails after the script finished
Verify fails after the script finished
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
Can we read the script before running it?
Can we read the script before running it?
Does the script give nOps more access than the manual setup?
Does the script give nOps more access than the manual setup?
Does nOps get our credentials?
Does nOps get our credentials?
Can we run it in a pipeline instead of by hand?
Can we run it in a pipeline instead of by hand?
NOPS_SETUP_YES=1 to skip the question. Run the preview first and review its output in your change process.What if our naming or tagging policy requires other names?
What if our naming or tagging policy requires other names?
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.We changed the management group or export subscription after a first run
We changed the management group or export subscription after a first run
Does the script set up Commitment Management?
Does the script set up Commitment Management?