GreenOps

© 2026 GreenOps. All rights reserved.

npx greenops-scanBlogPrivacy PolicyTermsRefund PolicyMethodology
GreenOps
ProblemSolutionPricingBlognpx greenops-scan
Sign in / Sign upFree audit
← Back to blog
GreenOps dashboard preview

Every Finding Now Tells You Which Team, Project, and Stack Owns It

"Idle database — avg CPU 4.3%" is a fact. It's not an owner.

Every cost/carbon finding a scanner produces answers what is wrong. It almost never answers the question that actually blocks you from fixing it: whose resource is this, and where does it live in code?

In any account with more than a handful of engineers, a resourceId like dlcsearchmysqldatabasesta-dlcsearchmysqlinstance1c-s4a5orsoc232 tells you nothing. You either already know the account well enough to guess, or you go spelunking through the AWS console, CloudTrail, or a spreadsheet someone maintains by hand, just to find out which team to Slack.

GreenOps Scan now skips that step entirely. Every finding can carry the underlying resource's AWS tags — straight from the account, attached automatically, no extra setup.

What it looks like

No new flag needed — tags show up automatically wherever a resource has them, in human output, --json, --llm-prompts, and --cached:

npx greenops-scan --profile production --region eu-west-1 --severity critical
  - severity: CRITICAL
    module: RDS
    resource: dlcsearchmysqldatabasesta-dlcsearchmysqlinstance1c-s4a5orsoc232
    resourceType: RDS Instance
    region: eu-west-1
    tags:
      Project: dlcsearch
      Department: CCE
      Repository: my-org/appdev-cce-dlc-search
      aws:cloudformation:stack-name: DLCSearchMySqlDatabaseStack
      aws:cloudformation:logical-id: DLCSearchMySqlInstance1C692381
    issue: Idle database — avg CPU 4.3% over 14 days
    costSavings: $12.41/mo
    confidence: MED
    co2Savings: 1.48 kg/mo
    recommendation: Consider stopping, downsizing, or consolidating this database

That's a real shape of finding pulled from a live scan (resource IDs shortened, account/repo names changed) — and it goes from "some idle database, good luck" to "this belongs to the dlcsearch project, owned by the CCE department, defined in the my-org/appdev-cce-dlc-search repo, inside the DLCSearchMySqlDatabaseStack CloudFormation stack, as the DLCSearchMySqlInstance1C692381 logical resource." No guessing, no Slack thread, no console detective work.

It makes --llm-prompts dramatically more useful

We shipped --llm-prompts recently so engineers could hand a finding straight to their coding agent instead of running a raw aws command against a live resource. The one thing that prompt was missing was a reliable way for the agent to find the resource in the repo. Tags close that gap:

    ----- COPY BELOW: LLM fix prompt -----
    Fix this AWS cost/carbon finding in my infrastructure as code (Terraform, AWS CDK,
    CloudFormation, Pulumi, Serverless Framework, or whatever this repo uses) — do not
    change the live resource via the AWS CLI or console, make the change in code so it
    stays in sync with the rest of the stack:

    Resource: RDS Instance "dlcsearchmysqldatabasesta-dlcsearchmysqlinstance1c-s4a5orsoc232" (region: eu-west-1)
    Module: rds
    Issue: Idle database — avg CPU 4.3% over 14 days
    Recommendation: Consider stopping, downsizing, or consolidating this database
    Estimated savings: $12.41/mo ($148.92/yr), 1.48 kg CO2/mo
    Context:
      - avgCpuPercent: 4.3
      - instanceClass: "db.t3.micro"
      - engine: "mysql"
    Resource tags (use these to help locate the right stack/module):
      - Project: dlcsearch
      - Department: CCE
      - Repository: my-org/appdev-cce-dlc-search
      - aws:cloudformation:stack-name: DLCSearchMySqlDatabaseStack
      - aws:cloudformation:logical-id: DLCSearchMySqlInstance1C692381

    Please:
    1. Search this repository for where "dlcsearchmysqldatabasesta-dlcsearchmysqlinstance1c-s4a5orsoc232"
       (or a matching tag/logical name) is defined in infrastructure-as-code.
    2. Apply the change described in the recommendation above, keeping all other
       configuration unchanged.
    3. Show me the diff before applying/deploying anything — do not run
       `terraform apply`, `cdk deploy`, or equivalent without my review.
    4. If you can't find this resource in the codebase, tell me instead of guessing.
    ----- COPY ABOVE -----

When a resource is CloudFormation-managed, aws:cloudformation:stack-name and aws:cloudformation:logical-id are tags AWS attaches automatically — meaning your agent doesn't have to guess or fuzzy-match a resource ID at all. It can go straight to the exact stack and logical resource. For Terraform or CDK shops, Project, Repository, and similar custom tags do the same job.

No new permissions, no new setup

This was the non-negotiable design constraint. GreenOps Scan already asks customers to attach the standard AWS managed policy ReadOnlyAccess to the read-only role it assumes. Tag lookups go through a single unified API — ResourceGroupsTaggingAPI.GetResources — and that action is already included in ReadOnlyAccess. If you're already scanning an account, tags just start showing up. There's nothing to reconfigure, no new IAM statement to add, no re-run of --profile add.

It's also strictly best-effort:

  • If a resource has no tags, the tags field is simply omitted from that finding.
  • If tag fetching fails for any reason — a stricter custom IAM policy, a LocalStack environment that doesn't implement the API, a transient error — the scan continues normally with tags absent. It never blocks or fails a scan.
  • Coverage today spans EC2 instances and EBS volumes, RDS instances, ElastiCache clusters, Lambda functions, EKS clusters, OpenSearch domains, S3 buckets, and CloudFront distributions — the resource types most commonly flagged for cost/carbon waste. A few modules (Bedrock, ECS, VPC endpoints, and any purely aggregate finding like "12 EBS snapshots older than a year") don't have a single real resource to tag yet, so they're intentionally left out rather than guessed at.

Works everywhere findings already do

Tags flow through the whole pipeline, not just the pretty terminal output:

# JSON output includes the tags field per finding
npx greenops-scan --format json | jq '.findings[] | select(.tags) | {resourceId, tags}'

# Filter a cached report and still see tags — they were saved with the original scan
npx greenops-scan --cached --severity critical --modules rds

# Combine with LLM prompts for the full "who owns this, fix it in code" workflow
npx greenops-scan --severity critical --llm-prompts

Try it

npx greenops-scan

If your account tags its resources — by hand, via CloudFormation, via a Terraform default_tags block, or an org-wide tagging policy — you'll see the payoff on your very next scan. No flag to remember, nothing to turn on. It's just more context on the same findings you already get, aimed at the one question every finding used to leave unanswered: whose is this, and where do I go to fix it?

Tags: #AWS #FinOps #CloudCostOptimization #ResourceTagging #InfrastructureAsCode #CloudFormation #Terraform #GreenOps

More posts

View all posts →

Stop Pasting AWS CLI Commands Into Prod — Let Your Agent Fix the Code Instead

GreenOps Scan's new --llm-prompts flag turns every finding into a copy/paste prompt for Copilot, Claude, or Cursor to fix in your actual Terraform/CDK/CloudFormation source — no more IaC drift from hand-run remediation commands.

The Bill You Don't See Coming: AWS Extended Support Surcharges

GreenOps Scan now proactively detects deprecated Lambda runtimes, RDS/Aurora/DocumentDB engines, EKS versions, ElastiCache Redis, and OpenSearch domains before AWS starts billing you extra for staying on them.

How to Right-Size EC2 Instances Before You Migrate to Graviton

A practical guide to collecting CPU, memory, and network baselines, matching the right instance family, and avoiding the common mistakes that kill Graviton migrations.