Run FinOps policy evaluations in CI/CD
Cloud mode (live AWS scan) or Terraform mode (pre-deploy plan scan).
Quick Start · Inputs · How It Works · Ecosystem
Catch cost violations before they reach production. Two modes:
- Cloud mode: Scan live AWS resources for idle resources, tagging violations, and savings
- Terraform mode: Scan
tfplan.jsonpre-deploy to catch policy violations beforeterraform apply
- uses: breakingthecloud/sofe-action@v2with:
api-key: ${{ secrets.SOFE_API_KEY }}fail-on: high- uses: breakingthecloud/sofe-action@v2with:
api-key: ${{ secrets.SOFE_API_KEY }}mode: cloudfail-on: high- run: terraform plan -out=tfplan && terraform show -json tfplan > tfplan.json
- uses: breakingthecloud/sofe-action@v2with:
api-key: ${{ secrets.SOFE_API_KEY }}mode: terraformplan-file: tfplan.jsonfail-on: highname: FinOps Pre-Deploy Gateon: pull_requestjobs:
terraform-scan:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Planrun: | cd infra/ terraform init && terraform plan -out=tfplan terraform show -json tfplan > tfplan.json - name: SOFE Pre-Deploy Scanuses: breakingthecloud/sofe-action@v2id: sofewith:
api-key: ${{ secrets.SOFE_API_KEY }}mode: terraformplan-file: infra/tfplan.jsonfail-on: high
- name: Comment findings on PRif: always() && github.event_name == 'pull_request'uses: actions/github-script@v7with:
script: | const findings = '${{ steps.sofe.outputs.findings-count }}'; const resources = '${{ steps.sofe.outputs.resources-scanned }}'; const failed = '${{ steps.sofe.outputs.failed }}'; const icon = failed === 'true' ? '❌' : '✅'; github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: `## ${icon} SOFE Terraform Scan\n| Metric | Value |\n|--------|-------|\n| Resources scanned | ${resources} |\n| Findings | ${findings} |\n| Status | ${failed === 'true' ? 'FAILED (high+ severity)' : 'PASSED'} |` })name: FinOps Gateon: [push, pull_request]jobs:
sofe-evaluate:
runs-on: ubuntu-lateststeps:
- uses: breakingthecloud/sofe-action@v2id: sofewith:
api-key: ${{ secrets.SOFE_API_KEY }}mode: cloudfail-on: high
- name: Comment findings on PRif: github.event_name == 'pull_request'uses: actions/github-script@v7with:
script: | github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: `## SOFE FinOps Report\n- Findings: ${{ steps.sofe.outputs.findings-count }}\n- Resources scanned: ${{ steps.sofe.outputs.resources-scanned }}` })| Input | Description | Required | Default | Modes |
|---|---|---|---|---|
api-key | SOFE API key (sk_sofe_xxx) | ✅ | — | both |
mode | cloud or terraform | ❌ | cloud | — |
plan-file | Path to tfplan.json | ✅ (tf) | — | terraform |
fail-on | Fail if findings ≥ severity | ❌ | (none) | both |
resource-types | Filter resource types | ❌ | all | cloud |
format | Output: table, json, markdown | ❌ | table | both |
version | CLI version to install | ❌ | latest | cloud |
| Output | Description |
|---|---|
findings-count | Number of findings detected |
resources-scanned | Number of resources scanned |
failed | true if fail-on threshold was exceeded |
- Installs the SOFE CLI binary
- Runs
sofe evaluate --cloudwith your API key - SOFE evaluates your connected AWS account
- Returns findings + optional pipeline failure
- Reads your
tfplan.jsonfile (no CLI install needed) - POSTs it to
api.sofe.dev/terraform/scan - Evaluates 6 pre-deploy policies (tags, sizing, encryption, etc.)
- Returns findings + optional pipeline failure
Key advantage: Same policies work pre AND post deploy. Write once, enforce everywhere.
| Policy | What it catches |
|---|---|
require-cost-tags | Resource without owner/env/costcenter tag |
no-oversized-staging | Large instance in non-prod environment |
s3-encryption-required | Bucket without SSE configured |
no-public-s3 | Bucket with public access |
rds-multi-az-prod | Production RDS without Multi-AZ |
naming-convention | Resource not following naming standard |
-- uses: breakingthecloud/sofe-action@v1+- uses: breakingthecloud/sofe-action@v2
with:
api-key: ${{ secrets.SOFE_API_KEY }}
+ mode: cloud
fail-on: high- SOFE account at platform.sofe.dev
- API key (add as
SOFE_API_KEYsecret in your repo) - Cloud mode: AWS account connected in the SOFE platform
- Terraform mode:
terraform show -jsonoutput as.jsonfile
| Project | Description |
|---|---|
| sofe | Python engine (collectors + policies) |
| sofe-server | REST API server |
| sofe-cli | Go CLI (19 commands, TUI) |
| platform.sofe.dev | SaaS dashboard (free tier) |
| sofe.dev/docs | Documentation |
Apache 2.0 — see LICENSE.
sofe.dev · Engine · finoptix.dev
Catch cost violations before they reach production.