Solved: Visualizing AWS Billing Costs in Google Sheets via API

Source: Dev.to | Jan 17, 2026 (UTC)

🚀 Executive Summary

TL;DR: Manually managing AWS billing data in spreadsheets is inefficient and costly SaaS alternatives exist. This solution automates fetching AWS Cost Explorer data into Google Sheets using Python, boto3, and gspread, enabling custom, cost-effective visualization and analysis.

🎯 Key Takeaways

  • Programmatic access to AWS Cost Explorer data requires a dedicated IAM user with ce:GetCostAndUsage and related permissions, adhering to the principle of least privilege.
  • Secure authentication to Google Sheets for data ingestion is achieved via a Google Service Account, requiring a JSON key file and ‘Editor’ access granted to the target Google Sheet.
  • A Python script leveraging boto3 for AWS Cost Explorer API interaction (get\_cost\_and\_usage) and gspread for writing data to Google Sheets forms the core of this automated billing visualization pipeline.

Visualizing AWS Billing Costs in Google Sheets via API

Introduction

In the fast-paced world of cloud computing, managing and understanding your AWS expenditures can often feel like navigating a labyrinth.

While the AWS Billing Console provides a wealth of information, extracting and visualizing this data in a custom, flexible, and repeatable manner for deeper analysis can be a cumbersome, manual process.

Exporting CSVs and manually importing them into spreadsheets is not only time-consuming but also prone to errors and lacks the agility required for timely financial insights.

SaaS solutions exist, but they come with their own costs and might not always align with your specific reporting needs or data governance policies.

What if you could pull your AWS billing data directly into a familiar tool like Google Sheets, automate the process, and build custom dashboards without incurring extra subscription fees?

This tutorial from TechResolve will guide SysAdmins, Developers, and DevOps Engineers through building a robust, automated solution to fetch AWS billing costs using the AWS Cost Explorer API and push that data into Google Sheets via its API.

You’ll gain the power to create bespoke visualizations, perform ad-hoc analysis, and share insights seamlessly with your team, all while keeping costs in check and minimizing manual effort.

Prerequisites

Before we dive into the implementation, ensure you have the following:

  • An AWS Account: With permissions to access Cost Explorer data.
  • An AWS IAM User: With programmatic access (Access Key ID and Secret Access Key) and an attached policy allowing ce:GetCostAndUsage.
  • A Google Cloud Project: To enable the Google Sheets API and create a service account.
  • Google Sheets API Enabled: Within your Google Cloud Project.
  • Google Service Account: With a generated JSON key file. This account will need editor access to your target Google Sheet.
  • A Google Sheet: Created and ready to receive data. Make sure it’s shared with the email address of your Google Service Account.
  • Python 3.x: Installed on your local machine or a server where you’ll run the script.
  • pip: Python’s package installer, usually included with Python 3.x.

Step-by-Step Guide

Step 1: Set Up AWS IAM User and Permissions

To programmatically access AWS billing data, we need an IAM user with specific permissions.

It’s a best practice to create a dedicated IAM user with the least privilege required, rather than using root credentials.

  1. Navigate to the AWS IAM console.
  2. Go to “Users” and click “Add user”.
  3. Provide a user name (e.g., techresolve-billing-api-user).
  4. Select “Programmatic access” as the access type.
  5. On the “Permissions” screen, choose “Attach existing policies directly” and click “Create policy”.
  6. In the new tab, select the “JSON” tab and paste the following policy. This grants read-only access to Cost Explorer data.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ce:GetCostAndUsage", "ce:GetDimensionValues", "ce:GetCostForecast", "ce:GetTags" ], "Resource": "*" } ] }

Enter fullscreen mode

Exit fullscreen mode

Give your new policy a name (e.g., TechResolveCostExplorerReadOnly) and create it.

Then, attach this newly created policy to your IAM user.

Complete the user creation process. You will be presented with the Access Key ID and Secret Access Key.

Store these securely; you will not be able to retrieve the Secret Access Key again.

You can configure these credentials as environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) or in your AWS CLI configuration file (~/.aws/credentials).

Step 2: Configure Google Cloud Project and Sheets API

Next, we need to enable the Google Sheets API and create a service account that our Python script will use to authenticate and write data.

  1. Go to the Google Cloud Console.
  2. Create a new project or select an existing one.
  3. Navigate to “APIs & Services” > “Library”.
  4. Search for “Google Sheets API” and enable it for your project.
  5. Go to “APIs & Services” > “Credentials”.
  6. Click “Create Credentials” > “Service Account”.
  7. Provide a service account name (e.g., techresolve-sheets-writer) and description.
  8. Grant the service account a role. For basic writing to a spreadsheet, “Project” > “Editor” is sufficient, or a more granular role like “Sheets” > “Google Sheets Editor”.
  9. In the next step, create a new JSON key for the service account. This will download a JSON file to your computer. Keep this file secure and remember its path. We’ll refer to it as service_account_key.json.
  10. Finally, open your target Google Sheet. Click “Share” and paste the email address of your newly created service account. Grant it “Editor” access.

Step 3: Develop the Python Script for Data Extraction and Ingestion

Now for the core logic. We’ll write a Python script that uses boto3 to fetch AWS Cost Explorer data and gspread to write it to Google Sheets.

First, install the necessary Python libraries:

pip install boto3 gspread

Enter fullscreen mode

Exit fullscreen mode

Here’s a comprehensive Python script. Remember to replace placeholders like YOUR_GOOGLE_SHEET_NAME and YOUR_SERVICE_ACCOUNT_KEY_PATH.

