DEV Community

Yash
Yash

Posted on

Multi-account AWS cost visibility: the tagging strategy that actually works

Multi-account AWS cost visibility: the tagging strategy that actually works

The gap between "we have a billing dashboard" and "we understand our costs" is almost always a tagging problem.

The tag taxonomy

Required (enforced via AWS Config):
  Project     = "payment-api" | "user-service"
  Environment = "prod" | "staging" | "dev"
  Team        = "platform" | "backend"
  ManagedBy   = "terraform" | "manual"
Enter fullscreen mode Exit fullscreen mode

Terraform: default_tags (auto-applies to every resource)

provider "aws" {
  region = "us-east-1"
  default_tags {
    tags = {
      Project     = var.project_name
      Environment = var.environment
      Team        = var.team
      ManagedBy   = "terraform"
    }
  }
}
# All resources now inherit these tags — no per-resource tagging needed
Enter fullscreen mode Exit fullscreen mode

Enforce via AWS Config

resource "aws_config_config_rule" "required_tags" {
  name = "required-tags"
  source { owner = "AWS"; source_identifier = "REQUIRED_TAGS" }
  input_parameters = jsonencode({
    tag1Key = "Project"; tag2Key = "Environment"; tag3Key = "Team"
  })
}
Enter fullscreen mode Exit fullscreen mode

Query cost by project (Lambda)

import boto3

def get_cost_by_project(account_id: str) -> dict:
    ce = boto3.client('ce', region_name='us-east-1')
    response = ce.get_cost_and_usage(
        TimePeriod={'Start': '2025-01-01', 'End': '2025-02-01'},
        Granularity='MONTHLY',
        Filter={'Dimensions': {'Key': 'LINKED_ACCOUNT', 'Values': [account_id]}},
        GroupBy=[{'Type': 'TAG', 'Key': 'Project'}],
        Metrics=['UnblendedCost']
    )
    return {
        g['Keys'][0].replace('Project$', ''):
        round(float(g['Metrics']['UnblendedCost']['Amount']), 2)
        for g in response['ResultsByTime'][0]['Groups']
    }
Enter fullscreen mode Exit fullscreen mode

Most common tagging failures

  1. Tags on launch, never updated — use Config rules to catch untagged resources
  2. Different values for same concept ("prod", "production", "PROD") — enforce allowed values
  3. EC2 tagged but not EBS volumes — add volume_tags in Terraform provider
  4. Tags not activated in Cost Explorer — takes 24 hours after activation

Per-project cost visibility across accounts is coming to Step2Dev in Q1.

👉 step2dev.com

Top comments (0)