Skip to content

User Guide

This guide is for anyone who wants to use FinFocus to see costs for their Pulumi infrastructure.

  1. What is FinFocus?
  2. Installation
  3. Quick Start
  4. Cost Types
  5. Common Workflows
  6. Configuration
  7. Budget Management
  8. Output Formats
  9. Filtering and Grouping
  10. Debugging and Logging
  11. Logging Configuration
  12. Troubleshooting

FinFocus is a command-line tool that calculates cloud infrastructure costs from your Pulumi infrastructure definitions.

Key Features:

  • 📊 Projected Costs - Estimate costs before deploying
  • 💰 Actual Costs - See what you’re actually paying
  • 🔌 Multiple Cost Sources - Works with Vantage, local specs, and more
  • 🎯 Flexible Filtering - Filter by resource type, tags, or custom criteria
  • 📈 Cost Aggregation - Group costs by provider, type, date, or tags
  • 📱 Multiple Formats - Table, JSON, or NDJSON output

  • Pulumi CLI installed and working
  • Go 1.25.8+ (if building from source)
  • Cloud credentials configured (AWS, Azure, GCP, etc.)

Coming soon - prebuilt binaries for Linux, macOS, and Windows.

Terminal window
git clone https://github.com/rshade/finfocus
cd finfocus
make build
./bin/finfocus --help
Terminal window
finfocus --version
finfocus --help

Terminal window
cd your-pulumi-project
pulumi preview --json > plan.json
Terminal window
finfocus cost projected --pulumi-json plan.json

Output:

RESOURCE TYPE MONTHLY CURRENCY
aws:ec2/instance:Instance aws:ec2:Instance $7.50 USD
aws:s3/bucket:Bucket aws:s3:Bucket $0.00 USD
aws:rds/instance:Instance aws:rds:Instance $0.00 USD
Total: $7.50 USD

Requires plugin configuration. See Configuration.

Terminal window
finfocus cost actual --pulumi-json plan.json --from 2024-01-01

What it is: Estimated costs based on your infrastructure definitions

When to use:

  • Before deploying infrastructure
  • During planning and design phases
  • Comparing different infrastructure options

Command:

Terminal window
finfocus cost projected --pulumi-json plan.json

What it is: Real costs from your cloud provider’s billing system

When to use:

  • After infrastructure is deployed and running
  • Cost optimization and analysis
  • Budget tracking and reporting

Command:

Terminal window
finfocus cost actual --pulumi-json plan.json --from 2024-01-01 --to 2024-01-31

Note: Requires plugin setup (Vantage, Kubecost, etc.)


When you run finfocus cost projected or finfocus cost actual inside a Pulumi project directory, FinFocus automatically detects the project and runs the appropriate Pulumi CLI command. No flags required.

Terminal window
# Just cd into your Pulumi project and run
cd my-pulumi-project/
finfocus cost projected
# For actual costs
finfocus cost actual

This replaces the manual two-step workflow:

Terminal window
# Old workflow (still supported)
pulumi preview --json > plan.json
finfocus cost projected --pulumi-json plan.json
  1. FinFocus looks for Pulumi.yaml or Pulumi.yml in the current directory and parent directories
  2. It verifies the pulumi CLI is available in your PATH
  3. It determines the active stack (or uses --stack if provided)
  4. For projected costs: runs pulumi preview --json
  5. For actual costs: runs pulumi stack export and auto-detects the date range from resource timestamps

Use --stack to target a specific stack without changing your active stack:

Terminal window
finfocus cost projected --stack production
finfocus cost actual --stack staging
  • Explicit file flags always take priority: --pulumi-json or --pulumi-state
  • When no file flag is provided, auto-detection is attempted
  • --stack only applies during auto-detection (ignored with file flags)
  • The pulumi CLI must be installed and available in PATH
  • You must be inside a Pulumi project directory (or a subdirectory)
  • Environment variables for your cloud provider and Pulumi backend must be configured

If auto-detection fails, you’ll see actionable error messages:

  • “pulumi CLI not found”: Install from https://www.pulumi.com/docs/install/
  • “no Pulumi project found”: Run from a directory containing Pulumi.yaml
  • “no active Pulumi stack”: Use --stack to specify one, or run pulumi stack select

FinFocus can integrate directly with the Pulumi CLI as an Analyzer, providing instant cost estimates during pulumi preview. This eliminates the need for a separate finfocus command to see projected costs.

For detailed setup instructions, refer to the Analyzer Setup Guide.


FinFocus supports aggregating costs across multiple cloud providers and services, allowing you to get a holistic view of your infrastructure spending. This feature is particularly powerful when combining actual cost data from various plugins.