import boto3 import gspread from datetime import datetime, timedelta # --- Configuration --- # Your Google Sheet details GOOGLE_SHEET_NAME = "My AWS Billing Dashboard" GOOGLE_WORKSHEET_NAME = "Monthly Costs" SERVICE_ACCOUNT_KEY_PATH = "./service_account_key.json" # Path to your downloaded JSON key # AWS Cost Explorer Configuration AWS_REGION = "us-east-1" # Or your preferred AWS region GRANULARITY = "MONTHLY" # DAILY, MONTHLY METRICS = ["UnblendedCost"] # Can also include "BlendedCost", "UsageQuantity" GROUP_BY = [{"Type": "DIMENSION", "Key": "SERVICE"}] # Group by service, linked account, etc. # Time Period (Last month's data) END_DATE = datetime.now().strftime('%Y-%m-%d') # Today START_DATE = (datetime.now() - timedelta(days=30)).replace(day=1).strftime('%Y-%m-%d') # Start of last full month # --- AWS Data Fetching Function --- def get_aws_cost_data(): """Fetches AWS cost and usage data from Cost Explorer.""" client = boto3.client("ce", region_name=AWS_REGION) response = client.get_cost_and_usage( TimePeriod={ "Start": START_DATE, "End": END_DATE }, Granularity=GRANULARITY, Metrics=METRICS, GroupBy=GROUP_BY ) data = [] # Extract headers from the first group's keys if available headers = ["TimePeriod", "Service"] + [metric.strip() for metric in METRICS] data.append(headers) for item in response["ResultsByTime"]: time_period = f"{item['TimePeriod']['Start']} to {item['TimePeriod']['End']}" for group in item["Groups"]: service_name = group["Keys"][0] cost_value = float(group["Metrics"]["UnblendedCost"]["Amount"]) data.append([time_period, service_name, cost_value]) # Handle pagination if more data exists (for large accounts/longer periods) next_page_token = response.get('NextPageToken') while next_page_token: response = client.get_cost_and_usage( NextPageToken=next_page_token, TimePeriod={ "Start": START_DATE, "End": END_DATE }, Granularity=GRANULARITY, Metrics=METRICS, GroupBy=GROUP_BY ) for item in response["ResultsByTime"]: time_period = f"{item['TimePeriod']['Start']} to {item['TimePeriod']['End']}" for group in item["Groups"]: service_name = group["Keys"][0] cost_value = float(group["Metrics"]["UnblendedCost"]["Amount"]) data.append([time_period, service_name, cost_value]) next_page_token = response.get('NextPageToken') return data # --- Google Sheets Update Function --- def update_google_sheet(data_to_write): """Authenticates with Google Sheets and updates the specified worksheet.""" try: # Authenticate with Google using the service account key gc = gspread.service_account(filename=SERVICE_ACCOUNT_KEY_PATH) # Open the spreadsheet by name spreadsheet = gc.open(GOOGLE_SHEET_NAME) # Select the worksheet by name # If the worksheet doesn't exist, create it (optional, but robust) try: worksheet = spreadsheet.worksheet(GOOGLE_WORKSHEET_NAME) except gspread.exceptions.WorksheetNotFound: print(f"Worksheet '{GOOGLE_WORKSHEET_NAME}' not found, creating it...") worksheet = spreadsheet.add_worksheet(title=GOOGLE_WORKSHEET_NAME, rows="100", cols="20") # Clear existing content and write new data worksheet.clear() worksheet.update('A1', data_to_write) print(f"Successfully updated Google Sheet '{GOOGLE_SHEET_NAME}' - Worksheet '{GOOGLE_WORKSHEET_NAME}'") except Exception as e: print(f"Error updating Google Sheet: {e}") # --- Main Execution --- if __name__ == "__main__": print("Fetching AWS cost data...") aws_data = get_aws_cost_data() if aws_data: print(f"Fetched {len(aws_data) - 1} data rows from AWS.") update_google_sheet(aws_data) else: print("No AWS data fetched.")

Enter fullscreen mode

Exit fullscreen mode

Logic Explanation:

  1. Configuration: Defines variables for Google Sheet names, service account key path, AWS region, and how to group/aggregate billing data (e.g., monthly by service).
  2. get_aws_cost_data():
  3. update_google_sheet():
  4. Main Execution Block: Calls the AWS data fetching function, and if data is retrieved, passes it to the Google Sheets update function.

Step 4: Run the Script and Verify

Save the Python script (e.g., as aws_billing_to_sheets.py).

Ensure your service_account_key.json is in the same directory or adjust the SERVICE_ACCOUNT_KEY_PATH variable accordingly.

Execute the script from your terminal:

python aws_billing_to_sheets.py

Enter fullscreen mode

Exit fullscreen mode

After execution, open your Google Sheet. You should see the monthly AWS cost data, grouped by service, populated in the specified worksheet.

You can then use Google Sheets’ built-in features (pivot tables, charts, conditional formatting) to visualize and analyze your costs.

Step 5: Automation and Visualization Ideas

To make this solution truly powerful, automate its execution. You can use:

Once the data is in Google Sheets, unleash its potential:

Common Pitfalls

Even with careful planning, you might encounter some issues. Here are a couple of common ones:

Verify all these points.

Conclusion

You’ve successfully built an automated pipeline to extract AWS billing data and visualize it within Google Sheets.

This not only eliminates tedious manual work but also empowers you with granular control over your cost reporting and analysis.

By leveraging the AWS Cost Explorer API and the Google Sheets API, you’ve created a flexible, cost-effective solution tailored to your organization’s needs.

From here, the possibilities are endless. Consider enhancing your script to:

Keep iterating, keep optimizing, and take control of your cloud spend with data-driven insights. Happy visualizing!

👉 Read the original article on TechResolve.blog

For further actions, you may consider blocking this person and/or reporting abuse

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Читайте також