Skip to content

openshift-online/finops-tools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

finops-tools

FinOps command-line tools. The repository is a Go monorepo with a shared core library and a finops CLI built with Cobra.

Layout

Path Module Role
core/ github.com/openshift-online/finops-tools/core Business logic (no CLI/HTTP dependencies)
cli/ github.com/openshift-online/finops-tools/cli Cobra commands; calls into core
go.work Ties modules together for local development

A future REST API can live in a separate module and import the same core package.

Package map (cli/internal)

Package Role
cmd/ Cobra wiring only: <noun>.go + <noun>_<verb>.go (e.g. report_generate.go)
output/ Human-readable tables and --format handlers
format/ Currency formatting for CLI output
configstore/ FinOps YAML config read/write
account/ Account login flows (account add business logic; not the cmd noun files)
aws/, awsauth/, awslogin/, awsrole/ Credentials, auth orchestration, SAML, role ARNs
report/ HTML templates and charts (distinct from core/report data assembly)
progress/ Progress lines on stderr

core/ grows by domain noun (core/cost, core/report), not by CLI verb. Shared target/credential orchestration stays in cli/ until a third command needs it; see .cursor/rules/cli-commands.mdc for when to split cmd/ into per-noun subpackages.

CLI commands

Every command uses finops <noun> <verb> (e.g. finops account add, finops demo hello). See .cursor/rules/cli-commands.mdc for conventions when adding commands.

Requirements

  • Go 1.24+

Development

From the repository root (uses go.work):

go work sync
make test
make build
./bin/finops demo hello   # prints: hello

Or without Make:

go test ./core/... ./cli/...
go run ./cli/cmd/finops demo hello
go build -o bin/finops ./cli/cmd/finops

Edits under core/ are picked up immediately by the CLI (workspace + replace in cli/go.mod).

Configuration

FinOps stores local settings in a YAML config file:

OS Default path
Linux / macOS $XDG_CONFIG_HOME/finops/config.yaml or ~/.config/finops/config.yaml
Windows %AppData%/finops/config.yaml

The file is created automatically on first finops account add. Example:

defaults:
  aws.auth_method: profile
  aws.linked_role: OrganizationAccountAccessRole
  cost.days: "30"
  cost.exclude_recent_days: "2"
aws:
  account_aliases:
    rh-control: "123456789012"
    osd-staging-1: "987654321098"
    osd-tenant-1:
      account_id: "111111111111"
      payer_alias: rh-control
      role: OrganizationAccountAccessRole
gcp:
  account_aliases: {}

Set defaults using fully qualified names (used when --auth-method is omitted on account add):

finops config default set --name aws.auth-method --value profile
finops config default get --name aws.auth-method
finops config default set --name aws.linked_role --value OrganizationAccountAccessRole
finops config default set --name cost.exclude_recent_days --value 2

Cost query period defaults (cost.days, cost.months, cost.from, cost.to, cost.exclude_recent_days) apply to finops cost get and finops report generate when the matching CLI flag is omitted. Set only one of cost.days, cost.months, or cost.from (optional cost.to with cost.from).

Register a payer account by 12-digit account ID (login + save in config):

finops account add aws 123456789012 --alias rh-control       # auth-method: flag, or config default, else saml
finops account add aws 123456789012 --auth-method profile  # overrides config default
finops account add aws 123456789012 --force

Register a linked account (authenticate to the payer first, then assume a role in the member account):

finops account add aws 111111111111 --alias osd-tenant-1 --payer rh-control
finops account add aws 111111111111 --payer rh-control --role CustomRole

The IAM role name defaults to OrganizationAccountAccessRole, or defaults.aws.linked_role in the finops config. The CLI builds arn:aws:iam::<account-id>:role/<role-name> automatically.

Without --alias, the account ID is used as the config key. Aliases are CLI-only; cost and AWS credential logic use 12-digit account IDs.

List registered accounts (payer vs linked):

finops account list
finops account list aws

Manage AWS Organizations tags on an account (registered alias or 12-digit account ID):

finops account list-tags --account-alias rh-control
finops account list-tags --account-id 111111111111 --payer rh-control
finops account add-tag --account-alias rh-control --tag-key owner --tag-value team-a
finops account add-tag --account-id 111111111111 --tag-key owner --tag-value team-b --force --payer rh-control
finops account update-tag --account-alias rh-control --tag-key owner --tag-value team-c
finops account update-tag --account-id 111111111111 --tag-key env --tag-value prod --force --payer rh-control

Cost Explorer (finops cost get) requires payer accounts only. Linked-account credentials are for member-account APIs, not payer-level billing queries.

Static secrets (API keys, etc.) for other tools live in ~/.config/finops/.env; AWS sessions use ~/.aws/credentials profiles.

AWS payer credentials

Store and verify temporary AWS credentials for a payer account (same profile layout as finops-mcp-aws):

finops account add aws 123456789012

Behavior:

  1. Looks up a profile derived from the account ID in ~/.aws/credentials, then in ~/.aws/config (shared config / SSO).
  2. If the profile exists and STS validation succeeds, reports success without logging in again.
  3. With --auth-method saml (default), if credentials are missing or invalid, runs a native Red Hat Kerberos + SAML login flow and merges temporary credentials into ~/.aws/credentials (other profiles are preserved).
  4. With --auth-method profile, SAML login is skipped. finops account add uses an existing profile when valid (including a ~/.aws profile named like --alias, e.g. rh-control); in an interactive terminal it prompts for access keys only when no matching profile exists. You can also configure the profile yourself (aws configure, aws sso login, etc.) and run account add again to confirm it works.

