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@v2
with:
api-key: ${{ secrets.SOFE_API_KEY }}
fail-on: high- uses: breakingthecloud/sofe-action@v2
with:
api-key: ${{ secrets.SOFE_API_KEY }}
mode: cloud
fail-on: high- run: terraform plan -out=tfplan && terraform show -json tfplan > tfplan.json
- uses: breakingthecloud/sofe-action@v2
with:
api-key: ${{ secrets.SOFE_API_KEY }}
mode: terraform
plan-file: tfplan.json
fail-on: highname: FinOps Pre-Deploy Gate
on: pull_request
jobs:
terraform-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Plan
run: |
cd infra/
terraform init && terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
- name: SOFE Pre-Deploy Scan
uses: breakingthecloud/sofe-action@v2
id: sofe
with:
api-key: ${{ secrets.SOFE_API_KEY }}
mode: terraform
plan-file: infra/tfplan.json
fail-on: high
- name: Comment findings on PR
if: always() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
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 Gate
on: [push, pull_request]
jobs:
sofe-evaluate:
runs-on: ubuntu-latest
steps:
- uses: breakingthecloud/sofe-action@v2
id: sofe
with:
api-key: ${{ secrets.SOFE_API_KEY }}
mode: cloud
fail-on: high
- name: Comment findings on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
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.