Easily build complex reports
Monitoring and efficiency metrics
Custom cost allocation tags
Network cost visibility
Organizational cost hierarchies
Budgeting and budget alerts
Discover active resources
Consumption-based insights
Alerts for unexpected charges
Automated AWS cost savings
Discover cost savings
Unified view of AWS discounts
COGS and business metrics
Model savings plans
Collaborate on cost initiatives
Create and manage your teams
Automate cloud infrastructure
Cloud cost issue tracking
Detect cost spikes
by Danielle Vansia
Contents
As cloud budgets continue to grow as the #2 line item behind salaries for many companies, cloud practitioners are becoming more attuned to the FinOps imperative — the need to optimize cloud costs, budgets, and cost allocation. In addition, most major organizations employ multiple cloud service providers, oftentimes having to manually manage and configure numerous cost reports and dashboards.
Enter FinOps as Code, offering a solution to streamline manual cloud cost management efforts. Like its close cousin, Infrastructure as Code (IaC), FinOps as Code empowers FinOps practitioners to automate practices, maintain consistency, and promote collaboration among teams.
Terraform is an open-source IaC tool, developed by HashiCorp, that automates provisioning and managing your resources in a version-controlled manner. With Terraform, infrastructure definitions are written as code, typically using HashiCorp Configuration Language, or HCL. The benefit of using an IaC tool, like Terraform, is that it enables version control, code reuse, and collaboration — just like traditional software development. When applied to FinOps, you can use Terraform for practices like cost allocation via automated resource tagging as well as creating numerous reports and dashboards.
This blog walks through several FinOps use cases, showcasing how Terraform and other FinOps as Code tools can automate and optimize cloud financial operations. We’ll provide code samples and recommendations for how to get up and running with your FinOps as Code practice.
The FinOps Foundation maintains a set of FinOps Principles that “guide the activities of [the] FinOps practice.” Integrating the FinOps as Code approach along with these principles not only helps your organization develop a culture of cloud cost mindfulness — it also drives greater efficiency and removes the mundane and manual burden of pointing and clicking through the setup of numerous reports and filters. Considering a few of these principles, we’ll dive deeper and discover the power of automation combined with FinOps as Code.
The Personal ownership of cloud usage FinOps Principle seeks to empower teams to manage their individual cloud cost usage against a designated budget. You can include a Terraform resource within your infrastructure to create a budget, as well as a notification of any budget anomalies that helps the team to immediately recognize when they are nearing budget thresholds.
In the following example, a hypothetical Marketing team uses Amazon Simple Storage Service (S3) to store website media and promotional graphics. They also use EC2 as the compute solution for some marketing analytics systems. They want to set up a monthly budget of $1000 that also alerts the team when they reach a 90% threshold of that budget. Using the aws_budgets_budget Terraform resource, the team can easily configure this budget and ensure they are immediately made aware of approaching that limit.
aws_budgets_budget
First, define the aws_budgets_budget resource. Define the limit_amount and time_unit arguments to fit the determined needs.
limit_amount
time_unit
resource "aws_budgets_budget" "marketing_s3_ec2" { name = "budget-s3-ec2-monthly-marketing" budget_type = "COST" limit_amount = "1000" limit_unit = "USD" time_period_end = "2023-12-31_00:00" time_period_start = "2023-01-01_00:00" time_unit = "MONTHLY" # ...
Add the S3 and EC2 cost_filter argument.
cost_filter
resource "aws_budgets_budget" "marketing_s3_ec2" { # ... cost_filter { name = "Service" values = [ "Amazon Simple Storage Service", "Amazon Elastic Compute Cloud - Compute", ] } # ...
The FinOps Principles also stress that organizations need to “[c]reate, monitor, and improve real-time financial forecasting and planning.” In the spirit of timely reporting, you can add the notification argument to send alerts via Amazon Simple Notification Service (SNS).
notification
resource "aws_budgets_budget" "marketing_s3_ec2" { # ... notification { comparison_operator = "GREATER_THAN" threshold = 90 threshold_type = "PERCENTAGE" notification_type = "ACTUAL" subscriber_sns_topic_arns = ["arn:aws:sns:us-east-1:123456789012:BudgetAlert"] } }
In the above example, we pass the Amazon Resource Name (ARN) for an already created SNS topic; however, to automate things further, you can use the power of Terraform data sources to dynamically access an ARN that you can then use as a variable within the above configuration.
The Accessible and timely reports FinOps Principle stresses the importance of processing and sharing cost data as soon as it is available. These examples support how convenient and streamlined it is to integrate automation into your FinOps workflow while addressing some FinOps Principles. However, in reality, many organizations are multi-cloud consumers and also work with a number of other cloud service providers. As a result, setting up cost reporting to cover all cloud spend is daunting.
In the following example, we’ll use the Vantage Terraform provider (which uses our Write API and VQL) to demo a simplified workflow and architecture for a Marketing department that uses AWS and Snowflake. We’ll use Terraform to create a cloud cost management infrastructure that monitors costs for the Marketing team.
All demo files are also included in the FinOps as Code demo repo.
For this tutorial, we will use the below directory structure. /vantage_modules will contain all the Terraform resources that we’ll call from each module. The root main.tf will contain the modules we create — one for our Snowflake reporting infrastructure and one for our AWS reporting infrastructure.
/vantage_modules
main.tf
terraform-marketing-costs/ ├── main.tf ├── variables.tf ├── vantage_modules/ │ ├── main.tf │ ├── variables.tf │ ├── outputs.tf
The goal of this walkthrough will be to create a final dashboard that shows the Marketing team’s Snowflake and AWS costs from the past six months, grouped by month.
Note: Before you use the Vantage Terraform provider, you will need a Vantage API token. You can store your API credentials as an environment variable with export VANTAGE_API_TOKEN=an-api-token.
export VANTAGE_API_TOKEN=an-api-token
First, we’ll obtain the Marketing workspace token from the /workspaces Vantage API endpoint. We’ll store this token as a variable within the variables.tf file, in the root of our directory.
/workspaces
variables.tf
# variables.tf variable "marketing_workspace_token" { description = "Value of Marketing workspace token" type = string default = "wrkspc_12345" }
Next, we’ll create a set of Vantage resources in /vantage_modules/main.tf.
/vantage_modules/main.tf
We’ll use this file as the source when we create our modules. We can then reuse this set of resources across both the AWS and Snowflake modules.
source
These resources will create a folder, a saved filter, and a Cost Report that uses the saved filter within the Vantage console.
The filter argument of the vantage_saved_filter resource uses Vantage Query Language — or VQL — which is a SQL-like language for creating filters. Once created, the Snowflake filter will look like the below image. The AWS filter will look similar, specifying the AWS provider.
filter
vantage_saved_filter
Filter for Snowflake costs created in Terraform.
In this scenario, the value for costs.provider is stored as a variable (var.service), which will be referenced when constructing the modules. These values will be set to aws and snowflake in their respective modules.
costs.provider
var.service
aws
snowflake
# /vantage_modules/main.tf terraform { required_providers { vantage = { source = "vantage-sh/vantage" } } } resource "vantage_folder" "folder" { title = var.folder_title workspace_token = var.workspace_token } resource "vantage_saved_filter" "filter" { title = "${var.folder_title} Filter" filter = <<FILTER (costs.provider = '${var.service}' AND tags.name = '${var.tag_name}' AND tags.value = '${var.tag_value}') FILTER workspace_token = var.workspace_token } resource "vantage_cost_report" "report" { title = "${var.folder_title} Report" folder_token = vantage_folder.folder.token saved_filter_tokens = [vantage_saved_filter.filter.token] workspace_token = var.workspace_token }
Observe the use of variables throughout this configuration (for example, var.tag_value). These variables should be stored in the /vantage_modules/variables.tf file, depicted below.
var.tag_value
/vantage_modules/variables.tf
# /vantage_modules/variables.tf variable "folder_title" { description = "The title of the folder" type = string } variable "workspace_token" { description = "The workspace token" type = string } variable "service" { description = "The cloud service provider" type = string } variable "tag_name" { description = "The tag name" type = string } variable "tag_value" { description = "The tag value" type = string }
In addition, the report ID, or token, that is output from the vantage_saved_filter resource needs to be saved to /vantage_modules/outputs.tf. We’ll use this token when creating a Cost Report in the vantage_cost_report resource. To create a dashboard that displays a Snowflake and an AWS report, we’ll also need to create outputs to obtain the generated token for both Costs Reports.
token
/vantage_modules/outputs.tf
vantage_cost_report
# /vantage_modules/outputs.tf output "created_saved_filter" { value = vantage_saved_filter.filter.token } output "marketing_aws_cost_report_token" { value = vantage_cost_report.report.token } output "marketing_snowflake_cost_report_token" { value = vantage_cost_report.report.token }
Once created, the Cost Report will look like the below image. One report will be created for Snowflake costs, and one report will be created for AWS costs.
AWS Cost Report created in Terraform.
Finally, we’ll configure the root main.tf file, which includes both the marketing_aws and marketing_snowflake modules as well as their associated configurations.
marketing_aws
marketing_snowflake
Here we will define the arguments specific to each module. For example, the values for the tag_name and tag_value are used in the vantage_saved_filter resource we defined earlier. A best-practice cloud cost strategy includes resource tagging. In this scenario, the Marketing team’s cost allocation strategy includes adding cost_center AWS tags and Snowflake metadata to the resources they use.
tag_name
tag_value
cost_center
# main.tf terraform { required_providers { vantage = { source = "vantage-sh/vantage" } } } module "marketing_aws" { source = "./vantage_modules" folder_title = "Marketing AWS Costs" workspace_token = var.marketing_workspace_token service = "aws" tag_name = "cost_center" tag_value = "marketing" } module "marketing_snowflake" { source = "./vantage_modules" folder_title = "Marketing Snowflake Costs" workspace_token = var.marketing_workspace_token service = "snowflake" tag_name = "cost_center" tag_value = "marketing" }
To bring everything together, we’ll create a single dashboard that contains the AWS and Marketing Cost Reports. This dashboard shows costs over the past six months, grouped by month.
# main.tf # ... resource "vantage_dashboard" "dashboard" { widget_tokens = [ module.marketing_aws.marketing_aws_cost_report_token, module.marketing_snowflake.marketing_snowflake_cost_report_token ] title = "Marketing Dashboard" date_interval = "last_6_months" date_bin = "month" workspace_token = var.marketing_workspace_token }
After running terraform plan and terraform apply, we now have a fully functioning dashboard that shows both AWS and Snowflake costs attributed to the Marketing team. Per our initial goal, the dashboard shows monthly data for the past six months. We’ve packaged a set of resources and variables we can use across multiple cloud service providers.
terraform plan
terraform apply
Final dashboard: AWS and Snowflake marketing costs for the past six months, created in Terraform.
FinOps as Code offers a new, more streamlined approach to cloud cost management. It not only addresses the increasing complexity of cloud budgets and resource management but also aligns with traditional software practices, like infrastructure automation and collaboration. As cloud practitioners grapple with multi-cloud deployments and numerous cloud service providers, FinOps as Code can promote financial efficiency.
The tutorial demonstrated a practical application of FinOps Principles using Terraform. Cloud practitioners can easily implement this cost-efficient and collaborative approach. The FinOps as Code mindset will empower teams to take ownership of their cloud usage and ensure accessible and timely financial insights.
MongoDB Atlas is the cost-effective choice for production workloads where high-availability is a requirement.
Grafana is a strong competitor to the monitoring and observability features of Datadog for a fraction of the price.
AWS is implementing a policy update that will no longer allow Reserved Instances and Savings Plans to be shared across end customers.