<?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: Ace7-coder</title>
    <description>The latest articles on DEV Community by Ace7-coder (@ace7coder).</description>
    <link>https://dev.to/ace7coder</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%2F4160122%2F50c05eb0-5732-4cdc-ac31-07f859bf08c2.png</url>
      <title>DEV Community: Ace7-coder</title>
      <link>https://dev.to/ace7coder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ace7coder"/>
    <language>en</language>
    <item>
      <title>AWS FinOps Field Notes (2026-11-01): Automated Infrastructure Auditing with Python</title>
      <dc:creator>Ace7-coder</dc:creator>
      <pubDate>Sun, 01 Nov 2026 18:52:27 +0000</pubDate>
      <link>https://dev.to/ace7coder/aws-finops-field-notes-2026-11-01-automated-infrastructure-auditing-with-python-2cp</link>
      <guid>https://dev.to/ace7coder/aws-finops-field-notes-2026-11-01-automated-infrastructure-auditing-with-python-2cp</guid>
      <description>&lt;p&gt;While auditing cloud infrastructure costs this week, recurring configuration gaps continue to quietly inflate monthly cloud bills.&lt;/p&gt;

&lt;h3&gt;
  
  
  Field Insight: The Hidden Cost Trap
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Cloud Community&lt;/strong&gt;: "﻿# Staged Community Leads"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When managed resources drift out of standard support windows or detached storage components persist after instance terminations, infrastructure spend spikes without any increase in user traffic or compute demand.&lt;/p&gt;




&lt;h3&gt;
  
  
  Automated Infrastructure Audit Execution
&lt;/h3&gt;

&lt;p&gt;Rather than relying on manual console spot-checks across multiple AWS regions, you can automate inspection using a lightweight Python script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;quick_audit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Running multi-service FinOps scan...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Collects unattached storage and idle compute instances
&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;quick_audit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Continuous Multi-Account Governance
&lt;/h3&gt;

&lt;p&gt;Running one-off audit scripts in single regions does not scale across enterprise AWS Organizations. Sustained cloud cost management requires cross-account role assumption (&lt;code&gt;sts:AssumeRole&lt;/code&gt;), cost anomaly correlation, and automated scheduled auditing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👉 &lt;strong&gt;Download the free open-source CLI on GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Ace7-coder/aws-finops-auditor-lite" rel="noopener noreferrer"&gt;aws-finops-auditor-lite&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👉 &lt;strong&gt;Need multi-account AWS Organization (&lt;code&gt;sts:AssumeRole&lt;/code&gt;) scanning and automated CI/CD schedules?&lt;/strong&gt;
&lt;strong&gt;&lt;a href="https://aisser.gumroad.com/l/krgac" rel="noopener noreferrer"&gt;Get the Enterprise AWS FinOps Auditor ($99 one-time)&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>finops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>AWS FinOps Field Notes (2026-11-01): Auditing RDS Extended Support Charges with Python</title>
      <dc:creator>Ace7-coder</dc:creator>
      <pubDate>Sun, 01 Nov 2026 15:16:14 +0000</pubDate>
      <link>https://dev.to/ace7coder/aws-finops-field-notes-2026-11-01-auditing-rds-extended-support-charges-with-python-379a</link>
      <guid>https://dev.to/ace7coder/aws-finops-field-notes-2026-11-01-auditing-rds-extended-support-charges-with-python-379a</guid>
      <description>&lt;p&gt;While auditing cloud infrastructure costs this week, recurring configuration gaps continue to quietly inflate monthly cloud bills.&lt;/p&gt;

&lt;h3&gt;
  
  
  Field Insight: The Hidden Cost Trap
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Antonio Augusto Maguelniski&lt;/strong&gt;: "A client who asked him to halve their AWS bill saw it double from February to March 2025 with no new resources, because the RDS line jumped from about $30 to about $330/month when two PostgreSQL 12 databases left standard support."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When managed resources drift out of standard support windows or detached storage components persist after instance terminations, infrastructure spend spikes without any increase in user traffic or compute demand.&lt;/p&gt;




&lt;h3&gt;
  
  
  Auditing Outdated RDS Engine Versions with Boto3
&lt;/h3&gt;

