CI/CD Integration
Block deploys that violate FinOps policies. Run SOFE in your CI pipeline.
GitHub Actions
# .github/workflows/finops-check.yml
name: FinOps Policy Check
on: [push, pull_request]
jobs:
sofe-evaluate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install SOFE
run: pip install sofe
- name: Run evaluation
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: us-east-1
run: |
sofe evaluate \
--policies ./policies/ \
--fail-on high \
--format json > findings.json
- name: Upload findings
if: always()
uses: actions/upload-artifact@v4
with:
name: sofe-findings
path: findings.json--fail-on Flag
Exit with code 1 if findings meet or exceed the specified severity:
# Fail on critical only (most lenient) sofe evaluate --policies ./policies/ --fail-on critical # Fail on high or above (recommended for production) sofe evaluate --policies ./policies/ --fail-on high # Fail on any finding (strictest) sofe evaluate --policies ./policies/ --fail-on low
Using the API (no AWS creds in CI)
# If you've connected your AWS account via platform.sofe.dev,
# you can call the API without local AWS credentials:
- name: SOFE Evaluate (via API)
run: |
RESULT=$(curl -s -X POST https://api.sofe.dev/evaluate \
-H "X-API-Key: ${{ secrets.SOFE_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"policies": ["*"]}')
HIGH=$(echo $RESULT | jq '.summary.high')
if [ "$HIGH" -gt 0 ]; then
echo "❌ Found $HIGH high-severity findings"
exit 1
fiGitHub Action — sofe-action@v2
The official SOFE GitHub Action supports two modes: cloud (scan live AWS resources) and terraform (scan plan files pre-deploy).
Cloud Mode (scan live resources)
- uses: breakingthecloud/sofe-action@v2
with:
api-key: ${{ secrets.SOFE_API_KEY }}
mode: cloud
fail-on: highTerraform Mode (pre-deploy scan)
- 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: highFull Workflow (Terraform + PR Comment)
name: 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 on PR
if: always()
uses: actions/github-script@v7
with:
script: |
const f = '${{ steps.sofe.outputs.findings-count }}';
const r = '${{ steps.sofe.outputs.resources-scanned }}';
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `## SOFE Scan\n| Metric | Value |\n|--|--|\n| Findings | ${f} |\n| Resources | ${r} |`
})Terraform mode advantage: No CLI install needed — the action sends your tfplan.json directly to the API. Same 6 pre-deploy policies check tags, sizing, encryption before terraform apply.
Best Practices
- ✓ Run on PRs (catch issues before merge)
- ✓ Use
--fail-on highfor production branches - ✓ Store findings as artifacts (audit trail)
- ✓ Use API key method if AWS creds rotation is complex
- ✓ Start lenient (--fail-on critical), tighten over time