Best Practice: Implementing FinOps Processes
Context
FinOps does not fail because of missing tooling. It fails because of missing processes, unclear responsibilities, and a lack of connection between cost data and actions. This best practice shows how structured FinOps processes are established from scratch – from the first monthly review to the architecture board quarterly cycle.
Related Controls
-
WAF-COST-060 – FinOps Review Cadence
Target State
-
Monthly engineering reviews run routinely with clear action items
-
Quarterly architecture board reviews connect cost debt governance with strategic decisions
-
Teams receive actionable cost data – not raw billing reports
-
Cost responsibility is clear: engineering teams, supported by the FinOps team
Setting Up the Monthly Engineering Review
Review Format (30–45 minutes)
Participants: Tech Lead / Engineering Manager of the team + FinOps support
Agenda:
1. Current cost status (5 min)
- Total costs for the month vs. budget
- Deviation from previous month (absolute and %)
- Forecast for end of month
2. Top 3 cost drivers (10 min)
- Which services / resources are driving costs?
- Anomalies and unexpected changes
- Budget alert events for the month
3. Rightsizing recommendations (10 min)
- Compute Optimizer / Azure Advisor / GCP Recommender: new recommendations
- Idle resource list: instances < 5% CPU over 7 days
- Decision per recommendation: implement / reject (with rationale)
4. Action items (10 min)
- New action items from review
- Status of open action items from previous month
- Owner and due date for each new item
5. Cost debt notes (5 min)
- New potential cost debt entries identified?
- Flag for quarterly review
Action Item Template
# action-items/2025-03.yml
month: "2025-03"
team: "platform-team"
action_items:
- id: AI-2025-03-001
title: "Shut down 3 idle dev instances (EC2 t3.large)"
owner: "platform-team"
due: "2025-03-31"
expected_saving_eur_month: 180
status: "open" # open | in-progress | done | cancelled
- id: AI-2025-03-002
title: "Set CloudWatch Log Group 'app-debug' retention from unlimited to 30d"
owner: "platform-team"
due: "2025-03-15"
expected_saving_eur_month: 45
status: "done"
completed: "2025-03-10"
actual_saving_eur_month: 42
Establishing the Quarterly Architecture Board Review
Preparation by the FinOps Team
2 weeks before the review, the FinOps team prepares:
-
Quarterly cost report (total costs, trend, top 10 cost drivers)
-
Cost debt register update with proposals for new entries
-
ADR list for the quarter with lock-in scores
-
Reservation portfolio analysis (RI/SP utilization, expiring RIs)
-
Recommendation list for strategic measures
Review Agenda (75 minutes)
1. Quarterly report (15 min)
- Total costs Q vs. budget
- Cost trend YoY and QoQ
- Biggest cost changes for the quarter
2. Cost debt register (25 min)
- New entries: confirmation, owner, status
- Existing entries: paydown progress, status updates
- Acceptance decisions with rationale
3. ADR reviews (15 min)
- ADRs with lock-in score >= 4: confirmation or rejection
- Cost impact of last quarter's decisions
4. Strategic measures (15 min)
- Reservation strategy for the next quarter
- Multi-cloud/multi-provider cost decisions
- Open-source vs. proprietary decisions with impact
5. Sign-off and next steps (5 min)
- Prioritized paydown measures
- Confirm next review date
Tooling Recommendations
| Area | AWS | Azure / GCP |
|---|---|---|
Cost Reporting |
AWS Cost Explorer, Cost & Usage Report (CUR) |
Azure Cost Management + Billing, GCP Billing |
Budget Management |
AWS Budgets (IaC: |
Azure Budgets ( |
Rightsizing |
AWS Compute Optimizer, Trusted Advisor |
Azure Advisor, GCP Recommender |
Anomaly Detection |
AWS Cost Anomaly Detection |
Azure Cost Alerts, GCP Budget Alerts |
FinOps Platforms (Multi-Cloud) |
CloudHealth, Apptio Cloudability, FOCUS-based tools |
CloudHealth, Apptio, Spot.io |
Dashboard Integration |
Cost Explorer Embedded, Grafana (CUR data in S3) |
Power BI + Azure Cost Management, Looker + GCP Billing |
GitHub Actions Integration
# .github/workflows/monthly-cost-report.yml
name: Monthly FinOps Report
on:
schedule:
- cron: '0 8 1 * *' # 1st of each month, 8:00
jobs:
generate-report:
runs-on: ubuntu-latest
steps:
- name: Generate Cost Report
run: |
# Costs for last month from AWS Cost Explorer
aws ce get-cost-and-usage \
--time-period Start=$(date -d "1 month ago" +%Y-%m-01),End=$(date +%Y-%m-01) \
--granularity MONTHLY \
--metrics "BlendedCost" \
--group-by Type=TAG,Key=workload \
> /tmp/cost-report.json
- name: Check Untagged Resources
run: |
UNTAGGED=$(aws ce get-cost-and-usage \
--time-period Start=$(date -d "1 month ago" +%Y-%m-01),End=$(date +%Y-%m-01) \
--granularity MONTHLY \
--metrics "BlendedCost" \
--filter '{"Tags":{"Key":"workload","Values":[""]}}' \
--query "ResultsByTime[0].Total.BlendedCost.Amount" \
--output text)
echo "Untagged costs: $UNTAGGED EUR"
- name: Create FinOps Review Issue
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `FinOps Monthly Review - ${new Date().toISOString().slice(0, 7)}`,
body: `Monthly FinOps review required. See cost report in workflow artifacts.`,
labels: ['finops-review', 'monthly']
});
KPIs and Tracking
# metrics/finops-kpis.yml – Monthly KPI tracking
month: "2025-03"
team: "platform-team"
kpis:
tagging_compliance_pct: 96.2 # Target >= 95%
budget_variance_pct: 4.1 # Target < ±10%
untagged_cost_pct: 3.8 # Target < 5%
rightsizing_coverage_pct: 82 # Target >= 80%
idle_resource_rate_pct: 1.9 # Target < 3%
observability_cost_pct_of_total: 17 # Target < 20%
ri_utilization_pct: 84 # Target >= 80%
quarterly_kpis:
cost_debt_register_entries: 5
cost_debt_paydown_pct: 60 # Target >= 50%
tco_tracked_workloads_pct: 75 # Target >= 80%
Anti-Patterns
-
FinOps as police: reviews where teams have to defend themselves create resistance
-
Costs without context: rising costs can be justified by growing usage
-
Action items without owners: unassigned items are never completed
-
Tooling before process: expensive FinOps platforms are useless without a review cycle