&lt;p&gt;Rather than relying on manual console spot-checks across multiple AWS regions, you can automate inspection using a lightweight Python script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;audit_rds_engine_versions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;rds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rds&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;instances&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe_db_instances&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DBInstances&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

    &lt;span class="c1"&gt;# PostgreSQL &amp;lt;= 12 and MySQL &amp;lt;= 5.7 incur AWS Extended Support charges
&lt;/span&gt;    &lt;span class="n"&gt;eol_engines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;12.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mysql&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;5.7&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;flagged&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;db_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DBInstanceIdentifier&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Engine&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;version_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;EngineVersion&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;version_str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;major_ver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;eol_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_ver&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;eol_engines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;eol_key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;major_ver&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;max_ver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;flagged&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DBInstance&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;db_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Engine&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Version&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;version_str&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[ALERT] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;db_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;version_str&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;) is past standard support! Extended Support fees apply.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;flagged&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;audit_rds_engine_versions&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Continuous Multi-Account Governance
&lt;/h3&gt;

&lt;p&gt;Running one-off audit scripts in single regions does not scale across enterprise AWS Organizations. Sustained cloud cost management requires cross-account role assumption (&lt;code&gt;sts:AssumeRole&lt;/code&gt;), cost anomaly correlation, and automated scheduled auditing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;👉 &lt;strong&gt;Download the free open-source CLI on GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Ace7-coder/aws-finops-auditor-lite" rel="noopener noreferrer"&gt;aws-finops-auditor-lite&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;👉 &lt;strong&gt;Need multi-account AWS Organization (&lt;code&gt;sts:AssumeRole&lt;/code&gt;) scanning and automated CI/CD schedules?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://aisser.gumroad.com/l/krgac" rel="noopener noreferrer"&gt;Get the Enterprise AWS FinOps Auditor ($99 one-time)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>finops</category>
      <category>database</category>
    </item>
    <item>
      <title>Preventing Post-Termination EBS Waste: Automated Ownership Reports with Python &amp; AWS Lambda</title>
      <dc:creator>Ace7-coder</dc:creator>
      <pubDate>Sun, 01 Nov 2026 11:52:09 +0000</pubDate>
      <link>https://dev.to/ace7coder/preventing-post-termination-ebs-waste-automated-ownership-reports-with-python-aws-lambda-1clf</link>
      <guid>https://dev.to/ace7coder/preventing-post-termination-ebs-waste-automated-ownership-reports-with-python-aws-lambda-1clf</guid>
      <description>&lt;p&gt;When EC2 instances are terminated across large AWS fleets, associated EBS volumes often survive in an unattached &lt;code&gt;available&lt;/code&gt; state if &lt;code&gt;DeleteOnTermination&lt;/code&gt; was not explicitly configured on every block device. Left unmonitored, hundreds of orphaned gigabytes continue accruing charges month after month.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Governance Problem: Why Scripts Fail Without Ownership
&lt;/h3&gt;

&lt;p&gt;As cloud engineer Aman Maheshwari noted, in environments with hundreds of instances, automated scripts that blindly delete unattached volumes create operational risk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Missing Context:&lt;/strong&gt; A detached volume might contain critical database state, debugging dumps, or compliance archives waiting on sign-off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Solution:&lt;/strong&gt; A two-tier governance model—generate automated reporting with resource owner tags, send notification digests (via SNS/Slack), and enforce a grace period before snapshotting and purging.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Auditing &amp;amp; Reporting Detached Volumes with Boto3
&lt;/h3&gt;

&lt;p&gt;Here is an automated audit pattern using &lt;code&gt;boto3&lt;/code&gt; that queries unattached volumes, resolves owner tags, and formats the findings for reporting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;audit_orphaned_ebs_with_tags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ec2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ec2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Query unattached volumes
&lt;/span&gt;    &lt;span class="n"&gt;volumes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe_volumes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Filters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Values&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;available&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}]&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Volumes&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

    &lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;vol_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VolumeId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Size&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Tags&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])}&lt;/span&gt;
        &lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Owner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CreatedBy&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Unassigned&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VolumeId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vol_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SizeGB&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Owner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CreateTime&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CreateTime&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enterprise Multi-Account Governance
&lt;/h3&gt;