View daily cost trends across all configured providers for a specific period:

Terminal window
finfocus cost actual --pulumi-json plan.json --from 2025-01-01 --to 2025-01-31 --group-by daily

Generate a monthly cost comparison. You can output this as JSON for further processing:

Terminal window
finfocus cost actual --pulumi-json plan.json --from 2025-01-01 --group-by monthly --output json

FinFocus now supports sustainability metrics, allowing you to estimate the carbon footprint of your infrastructure.

The table output includes a “CO₂” column showing the estimated carbon emissions for supported resources.

Example Output:

RESOURCE TYPE MONTHLY CURRENCY CO₂
aws:ec2/instance:Instance aws:ec2:Instance $7.50 USD 12.5 kg

You can adjust the assumed utilization rate for sustainability calculations using the --utilization flag. The default is 1.0 (100%).

Terminal window
finfocus cost projected --pulumi-json plan.json --utilization 0.8

Terminal window
# Generate plan
pulumi preview --json > plan.json
# Check projected costs
finfocus cost projected --pulumi-json plan.json
# Review output and make decisions

2. Compare Costs of Different Configurations

Section titled “2. Compare Costs of Different Configurations”
Terminal window
# Try one configuration
pulumi preview --json > config1.json
finfocus cost projected --pulumi-json config1.json
# Switch configuration
# ... modify Pulumi code ...
# Try another configuration
pulumi preview --json > config2.json
finfocus cost projected --pulumi-json config2.json
# Compare outputs
Terminal window
# View last 7 days
finfocus cost actual --from 2024-01-24
# View last month
finfocus cost actual --from 2024-01-01 --to 2024-01-31
# View by day
finfocus cost actual --from 2024-01-01 --to 2024-01-31 --group-by daily
Terminal window
# Sort by cost (output shows highest first)
finfocus cost projected --pulumi-json plan.json --output json | jq '.resources | sort_by(.estimatedCost) | reverse'
# Or filter to specific resource type
finfocus cost projected --pulumi-json plan.json --filter "type=aws:rds*"
Terminal window
# Assuming resources are tagged with 'env' tag
finfocus cost actual --filter "tag:env=prod" --from 2024-01-01
finfocus cost actual --filter "tag:env=dev" --from 2024-01-01

Vantage provides unified cost data from multiple cloud providers.

Setup:

  1. Get Vantage API key from Vantage
  2. Configure plugin (see Vantage Plugin Setup)
  3. Run commands with Vantage data

Commands:

Terminal window
finfocus cost actual --from 2024-01-01 --to 2024-01-31

Use local YAML files for cost estimates without external services.

Setup:

  1. Create YAML spec file: ~/.finfocus/specs/my-specs.yaml
  2. Add resource pricing definitions
  3. FinFocus automatically uses them

Example spec file:

---
resources:
aws:ec2/instance:Instance:
t3.micro:
monthly: 7.50
currency: USD
notes: Linux on-demand
t3.small:
monthly: 15.00
currency: USD

FinFocus allows you to set spending limits and receive alerts when your cloud costs approach or exceed configured thresholds. This helps you stay in control of your infrastructure spending.

Add a budget configuration to your ~/.finfocus/config.yaml:

cost:
budgets:
amount: 1000.00
currency: USD
period: monthly
alerts:
- threshold: 50
type: actual
- threshold: 80
type: actual
- threshold: 100
type: forecasted

Configuration Fields:

FieldDescriptionExample
amountTotal spend limit for the period1000.00
currencyISO 4217 currency codeUSD, EUR
periodBudget period (default: monthly)monthly
alertsList of threshold alertsSee below

Alert Configuration:

FieldDescriptionValues
thresholdPercentage of budget that triggers alert0 - 1000
typeWhat spend to check against thresholdactual, forecasted

Actual Alerts (type: actual)

Triggers when your current spending exceeds the threshold percentage of your budget.

alerts:
- threshold: 80
type: actual # Alert when actual spend reaches 80% of budget

Forecasted Alerts (type: forecasted)

Triggers when your projected end-of-period spend exceeds the threshold. Uses linear extrapolation based on your current daily spending rate.

alerts:
- threshold: 100
type: forecasted # Alert when forecasted spend will exceed budget

When a budget is configured, FinFocus automatically displays budget status after cost calculations:

Terminal Output (TTY):

╭──────────────────────────────────────────╮
│ BUDGET STATUS │
│ ──────────────────────────────────── │
│ │
│ Budget: $1,000.00/monthly │
│ Current Spend: $850.00 (85.0%) │
│ │
│ ██████████████████████████░░░░ 85% │
│ │
│ ⚠ WARNING - spend exceeds 80% threshold │
│ │
│ Forecasted: $1,240.00 (124.0%) │
╰──────────────────────────────────────────╯