SAML prerequisites (default login, and --force):

  • Red Hat VPN connected
  • Valid Kerberos ticket (kinit)
  • Kerberos tools available locally (klist, usually present on managed RH laptops)

SAML account matching accepts:

  • 12-digit AWS account ID (recommended for finops account add aws <id>)
  • SAML account display name (for example rh-control)
  • account/role when a specific role name is required

Linked accounts (profile chaining without finops flags)

You can also configure role assumption in ~/.aws/config and use --auth-method profile:

[profile rh-control]
# payer credentials (SAML output, SSO, or keys)

[profile osd-tenant-1]
role_arn = arn:aws:iam::111111111111:role/OrganizationAccountAccessRole
source_profile = rh-control
finops account add aws 111111111111 --alias osd-tenant-1 --auth-method profile

STS validation must report the linked account ID. This registers credentials only; for finops metadata (payer_alias, role) use --payer (and optional --role) as shown above.

Cost (AWS)

Fetch Net Amortized Cost from AWS Cost Explorer for a configurable date range (default: last 30 calendar days, or defaults.cost.* in config). Payer and linked account aliases are supported; linked accounts query Cost Explorer through the registered payer.

finops account add aws 123456789012 --alias rh-control
finops cost get --account-alias rh-control
finops cost get --account-alias rh-control --days 7
finops cost get --account-alias rh-control --months 3
finops cost get --account-alias rh-control --from 2026-01-01 --to 2026-03-31
finops cost get --account-alias rh-control --exclude-recent-days 2   # omit last 2 days (AWS CE lag)
finops cost get --account-alias quay              # linked account (uses payer credentials)
finops cost get --account 123456789012
finops cost get --account-alias rh-control,osd-staging-1
finops cost get --account 123456789012 --format json
finops cost get --account 123456789012 --format csv
finops cost get --account 123456789012 --split-by service
finops cost get --account 123456789012 --split-by account
finops cost get --account 710019948333 --payer rhc   # member account, payer registered; member need not be in config
Flag Description
--account One or more comma-separated 12-digit AWS account IDs (must be registered with account add); at least one of --account or --account-alias is required
--account-alias One or more comma-separated configured aliases (e.g. rh-control, or a linked alias such as quay)
--payer Registered payer alias when using --account for a member account that is not in config (requires --account)
--days Last N calendar days (mutually exclusive with --months and --from/--to)
--months Last N calendar months from the 1st of the month (mutually exclusive with --days and --from/--to)
--from Start date YYYY-MM-DD inclusive (optional --to; otherwise through the latest stable day)
--to End date YYYY-MM-DD inclusive (requires --from; historical only — future dates are rejected)
--exclude-recent-days Omit the last N UTC days from the end anchor (incomplete AWS CE data); default from defaults.cost.exclude_recent_days or 0
--auth-method saml (default) or profile; when omitted, uses defaults.aws.auth_method from config
--config Path to finops config file (default: OS-specific config dir)
--format pretty-print (default), json, or csv
--split-by Group costs by dimension: service (AWS service) or account (linked AWS account ID); includes share % and relative cost bars in pretty-print
--provider aws (default). gcp is reserved for a future release

pretty-print uses colors and Unicode bars when stdout is a TTY. Set NO_COLOR=1 to disable; FORCE_COLOR=1 forces colors when piping to a capable viewer.

Reports

Generate HTML reports from configured accounts. Templates use Jinja2 syntax (rendered with gonja in the CLI binary).

finops report list
finops report generate costs --account-alias rh-control
finops report generate costs --account-alias rh-control -o costs.html
finops report generate costs --account 710019948333 --payer rhc -o member.html

The costs template includes:

  • Total net amortized cost for the selected period (same flags and config defaults as cost get)
  • Breakdown by linked AWS account
  • Breakdown by AWS service
  • Daily cost trend chart (embedded SVG; works when opening the HTML file locally)
Flag Description
template Positional argument: report template name (run finops report list for options)
--format Output format (default: html)
--account Comma-separated payer AWS account IDs (at least one of --account or --account-alias is required)
--account-alias Comma-separated configured aliases
--payer Registered payer alias when using --account for a member account that is not in config (requires --account)
--auth-method saml (default) or profile
--config Path to finops config file
--credentials-file Path to AWS credentials file
--output / -o Write HTML to a file instead of stdout
--quiet Suppress progress messages on stderr (HTML still goes to stdout or --output)
--days, --months, --from, --to, --exclude-recent-days Same period options as finops cost get

Progress lines (credential checks, each Cost Explorer query, render) are printed to stderr so you can redirect HTML safely, e.g. finops report generate ... -o report.html.

Cross-compile (local)

GOOS=linux GOARCH=amd64 go build -o bin/finops-linux-amd64 ./cli/cmd/finops
GOOS=windows GOARCH=amd64 go build -o bin/finops.exe ./cli/cmd/finops
GOOS=darwin GOARCH=arm64 go build -o bin/finops-darwin-arm64 ./cli/cmd/finops

Releases

Releases are built with GoReleaser on tag push (v*). Artifacts include linux, darwin, and windows (amd64 and arm64 where applicable).

  1. Merge changes to the default branch.
  2. Create and push a tag, e.g. git tag v0.1.0 && git push origin v0.1.0.
  3. The Release workflow publishes binaries to GitHub Releases.

Download a release asset, extract it, and run:

finops demo hello

CI

  • Test (.github/workflows/test.yml): runs on pull requests and pushes to main/master.
  • Release (.github/workflows/release.yml): runs on version tags.

About

FINOPS COMMAND LINE TOOLS

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors