giip
SES Proposal
8 min read

Azure Cost Dashboard Guide

Learn how to review Azure subscription costs collected per server (LSSN), broken down by service or resource group, including the projected month-end cost.

๐Ÿš€ Go to Azure Cost โ†’

๐Ÿ“‹ Overview

The Azure Cost Dashboard shows the cost status of the Azure subscription tied to a selected server (LSSN). It reads the latest snapshot (kFactor=azure_cost) that the cost collector periodically gathers and stores in KVS, then visualizes the cost breakdown by service or resource group with a table and bar charts. When the reporting period is month-to-date (MonthToDate), it also projects the month-end cost based on the current daily average.

๐Ÿค– AI/API Quick Start

This section lets an AI agent or script query and analyze the same server-computed results shown on this screen, directly from outside. The screen and the public API use the same shared query service (the canonical stored procedure), so the values match.

1. Prerequisites

  • CSN: project number (e.g. 47).
  • LSSN: server number. If unknown, use the server-list API below, which also returns a default server (default_lssn).
  • API Key: your issued secret key. Keep it only in an environment variable (GIIP_API_KEY).

2. Auth security warning (x-api-key)

  • Authenticate only via the x-api-key request header. Never put the key in the URL query string or body (it leaks into logs/proxies).
  • The examples below hardcode nothing and use only the environment variables GIIP_CSN / GIIP_LSSN / GIIP_API_KEY.

3. Call order (azureCostServers โ†’ azureCost)

  1. Call azureCostServers to get the CSN's server list and default server (default_lssn).
  2. Call azureCost with the desired lssn (or default_lssn) to get the cost detail.

4. Base URL / Method

APIMethodURL
Server listGEThttps://giipfaw.azurewebsites.net/api/azureCostServers?csn={csn}
Cost detailGEThttps://giipfaw.azurewebsites.net/api/azureCost?csn={csn}&lssn={lssn}

5. Query / Header

LocationNameRequiredDescription
querycsnRequiredProject number (integer)
querylssnRequired for azureCostServer number (integer)
headerx-api-keyRequiredYour issued secret key

6. Success response example + field descriptions

Common envelope: { "rstVal": 200, "message": "OK", "data": { ... } }

azureCostServers data:

{
  "csn": 47,
  "default_lssn": 71197,
  "servers": [
    { "lssn": 71197, "hostname": "example-host", "has_azure_cost_snapshot": true, "latest_collected_at": "2026-09-02T22:26:36" }
  ]
}

azureCost data:

{
  "csn": 47,
  "lssn": 71197,
  "source": { "kfactor": "azure_cost", "snapshot_id": 44344061, "collected_at": "2026-09-02T22:26:36" },
  "subscription": { "subscription_id": "<your-subscription-id>", "subscription_name": "<your-subscription>" },
  "period": { "type": "MonthToDate", "start_date": "2026-09-01", "end_date": "2026-09-02", "currency": "KRW", "is_month_to_date": true },
  "totals": { "pretax_cost": 87993.34, "forecast_month_end": 1319900.03 },
  "by_service": [
    { "name": "Azure App Service", "pretax_cost": 38703.06, "ratio_percent": 43.98, "forecast_month_end": 580545.83 }
  ],
  "by_resource_group": [
    { "name": "rg-example-prod", "pretax_cost": 54988.80, "ratio_percent": 62.49, "forecast_month_end": 824832.00, "mapped_csn": null }
  ]
}

Field descriptions:

  • totals.pretax_cost: pre-tax total for the period. totals.forecast_month_end: month-end projection (see 8).
  • by_service[] / by_resource_group[]: already sorted by the server, descending by cost. ratio_percent is the share of the total (%); forecast_month_end is that item's month-end projection.
  • by_resource_group[].mapped_csn: see 9.

7. Error table (HTTP / rstVal)

HTTPrstValExample messageCause
400400csn and lssn are required numeric query parametersMissing/invalid required parameter
401401Missing x-api-key headerMissing or invalid key
403403Access deniedNo access to that CSN
404404No cost data for this serverServer not in the CSN, or no snapshot in the last 30 days
429429Too Many RequestsRate-limited due to excessive calls (see 10)
500500(internal error message)Server error โ€” retry shortly