CI/CD Output (Non-TTY):

BUDGET STATUS
=============
Budget: $1000.00/monthly
Current Spend: $850.00 (85.0%)
Status: WARNING - Exceeds 80% threshold
Forecasted: $1240.00 (124.0%)

The progress bar color indicates budget health:

ColorMeaning
GreenUnder 80% of budget
YellowBetween 80% and 100% of budget
RedOver 100% of budget
StatusIndicatorDescription
OK(none)Spend is below threshold
APPROACHINGWithin 5% of threshold (e.g., 75-80%)
EXCEEDEDAt or above threshold

Forecasted spend uses linear extrapolation:

Forecasted Spend = (Current Spend / Current Day) × Total Days in Month

Example:

  • Current day: 15th of a 31-day month
  • Current spend: $600
  • Daily rate: $600 / 15 = $40/day
  • Forecasted spend: $40 × 31 = $1,240

Basic Budget with Single Alert:

cost:
budgets:
amount: 500.00
currency: USD
alerts:
- threshold: 80
type: actual

Comprehensive Budget with Multiple Alerts:

cost:
budgets:
amount: 2000.00
currency: USD
period: monthly
alerts:
- threshold: 50
type: actual # Heads-up at 50%
- threshold: 80
type: actual # Warning at 80%
- threshold: 100
type: actual # Critical at 100%
- threshold: 100
type: forecasted # Proactive: warn if forecast exceeds budget

Proactive Forecasting Only:

cost:
budgets:
amount: 1000.00
currency: USD
alerts:
- threshold: 90
type: forecasted # Warn if forecast will hit 90%
- threshold: 100
type: forecasted # Critical if forecast will exceed budget

Set the amount to 0 to disable budget tracking:

cost:
budgets:
amount: 0 # Budget disabled

FinFocus supports multiple currencies for budget display:

CurrencySymbol
USD$
EUR
GBP£
JPY¥
CADC$
AUDA$
CHFCHF

Note: Budget currency must match your actual cost currency. A currency mismatch will result in an error.


Terminal window
finfocus cost projected --pulumi-json plan.json

Output:

RESOURCE TYPE MONTHLY CURRENCY
aws:ec2/instance:Instance aws:ec2:Instance $7.50 USD
aws:s3/bucket:Bucket aws:s3:Bucket $0.00 USD
Terminal window
finfocus cost projected --pulumi-json plan.json --output json

Output:

{
"summary": {
"totalMonthly": 7.5,
"currency": "USD"
},
"resources": [
{
"type": "aws:ec2:Instance",
"estimatedCost": 7.5,
"currency": "USD"
}
]
}

Useful for streaming and pipeline processing.

Terminal window
finfocus cost projected --pulumi-json plan.json --output ndjson

Output:

{"type": "aws:ec2:Instance", "estimatedCost": 7.50}
{"type": "aws:s3:Bucket", "estimatedCost": 0.00}

Terminal window
# EC2 instances only
finfocus cost projected --pulumi-json plan.json --filter "type=aws:ec2*"
# RDS databases
finfocus cost projected --pulumi-json plan.json --filter "type=aws:rds*"
Terminal window
# Production resources
finfocus cost actual --filter "tag:env=prod" --from 2024-01-01
# Team resources
finfocus cost actual --filter "tag:team=platform" --from 2024-01-01
# Multiple conditions
finfocus cost actual --filter "tag:env=prod AND tag:team=platform" --from 2024-01-01
Terminal window
# By provider (AWS, Azure, GCP)
finfocus cost actual --group-by provider --from 2024-01-01
# By resource type
finfocus cost actual --group-by type --from 2024-01-01
# By date (daily breakdown)
finfocus cost actual --group-by daily --from 2024-01-01 --to 2024-01-31
# By tag
finfocus cost actual --group-by "tag:env" --from 2024-01-01

FinFocus includes a --debug flag that enables verbose logging to help troubleshoot issues:

Terminal window
# Enable debug output for any command
finfocus cost projected --debug --pulumi-json plan.json
# Debug output shows:
# - Command start/stop with duration
# - Resource ingestion details
# - Plugin lookup attempts
# - Cost calculation decisions
# - Fallback behavior when plugins don't return data

Example Debug Output:

2025-01-15T10:30:45Z INF command started command=projected trace_id=01HQ7X2J3K4M5N6P7Q8R9S0T1U component=cli
2025-01-15T10:30:45Z DBG loading Pulumi plan plan_path=plan.json component=ingest
2025-01-15T10:30:45Z DBG extracted 3 resources from plan component=ingest
2025-01-15T10:30:45Z DBG querying plugin for projected cost resource_type=aws:ec2:Instance plugin=vantage component=engine
2025-01-15T10:30:46Z DBG plugin returned cost data monthly_cost=7.50 component=engine
2025-01-15T10:30:46Z INF projected cost calculation complete result_count=3 duration_ms=245 component=engine