&lt;p&gt;Running isolated scripts per region or single account does not scale across enterprise AWS Organizations. Real-world FinOps requires role assumption across organizational units, cost anomaly correlation, and automated scheduled auditing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👉 &lt;strong&gt;Download the free open-source CLI on GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Ace7-coder/aws-finops-auditor-lite" rel="noopener noreferrer"&gt;aws-finops-auditor-lite&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👉 &lt;strong&gt;Need automated multi-account scanning (&lt;code&gt;sts:AssumeRole&lt;/code&gt;) and production CI/CD pipelines?&lt;/strong&gt;
&lt;strong&gt;&lt;a href="https://aisser.gumroad.com/l/krgac" rel="noopener noreferrer"&gt;Get the Enterprise AWS FinOps Auditor ($99 one-time)&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>finops</category>
      <category>lambda</category>
    </item>
    <item>
      <title>AWS FinOps Field Notes (2026-10-31): Automating Orphaned EBS &amp; EC2 Cleanup</title>
      <dc:creator>Ace7-coder</dc:creator>
      <pubDate>Sat, 31 Oct 2026 18:12:10 +0000</pubDate>
      <link>https://dev.to/ace7coder/aws-finops-field-notes-2026-10-31-automating-orphaned-ebs-ec2-cleanup-1i5e</link>
      <guid>https://dev.to/ace7coder/aws-finops-field-notes-2026-10-31-automating-orphaned-ebs-ec2-cleanup-1i5e</guid>
      <description>&lt;p&gt;While reviewing real-world cloud cost audits this week, the same infrastructure leak kept surfacing across multiple engineering teams: unattached EBS volumes and idle resources quietly inflating the monthly bill.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where the Waste Hides
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Silent Accumulation:&lt;/strong&gt; As Tim O'Brien recently highlighted, fifty abandoned 100 GB unattached EBS volumes cost roughly $500/month ($6,000/year). Clearing out forgotten storage isn't just a one-off cleanup—it requires continuous ownership tracking because unattached volumes persist indefinitely unless removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orphaned Post-Termination Storage:&lt;/strong&gt; Aman Maheshwari pointed out that in environments running hundreds of EC2 instances, attached EBS volumes often survive instance termination (if &lt;code&gt;DeleteOnTermination&lt;/code&gt; was unset) and continue billing unnoticed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Extended Support Trap:&lt;/strong&gt; Antonio Augusto Maguelniski shared a case where a client's AWS bill doubled without any new deployments—their RDS costs surged from $30 to $330/month simply because two PostgreSQL 12 instances slipped out of standard support into AWS Extended Support.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Auditing Unattached Volumes with Python &amp;amp; Boto3
&lt;/h3&gt;

&lt;p&gt;Instead of manually clicking through region tabs in the AWS Console, you can query for detached volumes in &lt;code&gt;available&lt;/code&gt; state across your infrastructure with a simple Boto3 inspection script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;audit_unattached_ebs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ec2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ec2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Query volumes that are not attached to any running instance
&lt;/span&gt;    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe_volumes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Filters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Values&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;available&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;orphaned_volumes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Volumes&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] Found &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orphaned_volumes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; unattached EBS volume(s):&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;total_wasted_gb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;orphaned_volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;vol_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VolumeId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Size&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;vol_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;VolumeType&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;total_wasted_gb&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vol_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; | &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; GiB (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vol_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;) | Created: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vol&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CreateTime&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Total unattached storage: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;total_wasted_gb&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; GiB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;audit_unattached_ebs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Continuous FinOps Automation&lt;br&gt;
Manually deleting disks risks wiping data that still needs an owner review, while leaving them alone guarantees continuous waste. Automated governance requires regular multi-account audits and programmatic reporting before executing snapshots or deletions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👉 &lt;strong&gt;Grab the free open-source CLI on GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Ace7-coder/aws-finops-auditor-lite" rel="noopener noreferrer"&gt;aws-finops-auditor-lite&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👉 &lt;strong&gt;Need multi-account AWS Organization (&lt;code&gt;sts:AssumeRole&lt;/code&gt;) scanning and automated CI/CD schedules?&lt;/strong&gt;
&lt;strong&gt;&lt;a href="https://aisser.gumroad.com/l/krgac" rel="noopener noreferrer"&gt;Get the Enterprise AWS FinOps Auditor ($99 one-time)&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>finops</category>
      <category>devops</category>
    </item>
    <item>
      <title>How I Built a Strict SOC2 Compliance Gate in Jira using Atlassian Forge &amp; KVS</title>
      <dc:creator>Ace7-coder</dc:creator>
      <pubDate>Sun, 18 Oct 2026 21:34:18 +0000</pubDate>
      <link>https://dev.to/ace7coder/how-i-built-a-strict-soc2-compliance-gate-in-jira-using-atlassian-forge-kvs-2mbo</link>
      <guid>https://dev.to/ace7coder/how-i-built-a-strict-soc2-compliance-gate-in-jira-using-atlassian-forge-kvs-2mbo</guid>
      <description>&lt;p&gt;If you've ever gone through a SOC2 audit, you know the drill. Auditors want proof that every piece of code deployed to production went through a peer review, passed a security scan, and had a documented rollback plan.&lt;/p&gt;