8. Meaning of the values (pre-tax, currency, snapshot, collected_at, MonthToDate, projection)

  • All costs are pre-tax; the currency is period.currency.
  • Always based on the single most recent snapshot (not real time). The collection time is source.collected_at.
  • If period.type is MonthToDate, it is the running total from the 1st of the month to the collection day (is_month_to_date = true).
  • forecast_month_end is computed only for MonthToDate. Formula: total ร— (days in the month รท collection day-of-month); it is null for other periods.
  • The snapshot has no original period.start_date / end_date, so they are derived from collected_at.

9. Per-service / per-RG analysis and mapped_csn

  • by_service is cost per Azure service; by_resource_group is cost per resource group.
  • mapped_csn is the CSN that owns (is mapped to) that resource group, which may differ from the requested CSN (when the RG is owned by another project). This is ownership information, not an isolation breach; it is null when unmapped.

10. 429 retry

  • To prevent abuse of the public API, excessive calls may return 429 Too Many Requests. If the response has a Retry-After header (seconds), wait that long before retrying; otherwise use exponential backoff (e.g. 1s โ†’ 2s โ†’ 4s).

11. cURL example

# Use environment variables only; never put the key in the URL/body
export GIIP_CSN=47
export GIIP_LSSN=71197          # omit if unknown and use default_lssn below
export GIIP_API_KEY=***your_key***

# 1) Server list + default server
curl -s "https://giipfaw.azurewebsites.net/api/azureCostServers?csn=${GIIP_CSN}" \
  -H "x-api-key: ${GIIP_API_KEY}"

# 2) Single-server cost detail
curl -s "https://giipfaw.azurewebsites.net/api/azureCost?csn=${GIIP_CSN}&lssn=${GIIP_LSSN}" \
  -H "x-api-key: ${GIIP_API_KEY}"

12. PowerShell example

$csn = $env:GIIP_CSN; $lssn = $env:GIIP_LSSN; $key = $env:GIIP_API_KEY
$h = @{ "x-api-key" = $key }
$base = "https://giipfaw.azurewebsites.net/api"

$servers = Invoke-RestMethod -Uri "$base/azureCostServers?csn=$csn" -Headers $h
$target = if ($lssn) { $lssn } else { $servers.data.default_lssn }

$cost = Invoke-RestMethod -Uri "$base/azureCost?csn=$csn&lssn=$target" -Headers $h
"Total pre-tax: $($cost.data.totals.pretax_cost) $($cost.data.period.currency)"
$cost.data.by_service | Select-Object -First 5 name, pretax_cost, ratio_percent

13. Python example (one file: server list โ†’ default LSSN โ†’ cost query โ†’ top 5)

import os, sys, time, json, urllib.request, urllib.error

BASE = "https://giipfaw.azurewebsites.net/api"
CSN = os.environ["GIIP_CSN"]
KEY = os.environ["GIIP_API_KEY"]
LSSN = os.environ.get("GIIP_LSSN")  # if absent, use default_lssn

def call(path):
    req = urllib.request.Request(f"{BASE}/{path}", headers={"x-api-key": KEY})
    for attempt in range(4):
        try:
            with urllib.request.urlopen(req, timeout=30) as r:
                return json.load(r)
        except urllib.error.HTTPError as e:
            if e.code == 429:  # rate-limited โ†’ wait Retry-After then retry
                time.sleep(int(e.headers.get("Retry-After", 2 ** attempt)))
                continue
            sys.exit(f"HTTP {e.code}: {e.read().decode()}")
    sys.exit("429 retries exhausted")

servers = call(f"azureCostServers?csn={CSN}")
lssn = LSSN or servers["data"]["default_lssn"]
cost = call(f"azureCost?csn={CSN}&lssn={lssn}")["data"]

cur = cost["period"]["currency"]
print(f"Total pre-tax: {cost['totals']['pretax_cost']} {cur} "
      f"(forecast {cost['totals']['forecast_month_end']})")
print("Top 5 services:")
for s in cost["by_service"][:5]:
    print(f"  {s['name']}: {s['pretax_cost']} ({s['ratio_percent']:.1f}%)")
print("Top 5 resource groups:")
for g in cost["by_resource_group"][:5]:
    print(f"  {g['name']}: {g['pretax_cost']} ({g['ratio_percent']:.1f}%) mapped_csn={g['mapped_csn']}")

14. Execution order (5 steps)

  1. Set environment variables: GIIP_CSN, GIIP_API_KEY (optionally GIIP_LSSN).
  2. Call azureCostServers โ†’ confirm default_lssn.
  3. Call azureCost โ†’ obtain data.
  4. Analyze totals and top items from totals / by_service / by_resource_group.
  5. Handle 4xx/5xx per the error table; retry 429 using Retry-After.

