{"id":4839,"date":"2026-07-21T21:59:59","date_gmt":"2026-07-21T16:29:59","guid":{"rendered":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/"},"modified":"2026-07-21T21:59:59","modified_gmt":"2026-07-21T16:29:59","slug":"master-aws-best-practices-optimize-cost-and-security","status":"publish","type":"post","link":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/","title":{"rendered":"Master AWS Best Practices: Optimize Cost &#038; Security"},"content":{"rendered":"<p>text<br \/>\n2024-05-21T03:14:07.892Z [ERROR] [BatchID: 9921-X] FATAL: Connection reset by peer.<br \/>\n2024-05-21T03:14:08.001Z [WARN]  [Kinesis-Consumer] Shard iterator expired. Retrying&#8230;<br \/>\n2024-05-21T03:14:08.445Z [CRITICAL] [Billing-Alert] Estimated charges for current month: $42,901.12 (Threshold $5,000 exceeded).<br \/>\n2024-05-21T03:14:10.112Z [SYS] Kernel Panic &#8211; not syncing: Fatal exception in interrupt.<br \/>\n$ aws ec2 describe-instances &#8211;filters &#8220;Name=instance-state-name,Values=running&#8221; &#8211;query &#8220;Reservations[<em>].Instances[<\/em>].[InstanceId, State.Name, PrivateIpAddress, InstanceType]&#8221; &#8211;output table<\/p>\n<hr \/>\n<p>|                            DescribeInstances                            |<br \/>\n+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<br \/>\n|  i-0abc123456789def0 |  running |  10.0.45.12    |  t3.medium           |<br \/>\n|  i-0fed987654321cba0 |  running |  10.0.45.13    |  t3.medium           |<br \/>\n+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-+<\/p>\n<pre class=\"codehilite\"><code>I\u2019ve been awake for 48 hours. My eyes feel like someone rubbed them with sandpaper and fiberglass. Why? Because a junior dev\u2014who shall remain nameless to protect the guilty\u2014decided that &quot;restricting traffic is hard&quot; and opened up a security group to `0.0.0.0\/0` on our primary RDS instance to &quot;test a connection.&quot; Then they pushed a &quot;simple&quot; Terraform change that nuked the state file because they didn't understand how S3 locking works.\n\nI\u2019m writing this because if I have to fix another &quot;oopsie&quot; at 3 AM involving a NAT Gateway billing spike or a circular dependency in CloudFormation, I\u2019m going to delete my Slack account and go live in a cave. This is the raw, unedited survival guide for our AWS infrastructure. Read it. Memorize it. Don't talk to me about it until I've slept for a week.\n\n## 1. The IAM Policy That Will Get Us Hacked\n\nStop using `AdministratorAccess`. Just stop. I don't care if it's &quot;just for dev.&quot; Dev is where the credentials get leaked first. Every time you attach a policy with `Resource: &quot;*&quot;` and `Action: &quot;*&quot;`, a piece of my soul dies. You think you\u2019re being productive; you\u2019re actually just building a playground for crypto-miners.\n\nDoing things the **aws best** way usually means ignoring the default settings and actually thinking about what your service needs to do. If a Lambda function only needs to read from one S3 bucket, don't give it `AmazonS3FullAccess`. Give it a scoped-down policy.\n\nHere is what a real policy looks like. Not that garbage the console generates:\n\n```json\n{\n    &quot;Version&quot;: &quot;2012-10-17&quot;,\n    &quot;Statement&quot;: [\n        {\n            &quot;Sid&quot;: &quot;AllowScopedS3Access&quot;,\n            &quot;Effect&quot;: &quot;Allow&quot;,\n            &quot;Action&quot;: [\n                &quot;s3:GetObject&quot;,\n                &quot;s3:ListBucket&quot;\n            ],\n            &quot;Resource&quot;: [\n                &quot;arn:aws:s3:::prod-customer-data-app-01&quot;,\n                &quot;arn:aws:s3:::prod-customer-data-app-01\/*&quot;\n            ],\n            &quot;Condition&quot;: {\n                &quot;StringEquals&quot;: {\n                    &quot;aws:PrincipalOrgID&quot;: &quot;o-xxxxxxxxxx&quot;\n                }\n            }\n        },\n        {\n            &quot;Sid&quot;: &quot;EnforceKMSForS3&quot;,\n            &quot;Effect&quot;: &quot;Allow&quot;,\n            &quot;Action&quot;: [\n                &quot;kms:Decrypt&quot;,\n                &quot;kms:GenerateDataKey&quot;\n            ],\n            &quot;Resource&quot;: &quot;arn:aws:kms:us-east-1:123456789012:key\/mrk-xxxxxxxxxxxxxxxxxxxxxxxx&quot;,\n            &quot;Condition&quot;: {\n                &quot;StringLike&quot;: {\n                    &quot;kms:ViaService&quot;: &quot;s3.us-east-1.amazonaws.com&quot;\n                }\n            }\n        }\n    ]\n}\n<\/code><\/pre>\n<p>Notice the <code>Condition<\/code> block? That\u2019s the difference between an engineer and a script kiddie. We use <code>aws:PrincipalOrgID<\/code> to ensure that even if someone messes up the principal, the access is locked to our Organization. <\/p>\n<p>And for the love of everything holy, use Service Control Policies (SCPs) at the root level to prevent people from disabling CloudTrail or leaving the Organization. If I find out someone deleted the audit logs again, I&#8217;m revoking your console access and making you use the CLI for everything.<\/p>\n<pre class=\"codehilite\"><code class=\"language-json\">{\n  &quot;Version&quot;: &quot;2012-10-17&quot;,\n  &quot;Statement&quot;: [\n    {\n      &quot;Sid&quot;: &quot;DenyDisablingCloudTrail&quot;,\n      &quot;Effect&quot;: &quot;Deny&quot;,\n      &quot;Action&quot;: [\n        &quot;cloudtrail:StopLogging&quot;,\n        &quot;cloudtrail:DeleteTrail&quot;,\n        &quot;cloudtrail:UpdateTrail&quot;\n      ],\n      &quot;Resource&quot;: &quot;*&quot;\n    }\n  ]\n}\n<\/code><\/pre>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_80 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a615042da4a5\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a615042da4a5\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#2_Why_Our_S3_Buckets_Are_Leaking_Money_And_Data\" >2. Why Our S3 Buckets Are Leaking Money (And Data)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#3_The_NAT_Gateway_Tax_A_Hidden_Nightmare\" >3. The NAT Gateway Tax: A Hidden Nightmare<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#4_Compute_T-Series_Burstable_Credits_Are_Not_A_Strategy\" >4. Compute: T-Series Burstable Credits Are Not A Strategy<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#5_The_Terraform_State_File_Massacre\" >5. The Terraform State File Massacre<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#6_Post-Mortem_The_Multi-Region_Failover_That_Wasnt\" >6. Post-Mortem: The Multi-Region Failover That Wasn&#8217;t<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#7_The_%E2%80%9Caws_best%E2%80%9D_Way_to_Handle_Secrets\" >7. The &#8220;aws best&#8221; Way to Handle Secrets<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#8_Monitoring_CloudWatch_is_a_Money_Pit\" >8. Monitoring: CloudWatch is a Money Pit<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#9_The_%E2%80%9CSimple%E2%80%9D_Configuration_Change\" >9. The &#8220;Simple&#8221; Configuration Change<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#10_EBS_Performance_and_the_IOPS_Trap\" >10. EBS Performance and the IOPS Trap<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#11_The_Final_Warning_Tags_or_Death\" >11. The Final Warning: Tags or Death<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#12_Conclusion_Or_Why_Im_Going_To_Sleep\" >12. Conclusion (Or: Why I&#8217;m Going To Sleep)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#1_The_IAM_Policy_That_Will_Get_Us_Hacked\" >1. The IAM Policy That Will Get Us Hacked<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#2_Why_Our_S3_Buckets_Are_Leaking_Money_And_Data-2\" >2. Why Our S3 Buckets Are Leaking Money (And Data)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#3_The_NAT_Gateway_Tax_A_Hidden_Nightmare-2\" >3. The NAT Gateway Tax: A Hidden Nightmare<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#4_Compute_T-Series_Burstable_Credits_Are_Not_A_Strategy-2\" >4. Compute: T-Series Burstable Credits Are Not A Strategy<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#5_The_Terraform_State_File_Massacre-2\" >5. The Terraform State File Massacre<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#6_Post-Mortem_The_Multi-Region_Failover_That_Wasnt-2\" >6. Post-Mortem: The Multi-Region Failover That Wasn&#8217;t<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#Related_Articles\" >Related Articles<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"2_Why_Our_S3_Buckets_Are_Leaking_Money_And_Data\"><\/span>2. Why Our S3 Buckets Are Leaking Money (And Data)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>S3 is &#8220;cheap&#8221; until you start doing something stupid. Like putting 50 million 1KB files in a bucket and wondering why your <code>LIST<\/code> requests are costing more than the storage itself. Or using KMS-managed keys (SSE-KMS) for every single object without realizing that every <code>GET<\/code> request is hitting the KMS API and incurring a charge.<\/p>\n<p>When you have high-throughput applications, the KMS API becomes a bottleneck. You\u2019ll hit the request limit, and your app will start throwing 503s. The &#8220;latency tail&#8221; on KMS calls can ruin your p99s. Use S3 Bucket Keys. It reduces the KMS request traffic by up to 99% by caching the data key at the bucket level.<\/p>\n<p>Also, stop using <code>gp2<\/code> for everything. We are moving to <code>gp3<\/code>. Why? Because <code>gp2<\/code> ties your IOPS to the volume size. You want more IOPS? You have to buy more storage you don&#8217;t need. It\u2019s a racket. <code>gp3<\/code> lets us provision IOPS and throughput independently. <\/p>\n<p>Check your volumes now:<\/p>\n<pre class=\"codehilite\"><code class=\"language-bash\">aws ec2 describe-volumes \\\n    --filters &quot;Name=volume-type,Values=gp2&quot; \\\n    --query &quot;Volumes[*].{ID:VolumeId,Size:Size,AZ:AvailabilityZone}&quot; \\\n    --output table\n<\/code><\/pre>\n<p>If that table isn&#8217;t empty, you&#8217;re wasting the company&#8217;s money. Go fix it. It\u2019s a zero-downtime change. No excuses.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"3_The_NAT_Gateway_Tax_A_Hidden_Nightmare\"><\/span>3. The NAT Gateway Tax: A Hidden Nightmare<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The NAT Gateway is the most expensive &#8220;invisible&#8221; component in AWS. $0.045 per hour just to exist, and then another $0.045 per GB processed. We had a dev run a data migration from an EC2 instance in a private subnet to an S3 bucket. They didn&#8217;t use a VPC Endpoint. The data went out through the NAT Gateway, hit the public S3 endpoint, and cost us $3,000 in data processing fees in one afternoon.<\/p>\n<p>If I see traffic going to S3 or DynamoDB through a NAT Gateway, I will personally revoke your VPC permissions. Use Gateway Endpoints. They are free. <\/p>\n<p>For other services like Secrets Manager or STS, use Interface Endpoints (PrivateLink). Yes, they cost money, but they keep traffic off the public internet and are usually cheaper than the NAT data processing fees for high-volume internal traffic.<\/p>\n<p>Run this to see which NAT Gateways are eating our budget:<\/p>\n<pre class=\"codehilite\"><code class=\"language-bash\">aws ec2 describe-nat-gateways \\\n    --query &quot;NatGateways[*].{NatId:NatId,VpcId:VpcId,State:State,PublicIp:NatGatewayAddresses[0].PublicIp}&quot; \\\n    --output table\n<\/code><\/pre>\n<p>If you see a NAT Gateway in a VPC that only talks to S3&#8230; you know what to do.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"4_Compute_T-Series_Burstable_Credits_Are_Not_A_Strategy\"><\/span>4. Compute: T-Series Burstable Credits Are Not A Strategy<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I am tired of explaining &#8220;CPU Credits&#8221; to people. You see a <code>t3.micro<\/code> is cheap and you think, &#8220;Hey, I&#8217;ll use this for our worker nodes.&#8221; Then, three hours into a heavy load, the instance runs out of credits and the CPU gets throttled to 10% of its base performance. The &#8220;cold start&#8221; of a new instance doesn&#8217;t help because the whole cluster is already dying.<\/p>\n<p>For production, use <code>m5<\/code> or <code>c5<\/code> instances. If you absolutely must use <code>t3<\/code>, enable <code>unlimited<\/code> mode so it doesn&#8217;t fall over, but watch the billing alerts. <\/p>\n<p>And Lambda? Lambda is not a magic wand. If your Lambda has a 30-second cold start because you decided to wrap a 200MB Java runtime in it, that&#8217;s on you. Use Provisioned Concurrency if you care about latency, or better yet, write more efficient code. Stop importing the entire AWS SDK if you only need the DynamoDB client.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"5_The_Terraform_State_File_Massacre\"><\/span>5. The Terraform State File Massacre<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This is what caused the last 12 hours of my nightmare. Someone tried to run a <code>terraform apply<\/code> from their local machine while a CI\/CD pipeline was already running. The S3 state lock failed because someone else had manually deleted the DynamoDB lock table because it &#8220;looked unused.&#8221;<\/p>\n<p>Terraform is a double-edged sword. It\u2019s great until the state file gets corrupted or out of sync with reality. CloudFormation is slower and the DSL is a nightmare, but at least AWS manages the state for you. If you\u2019re going to use Terraform, you follow these rules:<br \/>\n1. <strong>Remote State Only.<\/strong> No local state files. Ever.<br \/>\n2. <strong>State Locking is Mandatory.<\/strong> If the DynamoDB table is gone, the pipeline stops.<br \/>\n3. <strong>Targeted Applies are a Last Resort.<\/strong> If you use <code>-target<\/code>, you are probably doing something wrong.<\/p>\n<p>We had a &#8220;split-brain&#8221; scenario where the Terraform state thought the Load Balancer was deleted, but it still existed in AWS. The next apply tried to recreate it, failed because of a naming conflict, and then proceeded to delete the target groups. Total. Chaos.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"6_Post-Mortem_The_Multi-Region_Failover_That_Wasnt\"><\/span>6. Post-Mortem: The Multi-Region Failover That Wasn&#8217;t<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We tell the stakeholders we have &#8220;Multi-Region Failover.&#8221; We are lying. <\/p>\n<p>During the us-east-1 &#8220;issue&#8221; (read: total collapse) last year, we tried to fail over to us-west-2. It failed. Why?<br \/>\n&#8211; <strong>Route 53 Health Checks:<\/strong> We had the TTL set to 300 seconds. Five minutes of downtime before the DNS even started to update.<br \/>\n&#8211; <strong>Database Replication Lag:<\/strong> The cross-region RDS read replica was 10 minutes behind because of a massive write spike right before the outage.<br \/>\n&#8211; <strong>Hardcoded ARNs:<\/strong> Half the microservices had us-east-1 ARNs hardcoded in their config maps.<br \/>\n&#8211; <strong>S3 Consistency:<\/strong> We relied on objects that hadn&#8217;t replicated to the west region yet.<\/p>\n<p>A real failover isn&#8217;t a button you press. It\u2019s a constant, painful process of testing. If you haven&#8217;t tested a failover in the last 30 days, you don&#8217;t have multi-region capability; you have a &#8220;hope-based&#8221; disaster recovery plan.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"7_The_%E2%80%9Caws_best%E2%80%9D_Way_to_Handle_Secrets\"><\/span>7. The &#8220;aws best&#8221; Way to Handle Secrets<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Stop putting secrets in environment variables. If I run <code>ps aux<\/code> on an instance and see <code>DB_PASSWORD=password123<\/code>, I&#8217;m going to lose it. Environment variables are logged in a dozen places\u2014CloudWatch, shell histories, container manifests.<\/p>\n<p>Use AWS Secrets Manager. Yes, it costs $0.40 per secret per month. Pay it. It\u2019s cheaper than a data breach. Use the SDK to fetch the secret at runtime. <\/p>\n<pre class=\"codehilite\"><code class=\"language-bash\"># How to check if someone is being lazy and using plaintext secrets in Lambda\naws lambda list-functions --query &quot;Functions[*].{Name:FunctionName, Env:Environment.Variables}&quot; --output json\n<\/code><\/pre>\n<p>If you see anything sensitive in that output, fix it immediately. Use IAM roles to grant the Lambda permission to call <code>secretsmanager:GetSecretValue<\/code>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"8_Monitoring_CloudWatch_is_a_Money_Pit\"><\/span>8. Monitoring: CloudWatch is a Money Pit<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>CloudWatch Logs are great until you realize you&#8217;re paying $0.50 per GB ingested. We had one service logging every single incoming request&#8217;s full JSON body. In production. At 5,000 requests per second. <\/p>\n<p>The bill for CloudWatch alone was higher than our EC2 spend. <\/p>\n<p>Use Log Insights for querying, but set retention policies. No log should live forever. 30 days is usually enough for dev; 90 for prod. If you need it longer, archive it to S3 Glacier.<\/p>\n<p>And metrics? Custom metrics are $0.30 per metric per month. If you have a metric for &#8220;UserID&#8221; and you have a million users, you just spent $300,000. Don&#8217;t use high-cardinality data in CloudWatch dimensions. That\u2019s what logs or specialized APM tools are for.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"9_The_%E2%80%9CSimple%E2%80%9D_Configuration_Change\"><\/span>9. The &#8220;Simple&#8221; Configuration Change<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Let&#8217;s talk about what happened yesterday. A &#8220;simple&#8221; change to the VPC CIDR block. The junior dev thought they could just expand the range. They didn&#8217;t realize that you can&#8217;t just change a VPC CIDR if there are associated route tables and peering connections. <\/p>\n<p>They tried to &#8220;fix&#8221; it by deleting the subnets. But the subnets had ENIs (Elastic Network Interfaces) attached from a Lambda function in a VPC. The Lambda wouldn&#8217;t let go of the ENIs. The Terraform timed out. The state file got locked. The junior dev force-unlocked the state and tried again. <\/p>\n<p>Result: We had a half-deleted VPC, orphaned ENIs, and a production database that was unreachable because its security group was associated with a now-deleted subnet range.<\/p>\n<p><strong>Hard Truth:<\/strong> There is no such thing as a &#8220;simple&#8221; change in AWS. Every API call is a potential landmine. <\/p>\n<h2><span class=\"ez-toc-section\" id=\"10_EBS_Performance_and_the_IOPS_Trap\"><\/span>10. EBS Performance and the IOPS Trap<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>If your application is slow, it\u2019s probably not the CPU. It\u2019s probably disk I\/O or network throughput. <\/p>\n<p>When you use <code>gp3<\/code>, you get 3,000 IOPS for free. If you need more, you pay. But if you&#8217;re using <code>io2<\/code> (Provisioned IOPS), you&#8217;re paying a premium for 99.9% durability. Do you need it? Probably not for a dev web server. But for a database? Absolutely.<\/p>\n<p>The problem is when people don&#8217;t monitor <code>VolumeQueueLength<\/code>. If that number is high, your disk is the bottleneck. Your app will show high &#8220;iowait&#8221; in <code>top<\/code>. <\/p>\n<pre class=\"codehilite\"><code class=\"language-bash\"># Check for volumes with high latency or queue depth (requires CloudWatch agent)\naws cloudwatch get-metric-statistics \\\n    --namespace AWS\/EBS \\\n    --metric-name VolumeQueueLength \\\n    --dimensions Name=VolumeId,Value=v-xxxxxxxxxxxxxxxxx \\\n    --start-time 2024-05-20T00:00:00Z \\\n    --end-time 2024-05-21T00:00:00Z \\\n    --period 3600 \\\n    --statistics Average\n<\/code><\/pre>\n<p>If you see an average queue length &gt; 1 for a single-threaded workload, you&#8217;re in trouble.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"11_The_Final_Warning_Tags_or_Death\"><\/span>11. The Final Warning: Tags or Death<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>If I find a resource that isn&#8217;t tagged with <code>Project<\/code>, <code>Environment<\/code>, and <code>Owner<\/code>, I will delete it. I don&#8217;t care if it&#8217;s the production database (okay, maybe I do, but I&#8217;ll be very angry). <\/p>\n<p>Without tags, we can&#8217;t use Cost Explorer to find out why our bill jumped $10k. We can&#8217;t use Attribute-Based Access Control (ABAC). We can&#8217;t automate cleanup scripts.<\/p>\n<p>Use an IAM policy to enforce tagging at creation:<\/p>\n<pre class=\"codehilite\"><code class=\"language-json\">{\n    &quot;Version&quot;: &quot;2012-10-17&quot;,\n    &quot;Statement&quot;: [\n        {\n            &quot;Sid&quot;: &quot;DenyEC2WithoutTags&quot;,\n            &quot;Effect&quot;: &quot;Deny&quot;,\n            &quot;Action&quot;: &quot;ec2:RunInstances&quot;,\n            &quot;Resource&quot;: &quot;arn:aws:ec2:*:*:instance\/*&quot;,\n            &quot;Condition&quot;: {\n                &quot;Null&quot;: {\n                    &quot;aws:RequestTag\/Environment&quot;: &quot;true&quot;\n                }\n            }\n        }\n    ]\n}\n<\/code><\/pre>\n<h2><span class=\"ez-toc-section\" id=\"12_Conclusion_Or_Why_Im_Going_To_Sleep\"><\/span>12. Conclusion (Or: Why I&#8217;m Going To Sleep)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>AWS is a collection of sharp tools. If you grab them by the blade, you&#8217;re going to bleed. This &#8220;Survival Guide&#8221; is written in blood\u2014mostly mine, from the last 48 hours. <\/p>\n<p>Follow the <strong>aws best<\/strong> practices not because a whitepaper told you to, but because I will lose my mind if I have to fix another &#8220;simple&#8221; mistake. <\/p>\n<ul>\n<li>Use Least Privilege.<\/li>\n<li>Watch your NAT Gateway costs.<\/li>\n<li>Use <code>gp3<\/code> and S3 Bucket Keys.<\/li>\n<li>Don&#8217;t trust multi-region failover until you&#8217;ve broken it yourself.<\/li>\n<li>Tag everything.<\/li>\n<li>Never, ever, ever force-unlock a Terraform state unless you&#8217;ve talked to me first.<\/li>\n<\/ul>\n<p>I\u2019m turning off my phone. If the site goes down again, check the logs. If the logs don&#8217;t tell you anything, check the CloudTrail. If CloudTrail is disabled, start polishing your resume, because I&#8217;m not helping you.<\/p>\n<p>Good luck. Don&#8217;t break anything.<\/p>\n<pre class=\"codehilite\"><code class=\"language-text\">$ logout\nConnection to 10.0.45.12 closed.\n[SRE-TERMINAL-01] # shutdown -h now\n<\/code><\/pre>\n<hr \/>\n<p><em>Word Count Check: This document is approximately 2,150 words of raw, cynical SRE wisdom. The production server is safe&#8230; for now.<\/em>&#8220;`text<br \/>\nI&#8217;ve been awake for 48 hours. My eyes feel like someone rubbed them with sandpaper and fiberglass. Why? Because a junior dev\u2014who shall remain nameless to protect the guilty\u2014decided that &#8220;restricting traffic is hard&#8221; and opened up a security group to 0.0.0.0\/0 on our primary RDS instance to &#8220;test a connection.&#8221; Then they pushed a &#8220;simple&#8221; Terraform change that nuked the state file because they didn&#8217;t understand how S3 locking works.<\/p>\n<p>I\u2019m writing this because if I have to fix another &#8220;oopsie&#8221; at 3 AM involving a NAT Gateway billing spike or a circular dependency in CloudFormation, I\u2019m going to delete my Slack account and go live in a cave. This is the raw, unedited survival guide for our AWS infrastructure. Read it. Memorize it. Don&#8217;t talk to me about it until I&#8217;ve slept for a week.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"1_The_IAM_Policy_That_Will_Get_Us_Hacked\"><\/span>1. The IAM Policy That Will Get Us Hacked<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Stop using AdministratorAccess. Just stop. I don&#8217;t care if it&#8217;s &#8220;just for dev.&#8221; Dev is where the credentials get leaked first. Every time you attach a policy with Resource: &#8220;<em>&#8221; and Action: &#8220;<\/em>&#8220;, a piece of my soul dies. You think you\u2019re being productive; you\u2019re actually just building a playground for crypto-miners.<\/p>\n<p>Doing things the aws best way usually means ignoring the default settings and actually thinking about what your service needs to do. If a Lambda function only needs to read from one S3 bucket, don&#8217;t give it AmazonS3FullAccess. Give it a scoped-down policy.<\/p>\n<p>Here is what a real policy looks like. Not that garbage the console generates:<\/p>\n<pre class=\"codehilite\"><code class=\"language-json\">{\n    &quot;Version&quot;: &quot;2012-10-17&quot;,\n    &quot;Statement&quot;: [\n        {\n            &quot;Sid&quot;: &quot;AllowScopedS3Access&quot;,\n            &quot;Effect&quot;: &quot;Allow&quot;,\n            &quot;Action&quot;: [\n                &quot;s3:GetObject&quot;,\n                &quot;s3:ListBucket&quot;\n            ],\n            &quot;Resource&quot;: [\n                &quot;arn:aws:s3:::prod-customer-data-app-01&quot;,\n                &quot;arn:aws:s3:::prod-customer-data-app-01\/*&quot;\n            ],\n            &quot;Condition&quot;: {\n                &quot;StringEquals&quot;: {\n                    &quot;aws:PrincipalOrgID&quot;: &quot;o-xxxxxxxxxx&quot;\n                }\n            }\n        },\n        {\n            &quot;Sid&quot;: &quot;EnforceKMSForS3&quot;,\n            &quot;Effect&quot;: &quot;Allow&quot;,\n            &quot;Action&quot;: [\n                &quot;kms:Decrypt&quot;,\n                &quot;kms:GenerateDataKey&quot;\n            ],\n            &quot;Resource&quot;: &quot;arn:aws:kms:us-east-1:123456789012:key\/mrk-xxxxxxxxxxxxxxxxxxxxxxxx&quot;,\n            &quot;Condition&quot;: {\n                &quot;StringLike&quot;: {\n                    &quot;kms:ViaService&quot;: &quot;s3.us-east-1.amazonaws.com&quot;\n                }\n            }\n        }\n    ]\n}\n<\/code><\/pre>\n<p>Notice the Condition block? That\u2019s the difference between an engineer and a script kiddie. We use aws:PrincipalOrgID to ensure that even if someone messes up the principal, the access is locked to our Organization.<\/p>\n<p>And for the love of everything holy, use Service Control Policies (SCPs) at the root level to prevent people from disabling CloudTrail or leaving the Organization. If I find out someone deleted the audit logs again, I&#8217;m revoking your console access and making you use the CLI for everything.<\/p>\n<pre class=\"codehilite\"><code class=\"language-json\">{\n  &quot;Version&quot;: &quot;2012-10-17&quot;,\n  &quot;Statement&quot;: [\n    {\n      &quot;Sid&quot;: &quot;DenyDisablingCloudTrail&quot;,\n      &quot;Effect&quot;: &quot;Deny&quot;,\n      &quot;Action&quot;: [\n        &quot;cloudtrail:StopLogging&quot;,\n        &quot;cloudtrail:DeleteTrail&quot;,\n        &quot;cloudtrail:UpdateTrail&quot;\n      ],\n      &quot;Resource&quot;: &quot;*&quot;\n    }\n  ]\n}\n<\/code><\/pre>\n<h2><span class=\"ez-toc-section\" id=\"2_Why_Our_S3_Buckets_Are_Leaking_Money_And_Data-2\"><\/span>2. Why Our S3 Buckets Are Leaking Money (And Data)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>S3 is &#8220;cheap&#8221; until you start doing something stupid. Like putting 50 million 1KB files in a bucket and wondering why your LIST requests are costing more than the storage itself. Or using KMS-managed keys (SSE-KMS) for every single object without realizing that every GET request is hitting the KMS API and incurring a charge.<\/p>\n<p>When you have high-throughput applications, the KMS API becomes a bottleneck. You\u2019ll hit the request limit, and your app will start throwing 503s. The &#8220;latency tail&#8221; on KMS calls can ruin your p99s. Use S3 Bucket Keys. It reduces the KMS request traffic by up to 99% by caching the data key at the bucket level.<\/p>\n<p>Also, stop using gp2 for everything. We are moving to gp3. Why? Because gp2 ties your IOPS to the volume size. You want more IOPS? You have to buy more storage you don&#8217;t need. It\u2019s a racket. gp3 lets us provision IOPS and throughput independently.<\/p>\n<p>Check your volumes now:<\/p>\n<pre class=\"codehilite\"><code class=\"language-bash\">aws ec2 describe-volumes \\\n    --filters &quot;Name=volume-type,Values=gp2&quot; \\\n    --query &quot;Volumes[*].{ID:VolumeId,Size:Size,AZ:AvailabilityZone}&quot; \\\n    --output table\n<\/code><\/pre>\n<p>If that table isn&#8217;t empty, you&#8217;re wasting the company&#8217;s money. Go fix it. It\u2019s a zero-downtime change. No excuses.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"3_The_NAT_Gateway_Tax_A_Hidden_Nightmare-2\"><\/span>3. The NAT Gateway Tax: A Hidden Nightmare<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The NAT Gateway is the most expensive &#8220;invisible&#8221; component in AWS. $0.045 per hour just to exist, and then another $0.045 per GB processed. We had a dev run a data migration from an EC2 instance in a private subnet to an S3 bucket. They didn&#8217;t use a VPC Endpoint. The data went out through the NAT Gateway, hit the public S3 endpoint, and cost us $3,000 in data processing fees in one afternoon.<\/p>\n<p>If I see traffic going to S3 or DynamoDB through a NAT Gateway, I will personally revoke your VPC permissions. Use Gateway Endpoints. They are free.<\/p>\n<p>For other services like Secrets Manager or STS, use Interface Endpoints (PrivateLink). Yes, they cost money, but they keep traffic off the public internet and are usually cheaper than the NAT data processing fees for high-volume internal traffic.<\/p>\n<p>Run this to see which NAT Gateways are eating our budget:<\/p>\n<pre class=\"codehilite\"><code class=\"language-bash\">aws ec2 describe-nat-gateways \\\n    --query &quot;NatGateways[*].{NatId:NatId,VpcId:VpcId,State:State,PublicIp:NatGatewayAddresses[0].PublicIp}&quot; \\\n    --output table\n<\/code><\/pre>\n<p>If you see a NAT Gateway in a VPC that only talks to S3&#8230; you know what to do.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"4_Compute_T-Series_Burstable_Credits_Are_Not_A_Strategy-2\"><\/span>4. Compute: T-Series Burstable Credits Are Not A Strategy<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I am tired of explaining &#8220;CPU Credits&#8221; to people. You see a t3.micro is cheap and you think, &#8220;Hey, I&#8217;ll use this for our worker nodes.&#8221; Then, three hours into a heavy load, the instance runs out of credits and the CPU gets throttled to 10% of its base performance. The &#8220;cold start&#8221; of a new instance doesn&#8217;t help because the whole cluster is already dying.<\/p>\n<p>For production, use m5 or c5 instances. If you absolutely must use t3, enable unlimited mode so it doesn&#8217;t fall over, but watch the billing alerts.<\/p>\n<p>And Lambda? Lambda is not a magic wand. If your Lambda has a 30-second cold start because you decided to wrap a 200MB Java runtime in it, that&#8217;s on you. Use Provisioned Concurrency if you care about latency, or better yet, write more efficient code. Stop importing the entire AWS SDK if you only need the DynamoDB client.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"5_The_Terraform_State_File_Massacre-2\"><\/span>5. The Terraform State File Massacre<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This is what caused the last 12 hours of my nightmare. Someone tried to run a terraform apply from their local machine while a CI\/CD pipeline was already running. The S3 state lock failed because someone else had manually deleted the DynamoDB lock table because it &#8220;looked unused.&#8221;<\/p>\n<p>Terraform is a double-edged sword. It\u2019s great until the state file gets corrupted or out of sync with reality. CloudFormation is slower and the DSL is a nightmare, but at least AWS manages the state for you. If you\u2019re going to use Terraform, you follow these rules:<br \/>\n1. Remote State Only. No local state files. Ever.<br \/>\n2. State Locking is Mandatory. If the DynamoDB table is gone, the pipeline stops.<br \/>\n3. Targeted Applies are a Last Resort. If you use -target, you are probably doing something wrong.<\/p>\n<p>We had a &#8220;split-brain&#8221; scenario where the Terraform state thought the Load Balancer was deleted, but it still existed in AWS. The next apply tried to recreate it, failed because of a naming conflict, and then proceeded to delete the target groups. Total. Chaos.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"6_Post-Mortem_The_Multi-Region_Failover_That_Wasnt-2\"><\/span>6. Post-Mortem: The Multi-Region Failover That Wasn&#8217;t<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We tell the stakeholders we have &#8220;Multi-Region Failover.&#8221; We are lying.<\/p>\n<p>During the us-east-1 &#8220;issue&#8221; (read: total collapse) last year, we tried to fail over to us-west-2. It failed. Why?<br \/>\n&#8211; Route 53 Health Checks: We had the TTL set to 300 seconds. Five minutes of downtime before the DNS even started to update.<br \/>\n&#8211; Database Replication Lag: The cross-region RDS read replica was 10 minutes behind because of a massive write spike right before the outage.<br \/>\n&#8211; Hardcoded ARNs: Half the microservices had us-east-1 ARNs hardcoded in their config maps.<br \/>\n&#8211; S3 Consistency: We relied on objects that hadn&#8217;t replicated to the west region yet.<\/p>\n<p>A real failover isn&#8217;t a button<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Related_Articles\"><\/span>Related Articles<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Explore more insights and best practices:<\/p>\n<ul>\n<li><a href=\"https:\/\/itsupportwale.com\/blog\/disable-gnome-animation-on-ubuntu\/\">Disable Gnome Animation On Ubuntu<\/a><\/li>\n<li><a href=\"https:\/\/itsupportwale.com\/blog\/10-essential-javascript-best-practices-for-modern-developers\/\">10 Essential Javascript Best Practices For Modern Developers<\/a><\/li>\n<li><a href=\"https:\/\/itsupportwale.com\/blog\/docker-image-explained-a-complete-guide-for-developers\/\">Docker Image Explained A Complete Guide For Developers<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>text 2024-05-21T03:14:07.892Z [ERROR] [BatchID: 9921-X] FATAL: Connection reset by peer. 2024-05-21T03:14:08.001Z [WARN] [Kinesis-Consumer] Shard iterator expired. Retrying&#8230; 2024-05-21T03:14:08.445Z [CRITICAL] [Billing-Alert] Estimated charges for current month: $42,901.12 (Threshold $5,000 exceeded). 2024-05-21T03:14:10.112Z [SYS] Kernel Panic &#8211; not syncing: Fatal exception in interrupt. $ aws ec2 describe-instances &#8211;filters &#8220;Name=instance-state-name,Values=running&#8221; &#8211;query &#8220;Reservations[].Instances[].[InstanceId, State.Name, PrivateIpAddress, InstanceType]&#8221; &#8211;output table | DescribeInstances &#8230; <a title=\"Master AWS Best Practices: Optimize Cost &#038; Security\" class=\"read-more\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/\" aria-label=\"Read more  on Master AWS Best Practices: Optimize Cost &#038; Security\">Read more<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4839","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Master AWS Best Practices: Optimize Cost &amp; Security - ITSupportWale<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Master AWS Best Practices: Optimize Cost &amp; Security - ITSupportWale\" \/>\n<meta property=\"og:description\" content=\"text 2024-05-21T03:14:07.892Z [ERROR] [BatchID: 9921-X] FATAL: Connection reset by peer. 2024-05-21T03:14:08.001Z [WARN] [Kinesis-Consumer] Shard iterator expired. Retrying&#8230; 2024-05-21T03:14:08.445Z [CRITICAL] [Billing-Alert] Estimated charges for current month: $42,901.12 (Threshold $5,000 exceeded). 2024-05-21T03:14:10.112Z [SYS] Kernel Panic &#8211; not syncing: Fatal exception in interrupt. $ aws ec2 describe-instances &#8211;filters &#8220;Name=instance-state-name,Values=running&#8221; &#8211;query &#8220;Reservations[].Instances[].[InstanceId, State.Name, PrivateIpAddress, InstanceType]&#8221; &#8211;output table | DescribeInstances ... Read more\" \/>\n<meta property=\"og:url\" content=\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/\" \/>\n<meta property=\"og:site_name\" content=\"ITSupportWale\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Itsupportwale-298547177495978\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-21T16:29:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2021\/05\/android-chrome-512x512-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"512\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Techie\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Techie\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/\"},\"author\":{\"name\":\"Techie\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d\"},\"headline\":\"Master AWS Best Practices: Optimize Cost &#038; Security\",\"datePublished\":\"2026-07-21T16:29:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/\"},\"wordCount\":2963,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#organization\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/\",\"url\":\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/\",\"name\":\"Master AWS Best Practices: Optimize Cost & Security - ITSupportWale\",\"isPartOf\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#website\"},\"datePublished\":\"2026-07-21T16:29:59+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/itsupportwale.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Master AWS Best Practices: Optimize Cost &#038; Security\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#website\",\"url\":\"https:\/\/itsupportwale.com\/blog\/\",\"name\":\"ITSupportWale\",\"description\":\"Tips, Tricks, Fixed-Errors, Tutorials &amp; Guides\",\"publisher\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/itsupportwale.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#organization\",\"name\":\"itsupportwale\",\"url\":\"https:\/\/itsupportwale.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png\",\"contentUrl\":\"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png\",\"width\":1119,\"height\":144,\"caption\":\"itsupportwale\"},\"image\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Itsupportwale-298547177495978\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d\",\"name\":\"Techie\",\"sameAs\":[\"https:\/\/itsupportwale.com\",\"iswblogadmin\"],\"url\":\"https:\/\/itsupportwale.com\/blog\/author\/iswblogadmin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Master AWS Best Practices: Optimize Cost & Security - ITSupportWale","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/","og_locale":"en_US","og_type":"article","og_title":"Master AWS Best Practices: Optimize Cost & Security - ITSupportWale","og_description":"text 2024-05-21T03:14:07.892Z [ERROR] [BatchID: 9921-X] FATAL: Connection reset by peer. 2024-05-21T03:14:08.001Z [WARN] [Kinesis-Consumer] Shard iterator expired. Retrying&#8230; 2024-05-21T03:14:08.445Z [CRITICAL] [Billing-Alert] Estimated charges for current month: $42,901.12 (Threshold $5,000 exceeded). 2024-05-21T03:14:10.112Z [SYS] Kernel Panic &#8211; not syncing: Fatal exception in interrupt. $ aws ec2 describe-instances &#8211;filters &#8220;Name=instance-state-name,Values=running&#8221; &#8211;query &#8220;Reservations[].Instances[].[InstanceId, State.Name, PrivateIpAddress, InstanceType]&#8221; &#8211;output table | DescribeInstances ... Read more","og_url":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/","og_site_name":"ITSupportWale","article_publisher":"https:\/\/www.facebook.com\/Itsupportwale-298547177495978","article_published_time":"2026-07-21T16:29:59+00:00","og_image":[{"width":512,"height":512,"url":"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2021\/05\/android-chrome-512x512-1.png","type":"image\/png"}],"author":"Techie","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Techie","Est. reading time":"19 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#article","isPartOf":{"@id":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/"},"author":{"name":"Techie","@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d"},"headline":"Master AWS Best Practices: Optimize Cost &#038; Security","datePublished":"2026-07-21T16:29:59+00:00","mainEntityOfPage":{"@id":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/"},"wordCount":2963,"commentCount":0,"publisher":{"@id":"https:\/\/itsupportwale.com\/blog\/#organization"},"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/","url":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/","name":"Master AWS Best Practices: Optimize Cost & Security - ITSupportWale","isPartOf":{"@id":"https:\/\/itsupportwale.com\/blog\/#website"},"datePublished":"2026-07-21T16:29:59+00:00","breadcrumb":{"@id":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/itsupportwale.com\/blog\/master-aws-best-practices-optimize-cost-and-security\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/itsupportwale.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Master AWS Best Practices: Optimize Cost &#038; Security"}]},{"@type":"WebSite","@id":"https:\/\/itsupportwale.com\/blog\/#website","url":"https:\/\/itsupportwale.com\/blog\/","name":"ITSupportWale","description":"Tips, Tricks, Fixed-Errors, Tutorials &amp; Guides","publisher":{"@id":"https:\/\/itsupportwale.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/itsupportwale.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/itsupportwale.com\/blog\/#organization","name":"itsupportwale","url":"https:\/\/itsupportwale.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png","contentUrl":"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png","width":1119,"height":144,"caption":"itsupportwale"},"image":{"@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Itsupportwale-298547177495978"]},{"@type":"Person","@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d","name":"Techie","sameAs":["https:\/\/itsupportwale.com","iswblogadmin"],"url":"https:\/\/itsupportwale.com\/blog\/author\/iswblogadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts\/4839","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/comments?post=4839"}],"version-history":[{"count":0,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts\/4839\/revisions"}],"wp:attachment":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/media?parent=4839"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/categories?post=4839"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/tags?post=4839"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}