&lt;p&gt;Usually, this means scrambling to pull Jira histories, cross-referencing GitHub PRs, and hoping nobody bypassed the rules. I wanted to eliminate the manual scramble and enforce these checks at the workflow level, so I built a strict compliance gate using Atlassian Forge.&lt;/p&gt;

&lt;p&gt;Here is a breakdown of how I designed the architecture to enforce compliance and generate immutable audit logs without ever letting data leave the Atlassian cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;I chose Atlassian Forge (Node.js 24 runtime) because of its "Runs on Atlassian" security model. For compliance tools, data residency is critical.&lt;/p&gt;

&lt;p&gt;The app consists of three main components:&lt;/p&gt;

&lt;p&gt;The UI Kit Issue Panel: Built with &lt;a class="mentioned-user" href="https://dev.to/forge"&gt;@forge&lt;/a&gt;/react, this injects a checklist directly into the Jira ticket. It forces the assignee to explicitly check off the required gates (PR Approved, Sec Scan Passed, QA Verified).&lt;/p&gt;

&lt;p&gt;The Immutable Ledger (&lt;a class="mentioned-user" href="https://dev.to/forge"&gt;@forge&lt;/a&gt;/kvs): When a user clicks "Sign Off &amp;amp; Save Evidence," the app writes the compliance state to Jira's Key-Value Store. Crucially, it captures the user's exact Atlassian Account ID and a precise timestamp.&lt;/p&gt;

&lt;p&gt;The Audit Exporter Dashboard: A global admin page that queries the KVS database, resolves the internal issue IDs via the Jira REST API, and aggregates every verified ticket into a clean, copyable CSV format for the auditor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enforcing the Rules
&lt;/h2&gt;

&lt;p&gt;The UI panel is great for visibility, but the real power is the backend validator. I hooked into Jira's workflow transition triggers. If someone tries to drag a ticket to "Done" without the KVS ledger showing a fully compliant state, the Forge app intercepts the transition and blocks it entirely. No sign-off, no deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;Instead of manually hunting for evidence at the end of the quarter, the audit trail builds itself in real-time. When the auditors come knocking, I just open the Exporter dashboard, click a button, and hand over the CSV.&lt;/p&gt;

&lt;p&gt;I've packaged the complete source code and a 1-click installation link for teams that want to implement this in their own workspaces. You can grab the full bundle here: &lt;a href="https://aisser.gumroad.com/l/jira-soc2" rel="noopener noreferrer"&gt;https://aisser.gumroad.com/l/jira-soc2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>jira</category>
      <category>devops</category>
      <category>atlassian</category>
    </item>
    <item>
      <title>Why AWS Cost Forecasts Fail: Cleaning Up Orphaned EBS and Idle EC2 Before Buying Savings Plans</title>
      <dc:creator>Ace7-coder</dc:creator>
      <pubDate>Thu, 15 Oct 2026 21:10:01 +0000</pubDate>
      <link>https://dev.to/ace7coder/why-aws-cost-forecasts-fail-cleaning-up-orphaned-ebs-and-idle-ec2-before-buying-savings-plans-4cn9</link>
      <guid>https://dev.to/ace7coder/why-aws-cost-forecasts-fail-cleaning-up-orphaned-ebs-and-idle-ec2-before-buying-savings-plans-4cn9</guid>
      <description>&lt;p&gt;Three questions keep coming up among cloud engineers and FinOps practitioners right now:&lt;/p&gt;

