<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bharath Nadar</title>
    <description>The latest articles on DEV Community by Bharath Nadar (@bharathnoddy).</description>
    <link>https://dev.to/bharathnoddy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1386608%2F27097396-aacb-4bd6-84a0-7f9d515ae1ef.png</url>
      <title>DEV Community: Bharath Nadar</title>
      <link>https://dev.to/bharathnoddy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bharathnoddy"/>
    <language>en</language>
    <item>
      <title>The Network Bill Nobody Owned: Finding Hidden AWS Data Transfer Cost with eBPF</title>
      <dc:creator>Bharath Nadar</dc:creator>
      <pubDate>Fri, 09 Oct 2026 09:55:25 +0000</pubDate>
      <link>https://dev.to/bharathnoddy/the-network-bill-nobody-owned-finding-hidden-aws-data-transfer-cost-with-ebpf-5ge9</link>
      <guid>https://dev.to/bharathnoddy/the-network-bill-nobody-owned-finding-hidden-aws-data-transfer-cost-with-ebpf-5ge9</guid>
      <description>&lt;p&gt;On a typical Kubernetes-on-AWS bill, &lt;strong&gt;15–20% of the cost is network&lt;/strong&gt;: cross-AZ data transfer, VPC peering, cross-region transfer and NAT Gateway bytes. On a $1M monthly AWS bill, that's &lt;strong&gt;$150–200k every month&lt;/strong&gt;. It's serious money, and it's almost always hidden. It sits on a few line items that everybody sees and nobody owns, and every review ends the same way: "it's network, it's the platform's problem".&lt;/p&gt;

&lt;p&gt;This post is about how we turned those lines into a list of named workloads with a cost next to each, and what we found once we could see it. The short version: within days of having per-app network data, we had more concrete savings opportunities than in months of looking at Cost Explorer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The pain: you can see the bill, but not the cause&lt;/li&gt;
&lt;li&gt;The approach: count bytes where the pod still has a name&lt;/li&gt;
&lt;li&gt;What we found&lt;/li&gt;
&lt;li&gt;How FinOps and OBI solved it together&lt;/li&gt;
&lt;li&gt;Why network-level observability matters&lt;/li&gt;
&lt;li&gt;Takeaways&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The pain: you can see the bill, but not the cause
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost Explorer tells you &lt;em&gt;what&lt;/em&gt; you pay for, never &lt;em&gt;who&lt;/em&gt; caused it.&lt;/strong&gt; &lt;code&gt;DataTransfer-Regional-Bytes&lt;/code&gt; is one number per account. It doesn't know about pods, deployments or teams.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tag-based showback gets network cost wrong.&lt;/strong&gt; Most FinOps reports assign cost by the EC2 instance's team tag. That works for compute. For network, it charges every byte leaving a node to whoever owns the node, including bytes sent by shared DaemonSets like log shippers and agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VPC Flow Logs see IPs, not workloads.&lt;/strong&gt; Pods churn, IPs get reused, and NAT and peering traffic is often SNATed to the node IP before Flow Logs see it. Joining Flow Logs to Kubernetes metadata after the fact is a project of its own, and keeping them on for a large cluster isn't cheap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;So the conversation goes nowhere.&lt;/strong&gt; "Your team's network cost went up." "We don't do anything network-heavy." Nobody can prove otherwise, so nothing changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The missing piece wasn't another dashboard of totals. It was &lt;strong&gt;attribution&lt;/strong&gt;: &lt;em&gt;this&lt;/em&gt; workload talks to &lt;em&gt;that&lt;/em&gt; workload, across &lt;em&gt;this&lt;/em&gt; billable path, costing &lt;em&gt;this&lt;/em&gt; much.&lt;/p&gt;

&lt;h2&gt;
  
  
  The approach: count bytes where the pod still has a name
&lt;/h2&gt;

