Skip to content

Repository files navigation

AWS Cost Tracker — Stream Deck plugin

Show your AWS month-to-date cost on a Stream Deck key, per profile, read from your local ~/.aws credentials. Two actions:

  • Account Cost — one key, one profile: the profile name, the cost so far this month (big), and the month underneath.
  • Two Account Costs — one key, two profiles stacked: each profile name over its month-to-date cost.

Example Stream Deck keys: a single-account key showing Production $1,284, and a two-account key stacking Production $1,284 over Staging $312.

Example keys — the Account Cost action (left) and Two Account Costs action (right).

Not affiliated with Amazon Web Services.

How it works

  • Uses your local credentials. The plugin lists the profiles in ~/.aws/credentials and ~/.aws/config (honouring AWS_SHARED_CREDENTIALS_FILE / AWS_CONFIG_FILE) and resolves each selected profile with the AWS SDK's standard chain (fromIni) — so static keys, SSO, credential_process, and assumed roles all work, exactly as the AWS CLI would.
  • Month-to-date cost. It calls the Cost Explorer API (GetCostAndUsage, MONTHLY granularity, UnblendedCost) for the current UTC month — the same figure the AWS console shows as "Month-to-date cost". Cost Explorer is only reachable in us-east-1, so the plugin always talks to that endpoint (your resources can live anywhere).
  • Refresh that respects the meter. Each Cost Explorer request is billed at about $0.01, and AWS only updates billing data a few times a day. So the refresh interval is in hours, not seconds — default every 6 hours, selectable from Manual up to Once a day in the property inspector.
  • Manual refresh. Press the key to refresh that profile immediately.
  • Custom label. Set a Show as name in the property inspector to display anything you like on the key instead of the raw profile name (e.g. personalProd). Logs still use the real profile name. Leave it blank to show the profile.
  • Shared fetches, no double billing. Every key shares one per-profile cache: a profile used by several keys (e.g. a single key and one side of a two-account key) is only fetched once per its refresh window — never billed twice for the same window.
  • Stays readable when a refresh fails. If a refresh fails, the last good figure stays on the key — dimmed, with a small amber dot, to read as "not live" — instead of flipping to an error. The error screen only shows when there's no figure yet.

Refresh interval & cost

Interval Requests/day per profile ≈ Cost/month per profile
Every hour 24 ~$7.20
Every 3 h 8 ~$2.40
Every 6 h 4 ~$1.20
Every 12 h 2 ~$0.60
Once a day 1 ~$0.30
Manual only when you press ~$0

Because billing data only settles a few times a day, every 6 hours is the default sweet spot — more frequent polling mostly just spends money on Cost Explorer without showing you anything new. Press the key any time you want a figure now.

Requirements

  • macOS 12+, Stream Deck 6.5+
  • Node.js 20+ (bundled with the Stream Deck app at runtime; 20+ to build)
  • An AWS profile in ~/.aws whose credentials can call ce:GetCostAndUsage

Minimal IAM policy for the profile:

{
  "Version": "2012-10-17",
  "Statement": [{ "Effect": "Allow", "Action": "ce:GetCostAndUsage", "Resource": "*" }]
}

Troubleshooting

The key shows a short hint when it can't display a figure:

  • configure — no profile is selected yet. Open the property inspector and pick one.
  • profile — the selected profile isn't in ~/.aws (renamed/removed).
  • creds — the profile has no usable credentials, or AWS rejected them.
  • login — credentials/SSO session expired. Run aws sso login (or refresh keys), then press the key.
  • access — the credentials work but lack ce:GetCostAndUsage. Attach the policy above.
  • busy — Cost Explorer rate-limited the request; it backs off and recovers on its own.
  • offline — couldn't reach AWS; recovers once you're back online.

Dimmed key. A dimmed key with an amber dot is showing the last good figure because the most recent refresh failed — press it to retry.

Logs live at ~/Library/Application Support/com.elgato.StreamDeck/Plugins/tphan.awscost.sdPlugin/logs/.

Develop

npm install
npm run gen:icons        # generate the PNG icons
npm run build            # bundle src/ into the .sdPlugin/bin
npx streamdeck link tphan.awscost.sdPlugin   # install the dev plugin
npm run watch            # rebuild + restart on change

npm run lint type-checks without emitting.

Package for distribution

npm run build
npx streamdeck pack tphan.awscost.sdPlugin

This produces a .streamDeckPlugin installer.

Project layout

src/
  plugin.ts                 entrypoint — registers both actions
  render.ts                 SVG → data-URI key images (single, dual, error)
  actions/
    cost-action.ts          shared base: lifecycle + property-inspector profile list
    poller.ts               shared per-profile scheduler (one fetch per refresh window, backoff, stale)
    single-cost.ts          the "Account Cost" action
    dual-cost.ts            the "Two Account Costs" action
  aws/
    client.ts               Cost Explorer month-to-date fetch + error → hint mapping
    profiles.ts             list profiles from ~/.aws/credentials + ~/.aws/config
    format.ts               currency + month-label formatting
    types.ts                settings, reading, and per-profile state types
scripts/gen-icons.mjs       generates plugin/action PNGs
tphan.awscost.sdPlugin/     the installed plugin package (manifest, ui, imgs, bin)

Notes

  • "This month" is the UTC calendar month, matching the Cost Explorer API.
  • Costs use UnblendedCost (the console's default month-to-date metric) in the currency Cost Explorer reports for the account.
  • Changing a profile's credentials on disk may need a plugin restart (npx streamdeck restart tphan.awscost) to be picked up.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages