Enterprise FinOps - Cost Allocation
Accurately allocating the costs of shared infrastructure to the business teams that consume it.
Enterprise FinOps: Cost Allocation for Shared Resources with Rescile
This example demonstrates how to use rescile to solve classic and challenging enterprise FinOps (Financial Operations) problems. A major challenge in FinOps is identifying and eliminating waste, such as services or instances that are running but no longer needed. rescile helps address this by creating a dependency graph; by modeling the connections between assets, it becomes clear which services are truly required and which are “orphaned” with no dependents. This example focuses on another key challenge: accurately allocating the costs of shared infrastructure to the business teams that consume it.
1. The Scenario
Imagine a typical enterprise with a modern, cloud-native technology stack. The organization is structured into several teams, each belonging to a business unit:
- Finance & Operations: Manages billing and reporting applications.
- Marketing & Sales: Runs data analytics dashboards.
- Platform Engineering: Manages shared, centralized infrastructure like Kubernetes clusters and authentication services.
These teams own and operate a portfolio of applications that run on a mix of dedicated and shared infrastructure, including servers, databases, and container platforms.
2. The Challenge: The $3,000 Question of Shared Costs
The CFO asks a simple question: “How much does each team really cost us to operate?”
At first glance, this seems easy. We can sum up the costs of the servers and databases each team uses. However, we immediately hit a wall with shared resources:
- A Kubernetes Cluster (
prod-k8s-cluster) costs $1000/month and runs applications for three different teams. - A Reporting Database (
reporting-db) costs $300/month and serves both the Marketing team’s analytics dashboard and the Finance team’s reporting API.
How do we fairly divide these costs? Simply assigning the full cost to one team is inaccurate and unfair. Ignoring them leaves a significant amount of infrastructure spending unattributed. This is the core challenge of enterprise FinOps: attributing shared costs to provide accurate showback (or chargeback) to business units.
The data is scattered across the organization in different systems, represented here by simple CSV files.
3. The Rescile Solution: From Silos to a Digital Twin
rescile solves this problem by transforming siloed, flat data into a rich, interconnected graph of the entire technology estate—a Digital Twin. This allows for powerful, graph-based queries and calculations that make complex cost allocation straightforward.
The solution uses two key steps:
Step 1: Ingest and Model the Data
rescile ingests all the raw CSV files from the assets/ directory. It automatically identifies relationships based on column headers (e.g., the application column in team.csv creates a link from a team to an application). This process stitches the disparate data sources together into a single, cohesive graph.
(Team: finops)is linked to(Application: billing-api)(Application: billing-api)is linked to(Server: app-server-1)(Application: billing-api)is also linked to(Kubernetes Platform: prod-k8s-cluster)
Step 2: Query the Graph to Generate the Cost Summary
This is where the magic happens. The output/cost_summary.toml file defines a final report to be generated. Instead of writing complex code, we use a powerful Tera template to query the graph and perform the cost allocation logic declaratively.
The template starts from each team and traverses the graph to find all associated applications and their underlying infrastructure. For shared resources, it performs a crucial operation: it traverses the connections from the shared resource back to all consuming applications to determine how many consumers there are. This allows for a precise, fair division of costs.
4. Dissecting the Data Model (assets/*.csv)
Our data is spread across several CSV files, each representing a different data source:
-
team.csv: The business view. It maps teams to business units and the applications they are responsible for.name,business_unit,application finops,"Finance & Operations","billing-api,reporting-api" ... -
application.csv: The logical service layer, linking applications to the servers they run on.name,server billing-api,"app-server-1,app-server-2" ... -
server.csv,database.csv,kubernetes_platform.csv,cdn_service.csv: These files represent the raw infrastructure assets and their direct costs, as you would get from a cloud provider’s billing report. Note that some assets list multiple consuming applications, defining them as shared resources.// kubernetes_platform.csv name,cost,application prod-k8s-cluster,1000,"billing-api,auth-service,reporting-api"
5. The Magic: The cost_summary.toml Output Model
This file is the heart of the solution. It instructs rescile to iterate through each team and generate a detailed cost summary.
# Step 3: Generate a final summary output for each team.
# This file queries the fully constructed graph to create a new 'cost_summary'
# resource, demonstrating the final attributed cost structure.
origin_resource = "team"
[[output]]
resource_type = "cost_summary"
name = "summary_for_{{ origin_resource.name }}"
# The template renders a JSON object that becomes the properties of the new resource.
# It accesses the 'team' node (as 'origin_resource') and uses path traversal to
# access cost data from all related components through the 'application' nodes.
# This demonstrates how to perform cost allocation for shared resources directly in
# the output generation, eliminating the need for intermediate cost rollup models.
template = """
{# ... Full Tera template logic ... #}
{# This is the key logic for shared costs. #}
{# It finds the number of consumers by traversing from the resource #}
{# back to its applications and getting the array length. #}
{%- set num_consumers = db.application | default(value=[]) | length -%}
{# The allocated cost is the total cost divided by the number of consumers. #}
{%- set_global grand_total = grand_total + (db.cost / divisor) -%}
{# ... #}
"""
Key Logic Explained
The power of rescile is evident in this line:
{%- set num_consumers = db.application | default(value=[]) | length -%}
dbis a database resource (e.g.,reporting-db).db.applicationtraverses the graph from the database back to all connected applications. This reverse lookup is possible because the graph contains the complete relationship model.| lengthis a Tera filter that gets the size of the resulting array of applications. Forreporting-db, this will be2(it’s used byanalytics-dashboardandreporting-api).- The allocated cost for the current application is then calculated as
db.cost / num_consumers.
This simple, declarative syntax replaces what would otherwise be complex joins, queries, or custom code.
The Final Calculated Results
When rescile processes this template, it generates a cost summary for each team, accurately attributing both direct and shared costs.
| Team | Business Unit | Total Attributed Cost | Breakdown |
|---|---|---|---|
| finops | Finance & Operations | $1696.67 | Owns billing-api ($1123.33) and reporting-api ($573.33). Includes their portion of the shared Kubernetes cluster and reporting database. |
| marketing | Marketing & Sales | $1050.00 | Owns analytics-dashboard ($1050.00). Includes dedicated servers, a CDN, a dedicated database, and a portion of the shared reporting database. |
| platform | Platform Engineering | $563.33 | Owns auth-service ($563.33). Includes dedicated infrastructure and a portion of the shared Kubernetes cluster it runs on. |
The CFO’s question is answered accurately and automatically.
6. How to Run This Example
You can run this example using rescile-ce.
- Explore the Graph via GraphQL
You can also serve the graph via a local GraphQL API to explore the data interactively.
# Serve the graph on http://127.0.0.1:7600
rescile-ce serve
Open your browser to http://127.0.0.1:7600 to access the GraphiQL explorer. You can then run the following query to inspect the generated cost summaries:
query GetCostSummaries {
cost_summary {
name
total_cost
business_unit
team_name
applications
}
}
7. Conclusion
This FinOps example illustrates the core power of rescile: it transforms disconnected, siloed enterprise data into an interconnected, queryable digital twin. By leveraging a graph model and declarative templating, rescile enables you to solve complex, real-world business problems like cost allocation elegantly and without writing a single line of application code. This “configuration-as-code” approach ensures your business logic is versionable, auditable, and easy to maintain.