๐Ÿ” Key Components

1. Service / Resource Group Tabs

The two tabs at the top of the page switch the same data between a by-service and a by-resource-group perspective. Selecting a tab updates only the ?view= value in the address bar (service or rg) without reloading the whole page, so you can share a link to a specific view as-is.

2. Server (LSSN) Selection

Choose the target server whose cost you want to review.

  • Dropdown: The list of servers belonging to the current project (csn) is populated in Hostname (LSSN) form.
  • Direct input: If a server is not in the list or you already know the LSSN, type the number in the input field on the right and press [Run] or Enter.

Once an LSSN is chosen, the latest cost data is queried automatically.

3. Summary Cards

Key metrics are shown as cards above the results.

  • Total Cost: The pre-tax total (total_pretax_cost) for the period, with currency and period (period). Month-to-date data is labeled MonthToDate.
  • Projected Month-End: Appears only for a MonthToDate period, calculated as the current daily average ร— the total number of days in that month.
  • Subscription: The subscription name (subscription_name) and subscription ID (subscription_id).
  • Collected At: The time the data was collected (collected_at) and the queried LSSN.

4. Per-item Cost Table

Depending on the active tab, costs are listed by service or by resource group, ordered from highest cost.

  • #: Rank
  • Service / Resource Group: Item name
  • Cost: Pre-tax cost of the item
  • Projected: Shown only for MonthToDate; the item's share applied to the overall projection
  • Share: The item's ratio of the total cost, shown as a bar with a percentage

5. Assign a CSN (project) to a resource group ยท mapped-RG filter

On the Resource Group tab you can assign a project (CSN) directly from each resource-group row.

  • How to assign: pick a project in the row's [Assign CSN] dropdown and click [Apply] โ€” the resource group is mapped to that CSN (stored in tCsnAzureRg). It then appears in that CSN's Azure-cost view (mapped-RG filter and subtotal).
  • Reassign / unassign: moving an RG that is already mapped to another CSN cleans up the old mapping automatically, keeping 1 RG = 1 CSN. Selecting (Unassigned) and applying removes the mapping.
  • Show only mapped RGs: if the current project (CSN) has one or more mapped RGs, a "Show only mapped RGs" toggle appears. Turning it on filters the current server's resource groups to the mapped RGs and shows a mapped subtotal. With no mappings, all RGs are shown (non-destructive fallback).
  • This inline assignment shares the same mapping data as the dedicated Azure Resource Group Management screen. Use that screen for detailed management including subscription ID and notes.

๐Ÿ› ๏ธ Tips

  • Switch perspective: Use the Service tab to see which Azure services cost the most, and the Resource Group tab to see which groups are largest.
  • Share links: Since the ?view= and ?lssn= values are reflected in the address bar, you can share a specific server and view directly.
  • Use the projection: The projected cost is calculated only when month-to-date data exists. Use it to spot cost spikes early.

๐Ÿ’ก Important Notes

  • All displayed costs are on a pre-tax basis.
  • The dashboard always shows the single most recently collected snapshot. Values are as of the collection time, not real-time.
  • If there is no data, a notice is shown. This usually means the cost collector has not yet run for that server, or no snapshot has been stored.

Troubleshooting

SymptomCauseResolution
Shows "No data"No azure_cost snapshot has been collected for that LSSNVerify that the Azure cost collector has run and stored data on the target server.
Server dropdown is emptyNo project (csn) is selected, or the list failed to loadSelect a project and reopen the page, or type the LSSN directly in the input field on the right.
Projected month-end card/column is missingThe period is not MonthToDateThe projection is only derived from month-to-date data. This is expected for other periods.
Resource Group tab is emptyThe snapshot has no by_resource_group dataConfirm the collector also gathers costs at the resource-group level.
[Assign CSN] dropdown is not shownThe selectable project list failed to load (no membership/network)Confirm you belong to a project and reconnect. The mapped-RG filter and lookups still work.
Mapping does not take effect after [Apply]No permission on the target project (CSN) or API failureConfirm your CSN permission; if it persists, contact an administrator.
An error message appears during queryNetwork error or failed API responseRetry [Run] after a moment; if it persists, contact your administrator.

Version: 1.1 Last Updated: 2026-07-24 Source: giipv3/public/help/azure-cost.en.md