Configure logging behavior via environment variables:

Terminal window
# Set log level (trace, debug, info, warn, error)
export FINFOCUS_LOG_LEVEL=debug
# Set log format (json, text, console)
export FINFOCUS_LOG_FORMAT=json
# Inject external trace ID for correlation with other systems
export FINFOCUS_TRACE_ID=my-pipeline-trace-12345
# Example: Debug with JSON format for log aggregation
FINFOCUS_LOG_LEVEL=debug FINFOCUS_LOG_FORMAT=json \
finfocus cost projected --pulumi-json plan.json 2> debug.log

Log settings are applied in this order (highest priority first):

  1. CLI flags (--debug)
  2. Environment variables (FINFOCUS_LOG_LEVEL)
  3. Config file (~/.finfocus/config.yaml)
  4. Defaults (info level, text format)

Every command generates a unique trace ID that appears in all log entries. This helps correlate log entries for a single operation:

Terminal window
# Use external trace ID for pipeline correlation
FINFOCUS_TRACE_ID=jenkins-build-123 finfocus cost projected --debug --pulumi-json plan.json
# All logs will include: trace_id=jenkins-build-123

FinFocus provides comprehensive logging capabilities for debugging, monitoring, and auditing.

Create or edit ~/.finfocus/config.yaml to configure logging:

logging:
# Log level: trace, debug, info, warn, error (default: info)
level: info
# Log format: json, text, console (default: console)
format: json
# Log to file (optional - defaults to stderr)
file: /var/log/finfocus/finfocus.log
# Audit logging for compliance (optional)
audit:
enabled: true
file: /var/log/finfocus/audit.log

Default Behavior:

  • Without configuration: logs go to stderr in console format
  • With --debug flag: forces debug level, console format, and stderr output

File Logging:

When file logging is configured, FinFocus displays the log location at startup:

Terminal window
$ finfocus cost projected --pulumi-json plan.json
Logging to: /var/log/finfocus/finfocus.log
COST SUMMARY
============
...

Fallback Behavior:

If the configured log file cannot be written (permissions, disk full), FinFocus:

  1. Falls back to stderr
  2. Displays a warning with the reason
Terminal window
$ finfocus cost projected --pulumi-json plan.json
Warning: Could not write to log file, falling back to stderr (permission denied)
COST SUMMARY
============
...

Audit logging tracks all cost queries for compliance and analysis.

Enable Audit Logging:

logging:
audit:
enabled: true
file: /var/log/finfocus/audit.log

Audit Log Entry Example:

{
"time": "2025-01-15T10:30:45Z",
"level": "info",
"audit": true,
"command": "cost projected",
"trace_id": "01HQ7X2J3K4M5N6P7Q8R9S0T1U",
"duration_ms": 245,
"success": true,
"result_count": 3,
"total_cost": 7.5,
"parameters": {
"pulumi_json": "plan.json",
"output": "table"
}
}

Audit Entry Fields:

FieldDescription
commandCLI command executed (e.g., “cost projected”, “cost actual”)
trace_idUnique request identifier for correlation
duration_msCommand execution time in milliseconds
successWhether the command completed successfully
result_countNumber of resources processed
total_costSum of all calculated costs
parametersCommand parameters (sensitive values redacted)

Security: Sensitive parameter values (API keys, passwords, tokens) are automatically redacted in audit logs.

FinFocus does not perform log rotation internally. Use external tools:

Linux (logrotate):

/etc/logrotate.d/finfocus
/var/log/finfocus/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
}

systemd journald:

If running as a service, logs go to journald automatically:

Terminal window
journalctl -u finfocus --since today

Problem: No pricing information found for resources

Solutions:

  • Check if plugin is configured correctly
  • Verify API credentials are valid
  • Some resources may not have pricing data - this is normal
  • Check troubleshooting guide: Troubleshooting

Problem: Date format not recognized

Solutions:

  • Use format: YYYY-MM-DD (e.g., 2024-01-01)
  • Or RFC3339: 2024-01-01T00:00:00Z
  • Example: --from 2024-01-01 --to 2024-01-31

Problem: Cost source plugin not installed

Solutions:

Terminal window
# List installed plugins
finfocus plugin list
# Validate installations
finfocus plugin validate
# See plugin setup guide for your cost source
# - Vantage: docs/plugins/vantage/setup.md


Last Updated: 2025-10-29