&lt;p&gt;Why do our cloud cost forecasts keep missing the mark?&lt;br&gt;
​2. Why does block storage feel like the one line item nobody owns?&lt;/p&gt;

&lt;p&gt;How can we confidently lock into 1-year or 3-year RIs and Savings Plans when our architecture is moving this fast?&lt;/p&gt;

&lt;p&gt;All three problems share the same root cause: infrastructure state drift.&lt;/p&gt;

&lt;p&gt;When engineering teams deploy a new feature or scale down a service, compute instances get terminated and noticed right away. Storage and auxiliary resources do not work that way. Unattached EBS volumes, forgotten snapshots, and idle dev instances outlive the services that created them. Because nobody's engineering scorecard measures orphaned disk cleanup, that silent waste gets baked into your "baseline" spend.&lt;/p&gt;

&lt;p&gt;Worse yet, if you size your AWS Compute Savings Plans or Reserved Instances against a bloated baseline, you end up locking in wasted capacity for the next 12 to 36 months.&lt;/p&gt;

&lt;p&gt;Why Native Dashboards Don't Solve the Ownership Gap&lt;br&gt;
Every FinOps dashboard and Cost Explorer view can show you a 15% spend spike after the bill lands. The problem isn't visibility. The problem is that acting on a dashboard still requires an engineer to click across a dozen AWS accounts, verify whether an available EBS volume has had any I/O activity, and manually write cleanup commands.&lt;/p&gt;

&lt;p&gt;To fix this before committing to Savings Plans or trusting a monthly forecast, I stopped relying on passive billing dashboards and started treating raw AWS infrastructure state like a Python and Pandas data pipeline.&lt;/p&gt;

&lt;p&gt;Auditing Raw AWS State with Python and Pandas&lt;br&gt;
Using my open-source CLI (aws-finops-auditor-lite), we pull the live environment state via boto3 directly into a Pandas DataFrame to isolate three high-leakage culprits across accounts:&lt;/p&gt;

&lt;p&gt;Orphaned EBS Storage: Filtering for volumes sitting in an available (unattached) state with 0% I/O over 30 days.&lt;br&gt;
​2. Idle EC2 Compute: Identifying running instances flatlining on CPU and network utilization before they inflate your Savings Plan commitment calculations.&lt;/p&gt;

&lt;p&gt;Unencrypted S3 Buckets: Catching storage compliance drift alongside cost anomalies in the same pass.&lt;/p&gt;

&lt;p&gt;Review-First Remediation (No Blind Deletions)&lt;br&gt;
Automatically firing destructive boto3 calls in production is a recipe for an outage. Instead of deleting resources blindly, passing the --remediate flag outputs a human-readable, executable bash script (remediate_anomalies.sh) alongside a clean Markdown waste report:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# --- Unattached EBS Volumes (0% I/O &amp;gt; 30 Days) ---&lt;/span&gt;
&lt;span class="c"&gt;# Account: 111122223333&lt;/span&gt;
aws ec2 delete-volume &lt;span class="nt"&gt;--volume-id&lt;/span&gt; vol-0123456789abcdef0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scale It Across Your AWS Organization (or Try the Open-Source CLI)&lt;br&gt;
Want to automate this across your entire AWS Organization by Friday? The Enterprise Tier handles the heavy lifting out of the box with a multi-account sts:AssumeRole scanning engine, an automated Friday morning GitHub Actions CI/CD schedule, and automated bash remediation script generators.&lt;br&gt;
👉 Grab the Enterprise FinOps Auditor template here ($99 one-time): &lt;a href="https://aisser.gumroad.com/l/krgac" rel="noopener noreferrer"&gt;https://aisser.gumroad.com/l/krgac&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just looking to run a manual scan on a single account? You can fork the Lite CLI for free on GitHub:&lt;br&gt;
👉 GitHub Repo (Lite CLI): &lt;a href="https://github.com/Ace7-coder/aws-finops-auditor-lite" rel="noopener noreferrer"&gt;https://github.com/Ace7-coder/aws-finops-auditor-lite&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How is your team currently cleaning up unowned EBS storage before locking in Savings Plans? Drop your workflow in the comments!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>finops</category>
      <category>devops</category>
    </item>
    <item>
      <title>Stop manually deleting EBS volumes: Building an open-source AWS Auditor in Python.</title>
      <dc:creator>Ace7-coder</dc:creator>
      <pubDate>Sat, 03 Oct 2026 16:37:24 +0000</pubDate>
      <link>https://dev.to/ace7coder/-stop-manually-deleting-ebs-volumes-building-an-open-source-aws-auditor-in-python-1hfg</link>
      <guid>https://dev.to/ace7coder/-stop-manually-deleting-ebs-volumes-building-an-open-source-aws-auditor-in-python-1hfg</guid>
      <description>&lt;p&gt;If you manage cloud infrastructure at scale, you already know the Friday afternoon drill. Finance pings you about a 15% spike in the AWS bill, and suddenly you are spending your weekend clicking through the Cost Explorer, hunting down unattached EBS volumes, idle EC2 instances, and unencrypted S3 buckets across a dozen different accounts.&lt;/p&gt;

&lt;p&gt;AWS provides native tools for this, but they often lack the programmable, deeply customizable data manipulation that a pure Python and Pandas pipeline provides. I realized that manually tracking down these orphaned resources was burning valuable engineering hours that should have been spent building.&lt;/p&gt;

&lt;p&gt;So, I built aws-finops-auditor.&lt;/p&gt;

&lt;p&gt;It is an open-source, CLI-driven tool that uses boto3 to pull your raw infrastructure data and Pandas to normalize, analyze, and aggregate it into a clean, actionable markdown report. No more console clicking—just a single terminal command that spits out exactly where you are wasting money and failing security checks.&lt;/p&gt;

&lt;p&gt;Technical Deep Dive: Treating Infrastructure as Data&lt;br&gt;
Most AWS scripts just blind-fire boto3 commands. But when you are dealing with production infrastructure, you need strict review processes before executing destructive actions. Applying principles from data analytics, I designed aws-finops-auditor to treat cloud infrastructure as a data pipeline.&lt;/p&gt;

&lt;p&gt;First, it pulls the raw AWS environment state into a Pandas DataFrame. This allows for complex filtering—like isolating EBS volumes that have an 'available' state and 0% I/O over 30 days—in just two lines of vectorized code, rather than writing brittle, deeply nested loops.&lt;/p&gt;

&lt;p&gt;Then comes the remediation generator. Instead of automatically deleting resources, passing the --remediate flag dynamically writes a targeted, executable bash script (remediate_anomalies.sh).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# --- Unattached EBS Volumes ---&lt;/span&gt;
&lt;span class="c"&gt;# Account: 111122223333&lt;/span&gt;
aws ec2 delete-volume &lt;span class="nt"&gt;--volume-id&lt;/span&gt; vol-0123456789abcdef0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scale It Across Your AWS Organization (or Try the Open-Source CLI)&lt;br&gt;
If you are an engineering manager or lead who needs to scale this across an entire AWS Organization, I packaged the Enterprise Tier to solve that exact problem. It includes the multi-account STS scanning engine, the automated Friday morning GitHub Actions CI/CD schedule, and the automated bash remediation generator.&lt;br&gt;
👉 Get lifetime access to the Enterprise package for a one-time $99 fee here: &lt;a href="https://aisser.gumroad.com/l/krgac" rel="noopener noreferrer"&gt;https://aisser.gumroad.com/l/krgac&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just looking to run a manual scan on a single account? The core CLI is completely open-source. I would love for you to run it against your own AWS environment and let me know how much idle waste it finds. You can grab the code and star the repository here:&lt;br&gt;
👉 GitHub Repo (Lite CLI): &lt;a href="https://github.com/Ace7-coder/aws-finops-auditor-lite" rel="noopener noreferrer"&gt;https://github.com/Ace7-coder/aws-finops-auditor-lite&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is the most frustrating part of managing your cloud infrastructure costs? Let me know in the comments below!&lt;/p&gt;

</description>
      <category>automation</category>
      <category>aws</category>
      <category>devops</category>
      <category>python</category>
    </item>
  </channel>
</rss>
