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.
๐ 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-keyrequest 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)
- Call
azureCostServersto get the CSN's server list and default server (default_lssn). - Call
azureCostwith the desiredlssn(ordefault_lssn) to get the cost detail.
4. Base URL / Method
| API | Method | URL |
|---|---|---|
| Server list | GET | https://giipfaw.azurewebsites.net/api/azureCostServers?csn={csn} |
| Cost detail | GET | https://giipfaw.azurewebsites.net/api/azureCost?csn={csn}&lssn={lssn} |
5. Query / Header
| Location | Name | Required | Description |
|---|---|---|---|
| query | csn | Required | Project number (integer) |
| query | lssn | Required for azureCost | Server number (integer) |
| header | x-api-key | Required | Your 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_percentis the share of the total (%);forecast_month_endis that item's month-end projection.by_resource_group[].mapped_csn: see 9.
7. Error table (HTTP / rstVal)
| HTTP | rstVal | Example message | Cause |
|---|---|---|---|
| 400 | 400 | csn and lssn are required numeric query parameters | Missing/invalid required parameter |
| 401 | 401 | Missing x-api-key header | Missing or invalid key |
| 403 | 403 | Access denied | No access to that CSN |
| 404 | 404 | No cost data for this server | Server not in the CSN, or no snapshot in the last 30 days |
| 429 | 429 | Too Many Requests | Rate-limited due to excessive calls (see 10) |
| 500 | 500 | (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.typeisMonthToDate, it is the running total from the 1st of the month to the collection day (is_month_to_date = true). forecast_month_endis computed only forMonthToDate. Formula:total ร (days in the month รท collection day-of-month); it isnullfor other periods.- The snapshot has no original
period.start_date/end_date, so they are derived fromcollected_at.
9. Per-service / per-RG analysis and mapped_csn
by_serviceis cost per Azure service;by_resource_groupis cost per resource group.mapped_csnis 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 isnullwhen unmapped.
10. 429 retry
- To prevent abuse of the public API, excessive calls may return
429 Too Many Requests. If the response has aRetry-Afterheader (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)
- Set environment variables:
GIIP_CSN,GIIP_API_KEY(optionallyGIIP_LSSN). - Call
azureCostServersโ confirmdefault_lssn. - Call
azureCostโ obtaindata. - Analyze totals and top items from
totals/by_service/by_resource_group. - Handle 4xx/5xx per the error table; retry
429usingRetry-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 labeledMonthToDate. - Projected Month-End: Appears only for a
MonthToDateperiod, 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
| Symptom | Cause | Resolution |
|---|---|---|
| Shows "No data" | No azure_cost snapshot has been collected for that LSSN | Verify that the Azure cost collector has run and stored data on the target server. |
| Server dropdown is empty | No project (csn) is selected, or the list failed to load | Select a project and reopen the page, or type the LSSN directly in the input field on the right. |
| Projected month-end card/column is missing | The period is not MonthToDate | The projection is only derived from month-to-date data. This is expected for other periods. |
| Resource Group tab is empty | The snapshot has no by_resource_group data | Confirm the collector also gathers costs at the resource-group level. |
| [Assign CSN] dropdown is not shown | The 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 failure | Confirm your CSN permission; if it persists, contact an administrator. |
| An error message appears during query | Network error or failed API response | Retry [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