&lt;p&gt;We used &lt;strong&gt;OBI (OpenTelemetry eBPF Instrumentation)&lt;/strong&gt;. A small eBPF program on each node counts bytes per network flow in the kernel, with no sidecars and no code changes. OBI then enriches each flow with Kubernetes metadata: namespace, owner workload, and pod labels like &lt;code&gt;application&lt;/code&gt; and &lt;code&gt;team&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Two placements made it work for cost:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On the node NIC (egress only):&lt;/strong&gt; every byte is counted once, on the sender. This is the source of truth for &lt;strong&gt;cross-AZ&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On the pod's veth interface:&lt;/strong&gt; the packet still carries the &lt;strong&gt;pod IP before SNAT&lt;/strong&gt;, so NAT and peering traffic can still be attributed to the pod that sent it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We gave OBI a &lt;strong&gt;CIDR map generated from the AWS API&lt;/strong&gt;: every subnet with its AZ, every peered VPC (same region and cross region), the gateway endpoints, and &lt;code&gt;0.0.0.0/0&lt;/code&gt; as "internet via NAT". An OpenTelemetry Collector turns that into one&lt;br&gt;
metric with a cost class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight prometheus"&gt;&lt;code&gt;&lt;span class="n"&gt;netcost_bytes_total&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;net_class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cross_az|nat|same_region_peering|cross_region"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;                    &lt;span class="na"&gt;net_team&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;net_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;net_workload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;                    &lt;span class="na"&gt;net_remote_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;net_remote_workload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;net_zone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Multiply by the AWS price per class and you get **cost per app, per team, and per "who talks to whom" pair*you already use.&lt;/p&gt;

&lt;p&gt;The dashboard that mattered most was a set of plain tables, not charts: &lt;em&gt;"Cross-AZ: who talks to whom"&lt;/em&gt;, &lt;em&gt;"alks to each peer VPC"&lt;/em&gt;. Each row is a sender workload, a receiver workload, bytes, and estimated cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we found
&lt;/h2&gt;

&lt;p&gt;None of these were visible in Cost Explorer. All of them showed up in the first few days of data.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Logs shipped uncompressed over VPC peering.&lt;/strong&gt; The biggest peering sender wasn't an app. It was the logng every node's logs uncompressed to a search cluster in a peered VPC. Its cost was spread across everyteam's node bill. &lt;em&gt;Fix:&lt;/em&gt; compress, drop noisy logs at the source, keep the log path local.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pods that aren't topology-aware.&lt;/strong&gt; With random endpoint choice across three AZs, about two-thirds of sossed a zone. &lt;em&gt;Fix:&lt;/em&gt; &lt;code&gt;topologySpreadConstraints&lt;/code&gt; plus zone-aware routing (&lt;code&gt;trafficDistribution: PreferClose&lt;/code&gt;or mesh locality load balancing).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single-replica Redis.&lt;/strong&gt; One app's biggest cross-AZ flow was to its own Redis: a single pod in one AZ, others. &lt;em&gt;Fix:&lt;/em&gt; a read replica in every AZ and nearest-replica reads, which also removes a single point offailure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unwanted cross-region transfer.&lt;/strong&gt; Workloads calling another region when an in-region endpoint already d configs. &lt;em&gt;Fix:&lt;/em&gt; use the in-region endpoint, and make cross-region traffic a reviewed decision.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ingress responses crossing zones.&lt;/strong&gt; Responses (the big half of the traffic) went back to an ingress gateway in another AZ. &lt;em&gt;Fix:&lt;/em&gt; locality-aware load balancing at the gateway.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How FinOps and OBI solved it together
&lt;/h2&gt;

&lt;p&gt;FinOps on its own gives you a bill. OBI on its own gives you traffic metrics. The value came from using them in that order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FinOps answers "how much" and "where to look".&lt;/strong&gt; The FinOps reports, built on the AWS bill (CUR), show each team's network spend and flag which team or account is growing. That's the starting point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OBI answers "who" and "why".&lt;/strong&gt; Once FinOps points at a team, OBI digs in: every byte has a sender worklnd a billable path. And because AWS prices turn those bytes into cost, we can check the result adds upagainst the bill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Together, they turn a cost line into a ticket.&lt;/strong&gt; Instead of "network cost went up", each finding names es, the cost, and the fix, and it goes to the team that can act on it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They also correct showback.&lt;/strong&gt; When a team's bill includes traffic they didn't send, like shared log shipping on their nodes, the data shows it, and the cost moves to the owner who can fix it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why network-level observability matters
&lt;/h2&gt;

&lt;p&gt;Most teams have good visibility into compute: CPU, memory, requests per second, cost per node pool. Network is usually a blind spot, even though it's often the fastest-growing part of the bill. Without network-level observability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Architecture decisions carry hidden cost.&lt;/strong&gt; A single-replica cache, a service without zone awareness or a default cross-region endpoint all look fine in a design review. The cost only shows up on the bill, months later, with no owner
attached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cost grows silently.&lt;/strong&gt; Every new service, replica or AZ adds traffic. Nothing alerts on it, and nobody sees it until the monthly bill.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Showback is wrong.&lt;/strong&gt; Tag-based attribution charges node owners for traffic they didn't send. Teams lose the real owners never find out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Troubleshooting is slower.&lt;/strong&gt; The same data that explains cost also answers "which app suddenly started sending gigabytes to another region?" during an incident.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With network-level observability, network cost becomes like any other engineering metric: measured per workload, owned by a team, and reviewed when architecture changes. That's what lets a platform team push for zone-aware design, per-AZ&lt;br&gt;
replicas and sensible log shipping with evidence instead of guidelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Network is 15–20% of a typical AWS bill, and it's the part nobody owns. On a $1M bill, that's $150–200k without attribution.&lt;/li&gt;
&lt;li&gt;FinOps tells you which team's network spend to look at. eBPF (OBI) tells you which workload sends each byte, and why. You need both to turn the bill into action.&lt;/li&gt;
&lt;li&gt;The usual suspects are worth checking first: uncompressed logs over peering, pods that aren't topology-as, unwanted cross-region calls, and ingress responses crossing zones.&lt;/li&gt;
&lt;li&gt;Treat network as a first-class part of observability, alongside CPU and memory. It's where a lot of the hidden cost lives.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your bill has a network line that nobody owns, you probably have the same findings waiting for you.&lt;/p&gt;

</description>
      <category>finops</category>
      <category>k8s</category>
      <category>cloud</category>
      <category>observability</category>
    </item>
    <item>
      <title>One Default CloudTrail Setting Cost Us $200,000 — Fixed in 5 Minutes</title>
      <dc:creator>Bharath Nadar</dc:creator>
      <pubDate>Wed, 11 Mar 2026 14:47:30 +0000</pubDate>
      <link>https://dev.to/bharathnoddy/a-200000-aws-bill-nobody-noticed-fixed-in-5-minutes-3p08</link>
      <guid>https://dev.to/bharathnoddy/a-200000-aws-bill-nobody-noticed-fixed-in-5-minutes-3p08</guid>
      <description>&lt;p&gt;We had a $200,000 problem hiding in plain sight.&lt;/p&gt;

&lt;p&gt;Not a breach. Not a runaway workload. Not even the security tool we had just onboarded. A single default setting, accepted during that tool's setup, that nobody revisited as the company scaled.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers That Didn't Add Up
&lt;/h2&gt;

&lt;p&gt;Late 2025. Reviewing AWS Cost Explorer. CloudTrail — a line item that used to sit quietly around $1,000 a month — had crept to $10,000 in one prod account and $30,000 at the org level.&lt;/p&gt;

&lt;p&gt;It never triggered an alert because it didn't spike. It crept.&lt;/p&gt;

&lt;p&gt;Around the same time, other costs had come down — reserved instance discounts, some workloads rightsized. The overall bill looked reasonable. CloudTrail was hiding in the noise.&lt;/p&gt;

&lt;p&gt;By the time I caught it: roughly $200,000 spent on audit logs nobody had asked for.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Was Causing It
&lt;/h2&gt;

&lt;p&gt;Breaking down CloudTrail by usage type in Cost Explorer showed the bill was driven entirely by data event recording — &lt;strong&gt;8.98 billion S3 events in us-east-1 alone&lt;/strong&gt; in December, at &lt;strong&gt;$0.10 per 100,000 events&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The org trail config explained why:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ReadWriteType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"All"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"DataResources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::S3::Object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every S3 API call. Every read, every write. Every bucket. Every account in the org.&lt;/p&gt;

&lt;p&gt;S3 reads account for &lt;strong&gt;85–95% of all S3 data events&lt;/strong&gt; in a production environment. ML pipelines, CDN origins, build artifact stores — all logging every single fetch. Billions of them. Every month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where That Config Came From
&lt;/h2&gt;

&lt;p&gt;One of the onboarding steps for a new security tool was to enable CloudTrail S3 data events. The setup offered a default: log &lt;strong&gt;read and write&lt;/strong&gt; events for &lt;strong&gt;all S3 buckets&lt;/strong&gt;. An engineer accepted it. Completely reasonable — it was the default, and a security tool was asking for it.&lt;/p&gt;

&lt;p&gt;That's the trap. The security tool wasn't reading our buckets. Our own workloads were, the same way they always had. The difference was that CloudTrail now recorded every one of those &lt;code&gt;GetObject&lt;/code&gt; and &lt;code&gt;HeadObject&lt;/code&gt; calls as an audit event, at $0.10 per 100,000. As traffic grew, so did the bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does Compliance Actually Require This?
&lt;/h2&gt;

&lt;p&gt;Before touching anything, I checked.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;S3 Read Logging Required?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SOC 2 Type II&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ISO 27001&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GDPR&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CIS AWS Benchmark&lt;/td&gt;
&lt;td&gt;Recommended (Level 2), not mandatory&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The CIS benchmark does recommend object-level logging for both reads and writes. That's often why security tools ask for it — it's an easy check to pass. But passing a check isn't the same as needing the data for every bucket.&lt;/p&gt;

&lt;p&gt;Read auditing earns its cost on buckets that hold &lt;strong&gt;customer data, PII, or credentials&lt;/strong&gt; — there you want to know who accessed what. For everything else, writes and deletes are what matter.&lt;/p&gt;

&lt;p&gt;Nobody needs to know a Lambda function fetched a static asset at 3am. They &lt;em&gt;do&lt;/em&gt; need to know if someone deleted a production backup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Phase 1 — Switch to WriteOnly
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudtrail put-event-selectors &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--trail-name&lt;/span&gt; &amp;lt;your-org-trail-arn&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--event-selectors&lt;/span&gt; &lt;span class="s1"&gt;'[{"ReadWriteType":"WriteOnly","IncludeManagementEvents":true,"DataResources":[{"Type":"AWS::S3::Object","Values":["arn:aws:s3:::"]}]}]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;"All" → "WriteOnly".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One word. ~$300,000 in annual savings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2 — Add Reads Back Only Where They Matter
&lt;/h3&gt;

&lt;p&gt;Switching to WriteOnly eliminates ~90% of the cost. The next step is turning read logging back on — but only for buckets that genuinely need it: customer data, PII, credentials, or compliance data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ReadWriteType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WriteOnly"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"IncludeManagementEvents"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"DataResources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::S3::Object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ReadWriteType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ReadOnly"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"IncludeManagementEvents"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"DataResources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::S3::Object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::your-pii-bucket/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::your-customer-data-bucket/"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Writes are audited everywhere. Reads are audited only on the handful of buckets where access itself is sensitive. Full coverage where it matters, at a fraction of the cost.&lt;/p&gt;

&lt;p&gt;At org scale, tag sensitive buckets (&lt;code&gt;security-scan: enabled&lt;/code&gt;) and use that tag to drive both CloudTrail scoping and security scanner configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3 — Make Sure It Can't Creep Again
&lt;/h3&gt;

&lt;p&gt;The original problem wasn't the spend — it was that nobody saw it grow. Set an AWS Budget or Cost Anomaly Detection monitor on the CloudTrail service so a slow climb gets flagged before it becomes a six-figure number.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Lesson
&lt;/h2&gt;

&lt;p&gt;The security tool wasn't the problem. Neither was the engineer who set it up. The problem was a CloudTrail default — log every read and every write on every bucket — accepted as part of a setup checklist without anyone asking what it would cost.&lt;/p&gt;

&lt;p&gt;Read logging is valuable on buckets that hold customer data, PII, or credentials. On everything else, it's billions of events nobody will ever look at.&lt;/p&gt;

&lt;p&gt;When a new tool asks you to enable CloudTrail data events as part of its setup, check what the default actually covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read, write, or both? Writes are usually enough.&lt;/li&gt;
&lt;li&gt;All buckets, or only the ones that hold sensitive data?&lt;/li&gt;
&lt;li&gt;What does that cost at your request volume? At $0.10 per 100,000 events, a busy bucket adds up fast.&lt;/li&gt;
&lt;li&gt;Who owns the monthly bill for this tool's footprint?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Security and FinOps need to be in the same conversation when a new tool lands.&lt;/p&gt;

&lt;p&gt;Not because security is the enemy of cost — but because the most expensive line on your bill might be a default checkbox a well-intentioned engineer left ticked during a tool rollout.&lt;/p&gt;

&lt;p&gt;The config that cost $1,000 a month in 2024 cost $30,000 a month in 2025. Our traffic scaled. The default didn't care.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>finops</category>
      <category>security</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
