Configuration Reference
Complete guide to configuring CostCutter.
Configuration Hierarchy
CostCutter merges configuration from multiple sources in this order (later sources override earlier ones):
- Default Config - Built-in defaults (
src/costcutter/conf/config.yaml) - Home Config - User's home directory (
~/.costcutter.{yaml,yml,toml,json}) - Explicit File - File specified via
--configflag orconfig_fileparameter - Environment Variables - Shell environment variables with
COSTCUTTER_prefix - CLI Arguments - Command-line flags (highest priority)
Partial overrides are supported: You only need to specify the values you want to change. Unspecified values are inherited from lower priority sources.
Configuration Methods
Method 1: Default Configuration (Built-in)
Located at src/costcutter/conf/config.yaml. Used automatically if no other config is provided.
Default Configuration:
dry_run: true
logging:
enabled: true
level: INFO
dir: ~/.local/share/costcutter/logs
reporting:
csv:
enabled: true
path: ~/.local/share/costcutter/reports/events.csv
aws:
profile: default
aws_access_key_id: ""
aws_secret_access_key: ""
aws_session_token: ""
credential_file_path: ~/.aws/credentials
max_workers: 4
region:
- us-east-1
- ap-south-1
services:
- ec2
- s3This is the baseline. All other configuration methods override these defaults.
Method 2: Home Directory Config
Create a config file in your home directory:
Supported formats:
~/.costcutter.yaml~/.costcutter.yml~/.costcutter.toml~/.costcutter.json
Example (~/.costcutter.yaml):
# Override only what you need
aws:
region:
- us-west-2
- eu-west-1
services:
- ec2
- s3Result: Regions and services are overridden. Other settings (dry_run, logging, etc.) use defaults.
TOML Example (~/.costcutter.toml):
dry_run = false
[aws]
region = ["us-east-1", "us-west-2"]
services = ["ec2", "s3"]JSON Example (~/.costcutter.json):
{
"dry_run": false,
"aws": {
"region": ["us-east-1"],
"services": ["ec2"]
}
}Method 3: Explicit Config File
Specify a config file when running CostCutter:
CLI:
costcutter --config /path/to/myconfig.yamlPython API:
from pathlib import Path
from costcutter.conf.config import get_config
config = get_config(config_file=Path("/path/to/myconfig.yaml"))Supported formats: .yaml, .yml, .toml, .json
Example (myconfig.yaml):
dry_run: false
aws:
profile: production
region:
- us-east-1
services:
- ec2Priority: Overrides both defaults and home directory config.
Method 4: Environment Variables
Set environment variables with COSTCUTTER_ prefix.
Syntax:
- Use double underscore (
__) for nesting - Variable names are case-insensitive
- Values are automatically parsed (YAML parser used for type coercion)
Examples:
# Override dry_run
export COSTCUTTER_DRY_RUN=false
# Override AWS region (YAML list syntax)
export COSTCUTTER_AWS__REGION="[us-west-2, eu-central-1]"
# Override logging level
export COSTCUTTER_LOGGING__LEVEL=DEBUG
# Override single nested value
export COSTCUTTER_AWS__PROFILE=staging
# Run costcutter
costcutterType Coercion Examples:
export COSTCUTTER_DRY_RUN=true # Boolean
export COSTCUTTER_AWS__MAX_WORKERS=8 # Integer
export COSTCUTTER_LOGGING__LEVEL=DEBUG # String
export COSTCUTTER_AWS__SERVICES="[ec2, s3]" # ListPython API:
import os
from costcutter.conf.config import get_config
os.environ["COSTCUTTER_DRY_RUN"] = "false"
os.environ["COSTCUTTER_AWS__REGION"] = "[us-east-1]"
config = get_config()Priority: Overrides defaults, home config, and explicit files. Only CLI arguments have higher priority.
Method 5: CLI Arguments
Pass arguments directly via command line:
# Override dry_run
costcutter --dry-run
# Combine with config file
costcutter --config myconfig.yaml --dry-runAvailable CLI Arguments:
--dry-run/--no-dry-run- Enable or disable dry-run mode--config PATH- Specify config file
Python API:
from costcutter.conf.config import get_config
cli_overrides = {
"dry_run": False,
"aws": {
"region": ["us-east-1"]
}
}
config = get_config(cli_args=cli_overrides)Priority: Highest priority. Overrides all other sources.
Using CostCutter as a Python Package
Import and configure programmatically:
Basic Usage
from costcutter.conf.config import get_config
from costcutter.orchestrator import orchestrate_services
# Load default config
config = get_config()
# Run cleanup
orchestrate_services(dry_run=True)Custom Configuration
from pathlib import Path
from costcutter.conf.config import get_config
# Method 1: Use config file
config = get_config(config_file=Path("./myconfig.yaml"))
# Method 2: Override via CLI args
config = get_config(cli_args={
"dry_run": False,
"aws": {
"region": ["us-west-2"],
"services": ["ec2", "s3"]
}
})
# Method 3: Combine both
config = get_config(
config_file=Path("./base.yaml"),
cli_args={"dry_run": False}
)Reload Configuration
from costcutter.conf.config import reload_config
# Reload with new settings
config = reload_config(cli_args={"dry_run": False})Access Configuration Values
config = get_config()
# Dot notation
print(config.dry_run)
print(config.aws.region)
print(config.logging.level)
# Dictionary notation
print(config["dry_run"])
print(config["aws"]["region"])
# Convert to dict
config_dict = config.to_dict()
print(config_dict["aws"]["services"])Configuration Options Reference
Top-Level
dry_run
- Type:
boolean - Default:
true - Description: When
true, simulates actions without making changes. Whenfalse, actually deletes resources. - CLI:
--dry-run/--no-dry-run
Examples:
dry_run: true # Safe mode (default)export COSTCUTTER_DRY_RUN=falseLogging Section
logging.enabled
- Type:
boolean - Default:
true - Description: Enable or disable file-based logging.
logging.level
- Type:
string - Default:
INFO - Options:
DEBUG,INFO,WARNING,ERROR,CRITICAL - Description: Log verbosity level.
logging.dir
- Type:
string(path) - Default:
~/.local/share/costcutter/logs - Description: Directory where log files are written. Supports
~expansion.
Examples:
logging:
enabled: true
level: DEBUG
dir: /var/log/costcutterexport COSTCUTTER_LOGGING__ENABLED=true
export COSTCUTTER_LOGGING__LEVEL=DEBUG
export COSTCUTTER_LOGGING__DIR=/tmp/logsReporting Section
reporting.csv.enabled
- Type:
boolean - Default:
true - Description: Enable CSV export of all events.
reporting.csv.path
- Type:
string(path) - Default:
~/.local/share/costcutter/reports/events.csv - Description: Path where CSV report is saved. Supports
~expansion.
Examples:
reporting:
csv:
enabled: true
path: ./reports/cleanup-2025-11-05.csvexport COSTCUTTER_REPORTING__CSV__ENABLED=true
export COSTCUTTER_REPORTING__CSV__PATH=./events.csvAWS Section
aws.profile
- Type:
string - Default:
default - Description: AWS CLI profile name from
~/.aws/credentials.
aws.aws_access_key_id
- Type:
string - Default:
""(empty) - Description: AWS access key ID. Leave empty to use credentials file or IAM role.
aws.aws_secret_access_key
- Type:
string - Default:
""(empty) - Description: AWS secret access key. Leave empty to use credentials file or IAM role.
aws.aws_session_token
- Type:
string - Default:
""(empty) - Description: AWS session token (optional, for temporary credentials).
aws.credential_file_path
- Type:
string(path) - Default:
~/.aws/credentials - Description: Path to AWS credentials file.
aws.max_workers
- Type:
integer - Default:
4 - Description: Number of parallel workers for orchestrator-level concurrency (regions + services).
aws.region
- Type:
list[string] - Default:
[us-east-1, ap-south-1] - Description: AWS regions to process. Specify multiple regions for parallel cleanup.
aws.services
- Type:
list[string] - Default:
[ec2, s3] - Description: AWS services to process. The repository ships with
ec2ands3handlers; include additional service names as you add new cleanup functions.
Examples:
aws:
profile: production
region:
- us-east-1
- us-west-2
- eu-west-1
services:
- ec2
- s3
max_workers: 8export COSTCUTTER_AWS__PROFILE=staging
export COSTCUTTER_AWS__REGION="[us-west-2, eu-central-1]"
export COSTCUTTER_AWS__SERVICES="[ec2, s3]"
export COSTCUTTER_AWS__MAX_WORKERS=6Complete Configuration Examples
Example 1: Development (Dry-Run)
# ~/.costcutter.yaml
dry_run: true
logging:
level: DEBUG
dir: ./logs
aws:
profile: dev
region:
- us-east-1
services:
- ec2Usage:
costcutter # Uses home configExample 2: Production (Execute)
# production.yaml
dry_run: false
logging:
level: INFO
dir: /var/log/costcutter
reporting:
csv:
path: /var/reports/cleanup-$(date +%Y%m%d).csv
aws:
profile: production
region:
- us-east-1
- us-west-2
- eu-west-1
services:
- ec2
- s3
max_workers: 10Usage:
costcutter --config production.yamlExample 3: Environment Variables Only
#!/bin/bash
# cleanup.sh
export COSTCUTTER_DRY_RUN=false
export COSTCUTTER_AWS__PROFILE=prod
export COSTCUTTER_AWS__REGION="[us-east-1, us-west-2]"
export COSTCUTTER_AWS__SERVICES="[ec2, s3]"
export COSTCUTTER_LOGGING__LEVEL=INFO
costcutterExample 4: Python Script
# cleanup.py
from pathlib import Path
from costcutter.conf.config import get_config
from costcutter.orchestrator import orchestrate_services
from costcutter.logger import setup_logging
# Load configuration
config = get_config(
config_file=Path("./config.yaml"),
cli_args={
"dry_run": False,
"aws": {
"region": ["us-east-1"],
"services": ["ec2"]
}
}
)
# Setup logging
setup_logging(config)
# Run cleanup
orchestrate_services(dry_run=False)Example 5: Minimal Override
You only need to specify what you want to change:
# minimal.yaml
aws:
region:
- eu-central-1Result: Only region is overridden. All other settings use defaults:
dry_run: true(default)logging.level: INFO(default)aws.services: [ec2, s3](default)- etc.
Precedence Example
Given these configurations:
1. Default (config.yaml):
dry_run: true
aws:
region: [us-east-1]
services: [ec2, s3]2. Home (~/.costcutter.yaml):
aws:
region: [us-west-2]3. Explicit (myconfig.yaml):
aws:
services: [ec2]4. Environment:
export COSTCUTTER_DRY_RUN=false5. CLI:
costcutter --config myconfig.yaml --dry-runFinal merged configuration:
dry_run: true # From CLI (highest priority)
aws:
region: [us-west-2] # From home config
services: [ec2] # From explicit file
# Other aws.* values from defaultsValidation
CostCutter validates configuration at startup:
- Config file format - Must be
.yaml,.yml,.toml, or.json - Required fields - All required fields must have values
- Type checking - Values must match expected types
Invalid config example:
costcutter --config myconfig.txt
# Error: Config file must be one of: .yaml, .yml, .toml, .jsonTroubleshooting
Configuration not taking effect
Check precedence order:
- Verify which config sources are active
- Higher priority sources override lower ones
- Use
DEBUGlogging to see loaded values
Debug configuration:
from costcutter.conf.config import get_config
config = get_config()
print(config.to_dict()) # See final merged configEnvironment variables not working
Ensure correct syntax:
- Prefix:
COSTCUTTER_ - Nesting: Use
__(double underscore) - Case: Insensitive (but uppercase recommended)
Test:
export COSTCUTTER_DRY_RUN=false
python -c "import os; from costcutter.conf.config import get_config; print(get_config().dry_run)"
# Should print: FalseHome config ignored
Check file exists and has correct extension:
ls -la ~/.costcutter.*Supported: .yaml, .yml, .toml, .json
Next Steps
- How It Works - Understand execution flow
- Getting Started - Quick start guide
- Troubleshooting - Common issues