<?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>Forem: Danny Steenman</title>
    <description>The latest articles on Forem by Danny Steenman (@dannysteenman).</description>
    <link>https://forem.com/dannysteenman</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F743421%2Fbb39bd38-8eb5-4d35-9f80-92fce1ec02d8.png</url>
      <title>Forem: Danny Steenman</title>
      <link>https://forem.com/dannysteenman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dannysteenman"/>
    <language>en</language>
    <item>
      <title>10 AWS Security Misconfigurations Found in 90% of Accounts</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 17:30:07 +0000</pubDate>
      <link>https://forem.com/dannysteenman/10-aws-security-misconfigurations-found-in-90-of-accounts-835</link>
      <guid>https://forem.com/dannysteenman/10-aws-security-misconfigurations-found-in-90-of-accounts-835</guid>
      <description>&lt;p&gt;import { FaqSection } from "@/components/mdx/faq-section";&lt;br&gt;
import { CtaCard } from "@/components/mdx/cta-card";&lt;/p&gt;

&lt;p&gt;I've reviewed over 200 AWS accounts across startups and enterprises. These 10 security misconfigurations appear in more than 90% of them, and most teams don't know they exist until something goes wrong. The difference between a good review and a great one is how findings are prioritized and presented so you can actually act on them. For a complete breakdown of the review process, see our &lt;a href="https://towardsthecloud.com/blog/aws-security-review-process" rel="noopener noreferrer"&gt;AWS security review process guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS security misconfigurations are incorrect settings in cloud infrastructure that expose resources to unauthorized access, data breaches, or service disruption.&lt;/strong&gt; Unlike software vulnerabilities requiring patches, misconfigurations result from human error, default settings that aren't secured, or operational shortcuts that become permanent. Cloud misconfigurations cause over 80% of security breaches, making this the most impactful security work you can do.&lt;/p&gt;

&lt;p&gt;The good news? Every issue I'll cover is detectable using native AWS tools, and most fixes take minutes to implement. By the end of this guide, you'll know exactly how to detect each issue using AWS Security Hub, Config rules, and CLI commands, plus the specific steps to fix them.&lt;/p&gt;

&lt;p&gt;Here's a quick reference of all 10 misconfigurations with severity ratings and detection methods:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Misconfiguration&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Primary Detection Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Public S3 Buckets&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;td&gt;Security Hub S3.1, S3.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overly Permissive IAM Policies&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;td&gt;Security Hub IAM.1, IAM.21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing MFA on Root Account&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;td&gt;Security Hub IAM.6, IAM.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unencrypted EBS Volumes&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Security Hub EC2.7, EC2.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Groups with 0.0.0.0/0&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Security Hub EC2.18, EC2.19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing CloudTrail Logging&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Security Hub CloudTrail.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unused IAM Credentials&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Security Hub IAM.3, IAM.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default VPC Usage&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Security Hub EC2.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing Encryption in Transit&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Security Hub S3.5, CloudFront.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No AWS Config Rules&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Config recorder status&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Let me walk through each one, including why it matters, how to detect it, and exactly how to fix it.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Public S3 Buckets
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: Critical&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Public S3 buckets remain the most common and dangerous misconfiguration in AWS environments. Despite AWS making Block Public Access the default for new buckets as of April 2023, legacy buckets and misconfigurations continue to expose sensitive data.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why It's Still the Number One Issue
&lt;/h3&gt;

&lt;p&gt;AWS considers a bucket public when Access Control Lists (ACLs) grant permissions to the &lt;code&gt;AllUsers&lt;/code&gt; or &lt;code&gt;AuthenticatedUsers&lt;/code&gt; groups, or when bucket policies grant access to principals outside your zone of trust. The challenge is that buckets created before April 2023 don't have Block Public Access enabled by default, and a single misconfigured policy can override account-level protections.&lt;/p&gt;

&lt;p&gt;Block Public Access provides four settings that work together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BlockPublicAcls&lt;/strong&gt;: Prevents accepting public ACLs for buckets and objects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IgnorePublicAcls&lt;/strong&gt;: Ignores all public ACLs on buckets and objects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BlockPublicPolicy&lt;/strong&gt;: Rejects bucket policies that grant public access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RestrictPublicBuckets&lt;/strong&gt;: Restricts access to AWS service principals and authorized users only&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  How to Detect Public Buckets
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security Hub Controls&lt;/strong&gt;: S3.1 (account-level), S3.8 (bucket-level), S3.2 (public read), S3.3 (public write)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config Rules&lt;/strong&gt;: &lt;code&gt;s3-account-level-public-access-blocks&lt;/code&gt;, &lt;code&gt;s3-bucket-public-read-prohibited&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Detection&lt;/strong&gt;:&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;# Check account-level Block Public Access settings&lt;/span&gt;
aws s3control get-public-access-block &lt;span class="nt"&gt;--account-id&lt;/span&gt; &amp;lt;account-id&amp;gt;

&lt;span class="c"&gt;# Check bucket-level settings&lt;/span&gt;
aws s3api get-public-access-block &lt;span class="nt"&gt;--bucket&lt;/span&gt; &amp;lt;bucket-name&amp;gt;

&lt;span class="c"&gt;# Check bucket ACLs for public grants&lt;/span&gt;
aws s3api get-bucket-acl &lt;span class="nt"&gt;--bucket&lt;/span&gt; &amp;lt;bucket-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IAM Access Analyzer also automatically flags cross-account and public access, generating findings with details about the access level and external principal.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Fix and Prevent
&lt;/h3&gt;

&lt;p&gt;Enable Block Public Access at the account level first, then verify bucket-level settings:&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;# Enable at account level (protects all buckets)&lt;/span&gt;
aws s3control put-public-access-block &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--account-id&lt;/span&gt; &amp;lt;account-id&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--public-access-block-configuration&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;BlockPublicAcls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,IgnorePublicAcls&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,BlockPublicPolicy&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,RestrictPublicBuckets&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;

&lt;span class="c"&gt;# Enable at bucket level&lt;/span&gt;
aws s3api put-public-access-block &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--bucket&lt;/span&gt; &amp;lt;bucket-name&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--public-access-block-configuration&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nv"&gt;BlockPublicAcls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,IgnorePublicAcls&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,BlockPublicPolicy&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;,RestrictPublicBuckets&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For legitimate public access needs, use CloudFront with Origin Access Control (OAC), presigned URLs with expiration times, or VPC endpoints for private access.&lt;/p&gt;

&lt;p&gt;While S3 exposure is visible, IAM policy issues hide in plain sight, making them equally dangerous but harder to spot.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Overly Permissive IAM Policies
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: Critical&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Overly permissive IAM policies violate the principle of least privilege and create the largest attack surface in most AWS accounts. When credentials are compromised, the damage is limited only by what those credentials can access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Anti-Patterns
&lt;/h3&gt;

&lt;p&gt;In my reviews, I consistently find these patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Full administrator permissions&lt;/strong&gt; (&lt;code&gt;*:*&lt;/code&gt;) granted to IAM users or roles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wildcard service actions&lt;/strong&gt; like &lt;code&gt;s3:*&lt;/code&gt; or &lt;code&gt;ec2:*&lt;/code&gt; instead of specific operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policies attached directly to users&lt;/strong&gt; rather than groups or roles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing condition keys&lt;/strong&gt; that would restrict access by IP, organization, or MFA status&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No permissions boundaries&lt;/strong&gt; for delegated administration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IAM users and roles have no permissions by default, which is the right starting point. The problem is that teams add permissions incrementally and rarely remove them.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Detect Overpermissioned Policies
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security Hub Controls&lt;/strong&gt;: IAM.1 (admin privileges), IAM.2 (user-attached policies), IAM.21 (wildcard actions)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config Rules&lt;/strong&gt;: &lt;code&gt;iam-policy-no-statements-with-admin-access&lt;/code&gt;, &lt;code&gt;iam-user-no-policies-check&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Detection with IAM Access Analyzer&lt;/strong&gt;:&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;# Validate a policy against best practices&lt;/span&gt;
aws accessanalyzer validate-policy &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--policy-document&lt;/span&gt; file://policy.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--policy-type&lt;/span&gt; IDENTITY_POLICY

&lt;span class="c"&gt;# List policies attached to a user (should be empty - use groups)&lt;/span&gt;
aws iam list-attached-user-policies &lt;span class="nt"&gt;--user-name&lt;/span&gt; &amp;lt;user-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Implement Least Privilege
&lt;/h3&gt;

&lt;p&gt;Start with AWS managed policies for job functions like &lt;code&gt;ViewOnlyAccess&lt;/code&gt;, &lt;code&gt;PowerUserAccess&lt;/code&gt;, or &lt;code&gt;SecurityAudit&lt;/code&gt;. Then use IAM Access Analyzer's policy generation feature, which creates least-privilege policies based on actual CloudTrail access activity.&lt;/p&gt;

&lt;p&gt;Here's an example of a properly scoped policy with condition keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:PutObject"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-bucket/my-prefix/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"IpAddress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"aws:SourceIp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"203.0.113.0/24"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Bool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"aws:MultiFactorAuthPresent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;aws:PrincipalOrgID&lt;/code&gt; condition keys to ensure access only comes from within your AWS Organization, and review permissions every 90 days to identify and remove unused access.&lt;/p&gt;

&lt;p&gt;For broader governance, consider using &lt;a href="https://towardsthecloud.com/blog/aws-scp-examples" rel="noopener noreferrer"&gt;Service Control Policies to prevent misconfigurations&lt;/a&gt; before they happen.&lt;/p&gt;

&lt;p&gt;Even perfect IAM policies mean nothing if your root account lacks MFA.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Missing MFA on Root Account
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: Critical&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The root user has unrestricted access to everything in your AWS account, including the ability to close it entirely. Compromise of root credentials without MFA protection leads to complete account takeover, data destruction, and significant financial impact through unauthorized resource provisioning.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Risk of Unprotected Root
&lt;/h3&gt;

&lt;p&gt;As of 2025, AWS now enforces MFA for root users across all account types, including member accounts in AWS Organizations. But enforcement doesn't mean configuration. Many accounts I review have MFA enabled with a single device that's lost or inaccessible, which creates operational risk without the security benefit.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Detect Missing MFA
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security Hub Controls&lt;/strong&gt;: IAM.6 (hardware MFA), IAM.9 (virtual MFA)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config Rules&lt;/strong&gt;: &lt;code&gt;root-account-mfa-enabled&lt;/code&gt;, &lt;code&gt;root-account-hardware-mfa-enabled&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Detection&lt;/strong&gt;:&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;# Check if root account has MFA enabled&lt;/span&gt;
aws iam get-account-summary | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"AccountMFAEnabled"&lt;/span&gt;

&lt;span class="c"&gt;# List MFA devices for root user&lt;/span&gt;
aws iam list-mfa-devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Enable MFA
&lt;/h3&gt;

&lt;p&gt;AWS supports three MFA types, and I recommend using the strongest option your team can manage:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Passkeys and FIDO Security Keys&lt;/strong&gt; (strongest): Physical devices like YubiKeys that use public key cryptography. These are phishing-resistant and provide the strongest authentication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Virtual Authenticator Apps&lt;/strong&gt;: Software applications like Google Authenticator, Microsoft Authenticator, or Authy that generate time-based codes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hardware TOTP Tokens&lt;/strong&gt;: Physical devices generating six-digit codes. AWS recommends FIDO security keys over these due to their stronger security properties.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Best practices&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register multiple MFA devices (up to 8 supported) for redundancy&lt;/li&gt;
&lt;li&gt;Store MFA recovery information with multi-person approval&lt;/li&gt;
&lt;li&gt;Use a group email address for root user, not an individual's email&lt;/li&gt;
&lt;li&gt;Document and test root access procedures annually&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With authentication secured, let's ensure your data at rest is encrypted.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Unencrypted EBS Volumes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: High&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;EBS volumes are not encrypted by default unless you explicitly enable encryption by default at the Region level. Unencrypted volumes expose data at rest to unauthorized access if snapshots are shared, volumes are attached to compromised instances, or physical hardware is accessed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Default Encryption Matters
&lt;/h3&gt;

&lt;p&gt;When you enable encryption by default, EBS automatically encrypts new volumes, new volumes created from unencrypted snapshots, and snapshot copies. The encryption happens on the servers hosting EC2 instances, protecting both data at rest and data in transit between instances and volumes.&lt;/p&gt;

&lt;p&gt;You have two key options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS managed key&lt;/strong&gt; (&lt;code&gt;aws/ebs&lt;/code&gt;): No configuration required, AWS handles everything&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer managed key&lt;/strong&gt;: Provides control over key policies, rotation, and cross-account snapshot sharing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Find Unencrypted Volumes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security Hub Controls&lt;/strong&gt;: EC2.7 (encryption by default), EC2.3 (attached volumes encrypted)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config Rules&lt;/strong&gt;: &lt;code&gt;ec2-ebs-encryption-by-default&lt;/code&gt;, &lt;code&gt;encrypted-volumes&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Detection&lt;/strong&gt;:&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;# Check if encryption by default is enabled&lt;/span&gt;
aws ec2 get-ebs-encryption-by-default &lt;span class="nt"&gt;--region&lt;/span&gt; &amp;lt;region&amp;gt;

&lt;span class="c"&gt;# List unencrypted volumes&lt;/span&gt;
aws ec2 describe-volumes &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;encrypted,Values&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Volumes[*].[VolumeId,State,Size]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Enable Encryption
&lt;/h3&gt;

&lt;p&gt;Enable encryption by default in each Region where you operate (this is Region-specific):&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;# Enable encryption by default&lt;/span&gt;
aws ec2 enable-ebs-encryption-by-default &lt;span class="nt"&gt;--region&lt;/span&gt; &amp;lt;region-name&amp;gt;

&lt;span class="c"&gt;# Optionally set a customer managed key as default&lt;/span&gt;
aws ec2 modify-ebs-default-kms-key-id &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--kms-key-id&lt;/span&gt; &amp;lt;kms-key-id&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--region&lt;/span&gt; &amp;lt;region-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For existing unencrypted volumes, you'll need to migrate via snapshots:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a snapshot of the unencrypted volume&lt;/li&gt;
&lt;li&gt;Copy the snapshot with encryption enabled&lt;/li&gt;
&lt;li&gt;Create a new encrypted volume from the encrypted snapshot&lt;/li&gt;
&lt;li&gt;Stop the instance, detach old volume, attach new volume, restart&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Encryption protects data at rest, but open security groups expose it to the network.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Security Groups with 0.0.0.0/0
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: High&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Security groups with rules allowing ingress from &lt;code&gt;0.0.0.0/0&lt;/code&gt; permit traffic from any IP address on the internet. While acceptable for ports 80 and 443 on public-facing load balancers, opening administrative or database ports to the world creates significant attack surface.&lt;/p&gt;

&lt;h3&gt;
  
  
  High-Risk Ports That Should Never Be Open
&lt;/h3&gt;

&lt;p&gt;These ports should never be accessible from 0.0.0.0/0:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;22 (SSH)&lt;/strong&gt;: Remote command-line access to Linux instances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3389 (RDP)&lt;/strong&gt;: Remote Desktop access to Windows instances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3306 (MySQL)&lt;/strong&gt;, &lt;strong&gt;5432 (PostgreSQL)&lt;/strong&gt;, &lt;strong&gt;1433 (MS SQL)&lt;/strong&gt;: Database access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;27017 (MongoDB)&lt;/strong&gt;, &lt;strong&gt;6379 (Redis)&lt;/strong&gt;: NoSQL and cache access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;9200/9300 (Elasticsearch)&lt;/strong&gt;: Search engine access&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Find Overly Permissive Rules
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security Hub Controls&lt;/strong&gt;: EC2.18 (unrestricted traffic for authorized ports), EC2.19 (unrestricted high-risk ports)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config Rules&lt;/strong&gt;: &lt;code&gt;restricted-ssh&lt;/code&gt;, &lt;code&gt;restricted-common-ports&lt;/code&gt;, &lt;code&gt;vpc-sg-open-only-to-authorized-ports&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Detection&lt;/strong&gt;:&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;# List security groups with 0.0.0.0/0 rules&lt;/span&gt;
aws ec2 describe-security-groups &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]].{GroupId:GroupId,GroupName:GroupName,VpcId:VpcId}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--output&lt;/span&gt; table

&lt;span class="c"&gt;# Find security groups with SSH open to the world&lt;/span&gt;
aws ec2 describe-security-groups &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ip-permission.from-port,Values&lt;span class="o"&gt;=&lt;/span&gt;22 &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ip-permission.to-port,Values&lt;span class="o"&gt;=&lt;/span&gt;22 &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ip-permission.cidr,Values&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'0.0.0.0/0'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'SecurityGroups[*].[GroupId,GroupName,VpcId]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While you're auditing security groups, you might also want to &lt;a href="https://towardsthecloud.com/blog/amazon-vpc-find-unused-security-groups" rel="noopener noreferrer"&gt;find unused security groups in your account&lt;/a&gt; to reduce unnecessary attack surface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure Alternatives to Open Ports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AWS Systems Manager Session Manager&lt;/strong&gt; (Recommended): Eliminates the need for SSH or RDP ports entirely. Sessions are fully auditable via CloudTrail, controlled by IAM policies, and logged to S3 or CloudWatch Logs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security group references&lt;/strong&gt;: Instead of IP ranges, reference other security groups for internal communication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 authorize-security-group-ingress &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--group-id&lt;/span&gt; &amp;lt;target-security-group-id&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--protocol&lt;/span&gt; tcp &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--port&lt;/span&gt; 3306 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--source-group&lt;/span&gt; &amp;lt;source-security-group-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Specific IP ranges&lt;/strong&gt;: For legacy requirements, restrict to known office or VPN IP ranges rather than 0.0.0.0/0.&lt;/p&gt;

&lt;p&gt;Even with tight network security, you need visibility into what's happening. That's where logging comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Missing CloudTrail Logging
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: High&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without CloudTrail enabled, you have no record of who did what, when, and from where in your AWS account. This makes incident investigation impossible, compliance audits difficult, and unauthorized activity undetectable.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Should Be Logged
&lt;/h3&gt;

&lt;p&gt;CloudTrail captures four types of events:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Management Events&lt;/strong&gt; (default, free): Control plane operations like creating instances, modifying security groups, and IAM changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Events&lt;/strong&gt; (additional charges): Data plane operations like S3 GetObject/PutObject and Lambda invocations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Activity Events&lt;/strong&gt;: VPC Flow Logs metadata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insights Events&lt;/strong&gt;: Anomalous API call patterns detected by machine learning&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;CloudTrail Event History provides 90 days of management event retention for free, but you need a trail configured to retain logs longer or send them to CloudWatch Logs for alerting.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Detect Logging Gaps
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security Hub Controls&lt;/strong&gt;: CloudTrail.1 (multi-Region trail), CloudTrail.2 (encryption), CloudTrail.4 (log validation), CloudTrail.5 (CloudWatch integration)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config Rules&lt;/strong&gt;: &lt;code&gt;cloud-trail-enabled&lt;/code&gt;, &lt;code&gt;multi-region-cloud-trail-enabled&lt;/code&gt;, &lt;code&gt;cloud-trail-encryption-enabled&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Detection&lt;/strong&gt;:&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;# List all trails&lt;/span&gt;
aws cloudtrail list-trails

&lt;span class="c"&gt;# Check if trail is logging&lt;/span&gt;
aws cloudtrail get-trail-status &lt;span class="nt"&gt;--name&lt;/span&gt; my-trail

&lt;span class="c"&gt;# Find trails that aren't multi-region (a gap)&lt;/span&gt;
aws cloudtrail describe-trails &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'trailList[?IsMultiRegionTrail==`false`]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Configure Proper Logging
&lt;/h3&gt;

&lt;p&gt;Always create multi-Region trails. Single-Region trails miss activity in other Regions, including new Regions AWS adds over time.&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;# Create a multi-region trail with best practices enabled&lt;/span&gt;
aws cloudtrail create-trail &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--name&lt;/span&gt; organization-trail &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--s3-bucket-name&lt;/span&gt; cloudtrail-logs-bucket &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--is-multi-region-trail&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--enable-log-file-validation&lt;/span&gt;

&lt;span class="c"&gt;# Start logging&lt;/span&gt;
aws cloudtrail start-logging &lt;span class="nt"&gt;--name&lt;/span&gt; organization-trail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For AWS Organizations, create an organization trail that automatically covers all member accounts. This is essential for &lt;a href="https://towardsthecloud.com/blog/aws-organizations-best-practices" rel="noopener noreferrer"&gt;AWS Organizations governance patterns&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Essential configuration checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable log file validation (detects tampering)&lt;/li&gt;
&lt;li&gt;Encrypt log files using KMS&lt;/li&gt;
&lt;li&gt;Configure S3 bucket policies to prevent unauthorized access&lt;/li&gt;
&lt;li&gt;Set up CloudWatch Logs for real-time alerting&lt;/li&gt;
&lt;li&gt;Enable CloudTrail Insights for anomaly detection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With logging in place, let's address the credentials that could be used against you.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Unused IAM Credentials
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: Medium&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unused credentials (access keys, passwords, roles, users) create significant risk. Forgotten credentials can be compromised without detection, used by former employees, or discovered in code repositories and configuration files by attackers.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Hidden Risk of Stale Credentials
&lt;/h3&gt;

&lt;p&gt;I regularly find access keys that haven't been used in over a year but remain active. These are prime targets: they have permissions, no one monitors them, and if compromised, no legitimate use would be disrupted to trigger an alert.&lt;/p&gt;

&lt;p&gt;Types of unused credentials to track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unused access keys&lt;/strong&gt;: Not used for API calls within 90 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unused passwords&lt;/strong&gt;: Not used for console sign-in within 45-90 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unused IAM roles&lt;/strong&gt;: Not assumed within 90 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unused IAM users&lt;/strong&gt;: No activity (console or API) for extended periods&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Find Unused Credentials
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security Hub Controls&lt;/strong&gt;: IAM.3 (key rotation), IAM.8 (unused credentials), IAM.22 (credentials unused 45+ days)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config Rules&lt;/strong&gt;: &lt;code&gt;iam-user-unused-credentials-check&lt;/code&gt;, &lt;code&gt;access-keys-rotated&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IAM Access Analyzer&lt;/strong&gt;: Continuously monitors and generates findings for unused roles, access keys, and passwords over 90 days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Detection using Credential Report&lt;/strong&gt;:&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;# Generate credential report&lt;/span&gt;
aws iam generate-credential-report

&lt;span class="c"&gt;# Download and analyze&lt;/span&gt;
aws iam get-credential-report &lt;span class="nt"&gt;--output&lt;/span&gt; text &lt;span class="nt"&gt;--query&lt;/span&gt; Content | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;--decode&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; credential-report.csv

&lt;span class="c"&gt;# Get access key last used information&lt;/span&gt;
aws iam get-access-key-last-used &lt;span class="nt"&gt;--access-key-id&lt;/span&gt; &amp;lt;access-key-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The credential report includes user creation date, password last used, access key last used dates, and MFA status for every user.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Clean Up and Rotate
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Disable before deleting&lt;/strong&gt;: Always disable unused keys first and wait a period to ensure nothing breaks:&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;# Disable unused access key&lt;/span&gt;
aws iam update-access-key &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--access-key-id&lt;/span&gt; &amp;lt;access-key-id&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--status&lt;/span&gt; Inactive &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--user-name&lt;/span&gt; &amp;lt;user-name&amp;gt;

&lt;span class="c"&gt;# After confirming no impact, delete&lt;/span&gt;
aws iam delete-access-key &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--access-key-id&lt;/span&gt; &amp;lt;access-key-id&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--user-name&lt;/span&gt; &amp;lt;user-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Best practices&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rotate access keys every 90 days maximum&lt;/li&gt;
&lt;li&gt;Create a second access key before disabling the first (zero-downtime rotation)&lt;/li&gt;
&lt;li&gt;Remove credentials for users inactive over 45 days&lt;/li&gt;
&lt;li&gt;Use AWS Secrets Manager for automated rotation of database credentials&lt;/li&gt;
&lt;li&gt;Replace long-term credentials with IAM roles wherever possible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Credential hygiene matters, but so does your network architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Default VPC Usage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: Medium&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every AWS account comes with a default VPC in each Region. While convenient for getting started, default VPCs have security and operational limitations that make them unsuitable for production workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Default VPCs Are Problematic
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security issues&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Predictable CIDR block&lt;/strong&gt; (172.31.0.0/16) makes network scanning easier&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internet Gateway attached by default&lt;/strong&gt; with public routes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default security group&lt;/strong&gt; allows all inbound traffic from itself&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public subnets by default&lt;/strong&gt; with automatic public IP assignment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No network segmentation&lt;/strong&gt; or isolation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Operational limitations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cannot customize CIDR block (always 172.31.0.0/16)&lt;/li&gt;
&lt;li&gt;Limited subnet sizing control&lt;/li&gt;
&lt;li&gt;Difficult to integrate with VPC peering or Transit Gateway systematically&lt;/li&gt;
&lt;li&gt;Cannot enforce organizational network standards&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Identify Default VPC Resources
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security Hub Control&lt;/strong&gt;: EC2.2 (default security group should not allow traffic)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config Rule&lt;/strong&gt;: &lt;code&gt;vpc-default-security-group-closed&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Detection&lt;/strong&gt;:&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;# List default VPCs across all regions&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;region &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;aws ec2 describe-regions &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Regions[].RegionName'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Region: &lt;/span&gt;&lt;span class="nv"&gt;$region&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  aws ec2 describe-vpcs &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="nv"&gt;$region&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;isDefault,Values&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Vpcs[*].[VpcId,CidrBlock]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Find instances in default VPC&lt;/span&gt;
aws ec2 describe-instances &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Reservations[*].Instances[?VpcId==`&amp;lt;default-vpc-id&amp;gt;`].[InstanceId,InstanceType,State.Name]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Migrate to Custom VPCs
&lt;/h3&gt;

&lt;p&gt;Create custom VPCs with proper network segmentation:&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;# Create VPC with appropriate CIDR&lt;/span&gt;
aws ec2 create-vpc &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--cidr-block&lt;/span&gt; 10.0.0.0/16 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--tag-specifications&lt;/span&gt; &lt;span class="s1"&gt;'ResourceType=vpc,Tags=[{Key=Name,Value=Production-VPC}]'&lt;/span&gt;

&lt;span class="c"&gt;# Create public and private subnets&lt;/span&gt;
aws ec2 create-subnet &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--vpc-id&lt;/span&gt; &amp;lt;vpc-id&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--cidr-block&lt;/span&gt; 10.0.1.0/24 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--availability-zone&lt;/span&gt; us-east-1a &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--tag-specifications&lt;/span&gt; &lt;span class="s1"&gt;'ResourceType=subnet,Tags=[{Key=Name,Value=Public-Subnet-1A}]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Best practices for custom VPCs&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy across at least 2 Availability Zones&lt;/li&gt;
&lt;li&gt;Create public, private, and data subnet tiers&lt;/li&gt;
&lt;li&gt;Use NAT Gateways for private subnet outbound access&lt;/li&gt;
&lt;li&gt;Enable VPC Flow Logs for traffic monitoring&lt;/li&gt;
&lt;li&gt;Use VPC endpoints for private connectivity to AWS services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider deleting default VPCs after migration to prevent accidental deployments. Note that AWS doesn't allow recreating them in the same Region once deleted.&lt;/p&gt;

&lt;p&gt;With proper network architecture, ensure all traffic is encrypted.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Missing Encryption in Transit
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: Medium&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Encryption in transit protects data as it travels over untrusted networks. Without it, traffic can be intercepted, modified, or analyzed through man-in-the-middle attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  TLS Requirements and Modern Standards
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum TLS version&lt;/strong&gt;: TLS 1.2 (TLS 1.0 and 1.1 are deprecated)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS 1.3&lt;/strong&gt;: Available across most AWS services for enhanced security and performance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cipher suites&lt;/strong&gt;: Use strong, modern ciphers; avoid weak ones like RC4 or DES&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Detect Unencrypted Traffic
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security Hub Controls&lt;/strong&gt;: S3.5 (S3 SSL requests only), CloudFront.3 (encryption in transit)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Config Rules&lt;/strong&gt;: &lt;code&gt;alb-http-to-https-redirection-check&lt;/code&gt;, &lt;code&gt;cloudfront-viewer-policy-https&lt;/code&gt;, &lt;code&gt;s3-bucket-ssl-requests-only&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Detection&lt;/strong&gt;:&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;# Check ALB listener security policy&lt;/span&gt;
aws elbv2 describe-listeners &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--load-balancer-arn&lt;/span&gt; &amp;lt;alb-arn&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Listeners[?Protocol==`HTTPS`].[ListenerArn,SslPolicy]'&lt;/span&gt;

&lt;span class="c"&gt;# Check CloudFront distribution TLS settings&lt;/span&gt;
aws cloudfront get-distribution-config &lt;span class="nt"&gt;--id&lt;/span&gt; &amp;lt;distribution-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Enforce HTTPS Everywhere
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;ALB Configuration&lt;/strong&gt;: Use modern security policies and configure HTTP to HTTPS redirect:&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;# Create HTTPS listener with TLS 1.2/1.3&lt;/span&gt;
aws elbv2 create-listener &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--load-balancer-arn&lt;/span&gt; &amp;lt;alb-arn&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--protocol&lt;/span&gt; HTTPS &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--port&lt;/span&gt; 443 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--certificates&lt;/span&gt; &lt;span class="nv"&gt;CertificateArn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;certificate-arn&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--ssl-policy&lt;/span&gt; ELBSecurityPolicy-TLS13-1-2-2021-06 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--default-actions&lt;/span&gt; &lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;forward,TargetGroupArn&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;target-group-arn&amp;gt;

&lt;span class="c"&gt;# Configure HTTP to HTTPS redirect&lt;/span&gt;
aws elbv2 create-listener &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--load-balancer-arn&lt;/span&gt; &amp;lt;alb-arn&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--protocol&lt;/span&gt; HTTP &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--port&lt;/span&gt; 80 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--default-actions&lt;/span&gt; &lt;span class="nv"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;redirect,RedirectConfig&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{Protocol=HTTPS,Port=443,StatusCode=HTTP_301}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;S3 Bucket Policy&lt;/strong&gt;: Enforce HTTPS and minimum TLS version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-bucket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-bucket/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Bool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"aws:SecureTransport"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-bucket/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"NumericLessThan"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"s3:TlsVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.2"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CloudFront&lt;/strong&gt;: Set &lt;code&gt;ViewerProtocolPolicy&lt;/code&gt; to &lt;code&gt;redirect-to-https&lt;/code&gt; and use &lt;code&gt;TLSv1.2_2021&lt;/code&gt; as minimum security policy.&lt;/p&gt;

&lt;p&gt;Finally, let's ensure you have continuous compliance monitoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. No AWS Config Rules
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Severity: Medium&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AWS Config continuously monitors and records resource configurations, evaluating them against rules that define desired states. Without Config rules enabled, you lack automated compliance checking and configuration drift detection. This is the meta-problem: having no system to catch the other nine issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Essential Config Rules for Security
&lt;/h3&gt;

&lt;p&gt;AWS provides managed rules for common security requirements. Here are the essential categories:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity and Access Management&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;iam-password-policy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iam-user-mfa-enabled&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;root-account-mfa-enabled&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iam-policy-no-statements-with-admin-access&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;access-keys-rotated&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Encryption&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;encrypted-volumes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ec2-ebs-encryption-by-default&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s3-bucket-server-side-encryption-enabled&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s3-bucket-ssl-requests-only&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Security&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;restricted-ssh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vpc-sg-open-only-to-authorized-ports&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vpc-default-security-group-closed&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Logging&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cloud-trail-enabled&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;multi-region-cloud-trail-enabled&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Public Access&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;s3-bucket-public-read-prohibited&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s3-bucket-public-write-prohibited&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rds-snapshots-public-prohibited&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Check Config Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if Config recorder is running&lt;/span&gt;
aws configservice describe-configuration-recorders

&lt;span class="c"&gt;# Get recorder status&lt;/span&gt;
aws configservice describe-configuration-recorder-status

&lt;span class="c"&gt;# List existing rules&lt;/span&gt;
aws configservice describe-config-rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Deploy Critical Rules
&lt;/h3&gt;

&lt;p&gt;Start by enabling the Config recorder, then deploy rules:&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;# Enable Config recorder&lt;/span&gt;
aws configservice start-configuration-recorder &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--configuration-recorder-name&lt;/span&gt; default

&lt;span class="c"&gt;# Deploy encrypted-volumes rule&lt;/span&gt;
aws configservice put-config-rule &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--config-rule&lt;/span&gt; &lt;span class="s1"&gt;'{
      "ConfigRuleName": "encrypted-volumes",
      "Source": {
        "Owner": "AWS",
        "SourceIdentifier": "ENCRYPTED_VOLUMES"
      }
    }'&lt;/span&gt;

&lt;span class="c"&gt;# Deploy restricted-ssh rule&lt;/span&gt;
aws configservice put-config-rule &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--config-rule&lt;/span&gt; &lt;span class="s1"&gt;'{
      "ConfigRuleName": "restricted-ssh",
      "Source": {
        "Owner": "AWS",
        "SourceIdentifier": "INCOMING_SSH_DISABLED"
      }
    }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conformance packs&lt;/strong&gt; bundle multiple rules for compliance frameworks. AWS provides sample packs for PCI DSS, HIPAA, NIST 800-53, and CIS Benchmarks.&lt;/p&gt;

&lt;p&gt;For multi-account deployments, use &lt;strong&gt;organization Config rules&lt;/strong&gt; to deploy consistently across all accounts, which integrates well with &lt;a href="https://towardsthecloud.com/blog/aws-organizations-best-practices" rel="noopener noreferrer"&gt;AWS Organizations governance patterns&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that we've covered individual issues, let's look at tools that catch them all.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Detect All 10 Issues at Once
&lt;/h2&gt;

&lt;p&gt;You don't need to run CLI commands for each misconfiguration individually. AWS provides tools that aggregate findings across multiple categories, giving you a single view of your security posture. For a comprehensive approach covering 55+ security checks across IAM, network, data, and logging domains, see our &lt;a href="https://towardsthecloud.com/blog/aws-security-review-checklist" rel="noopener noreferrer"&gt;AWS security review checklist&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Security Hub
&lt;/h3&gt;

&lt;p&gt;Security Hub is your central aggregation point. It collects findings from AWS Config, GuardDuty, Inspector, IAM Access Analyzer, Firewall Manager, and Macie. The &lt;strong&gt;AWS Foundational Security Best Practices&lt;/strong&gt; standard covers most of the misconfigurations in this guide and provides automated security checks with severity ratings.&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;# Enable Security Hub with default standards&lt;/span&gt;
aws securityhub enable-security-hub &lt;span class="nt"&gt;--enable-default-standards&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Security Hub calculates security scores based on passed vs. enabled controls, making it easy to track improvement over time. It also supports cross-Region aggregation for a unified view across your entire AWS footprint.&lt;/p&gt;

&lt;h3&gt;
  
  
  IAM Access Analyzer
&lt;/h3&gt;

&lt;p&gt;Access Analyzer focuses specifically on access issues using automated reasoning to identify external access. It performs three types of analysis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;External access&lt;/strong&gt;: Resources accessible outside your zone of trust&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internal access&lt;/strong&gt;: Which principals within your organization can access specific resources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unused access&lt;/strong&gt;: Unused roles, access keys, passwords, and permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also validates policies against IAM grammar and best practices before deployment, helping prevent misconfigurations proactively.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Trusted Advisor
&lt;/h3&gt;

&lt;p&gt;Trusted Advisor provides security checks including S3 bucket permissions, security group rules, IAM policies, MFA status, exposed access keys, and CloudTrail logging. Full security checks require Business or Enterprise Support plans.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with Security Hub&lt;/strong&gt;. Enable it with the Foundational Security Best Practices standard, then layer on Access Analyzer for deeper IAM analysis and Trusted Advisor for broader operational recommendations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;These 10 misconfigurations appear repeatedly because they're easy to create accidentally and hard to spot without systematic monitoring. The good news is that AWS provides the tools to detect and fix all of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with the Critical items today&lt;/strong&gt;: Enable S3 Block Public Access at the account level, verify root MFA, and audit your IAM policies for wildcards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enable Security Hub&lt;/strong&gt; with the Foundational Security Best Practices standard for continuous monitoring of all 10 issues across your accounts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most fixes take minutes&lt;/strong&gt; but prevent catastrophic breaches. A single public S3 bucket or overly permissive IAM policy can undo months of security work.&lt;/p&gt;

&lt;p&gt;For a deeper understanding of AWS security fundamentals, check out &lt;a href="https://towardsthecloud.com/blog/aws-account-best-practices" rel="noopener noreferrer"&gt;AWS account security fundamentals&lt;/a&gt; and &lt;a href="https://towardsthecloud.com/blog/aws-security-best-practices" rel="noopener noreferrer"&gt;comprehensive AWS security best practices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Quarterly security reviews catch drift before it becomes a problem. The misconfigurations I've covered aren't one-time fixes; they require ongoing vigilance as teams add resources, change configurations, and onboard new services.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>awssecurity</category>
      <category>securitymisconfigurations</category>
      <category>awsconfig</category>
      <category>securityhub</category>
    </item>
    <item>
      <title>Choosing an AWS Security Partner: The Honest Framework</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 17:30:04 +0000</pubDate>
      <link>https://forem.com/dannysteenman/choosing-an-aws-security-partner-the-honest-framework-1k47</link>
      <guid>https://forem.com/dannysteenman/choosing-an-aws-security-partner-the-honest-framework-1k47</guid>
      <description>&lt;p&gt;You've decided you need help with AWS security. That decision alone puts you ahead of most organizations who wait until after a breach. But here's the harder question: &lt;strong&gt;how do you pick the right AWS security partner without wasting months on the wrong one?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge is that everyone selling AWS security services sounds the same. They all claim "deep expertise," "proven experience," and "comprehensive solutions." Badges get thrown around. Logos get displayed. But how do you actually verify any of it?&lt;/p&gt;

&lt;p&gt;I've been on both sides of this conversation. As a boutique AWS partner ourselves, I've seen how the partner selection process works from the inside. And I'll be honest upfront: this guide will help you evaluate us against our own criteria. If we're not the right fit, I'd rather you know that now than waste both our time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you'll get from this guide&lt;/strong&gt;: A structured evaluation framework including a 10-point checklist, red flags to avoid, specific questions to ask in discovery calls (with guidance on what good answers look like), and transparent positioning on where different provider types, including us, fit best. For the technical foundation of what security partners actually implement, review our &lt;a href="https://towardsthecloud.com/blog/aws-security-best-practices" rel="noopener noreferrer"&gt;AWS security best practices&lt;/a&gt; guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signs You Actually Need an AWS Security Partner
&lt;/h2&gt;

&lt;p&gt;Before evaluating partners, let's confirm you're in the right place. Not every organization needs external security help. Here's how to know if you do.&lt;/p&gt;

&lt;h3&gt;
  
  
  When Internal Teams Hit Their Limits
&lt;/h3&gt;

&lt;p&gt;The trigger isn't usually capacity. It's expertise. Your team might be excellent at building applications but lack deep security knowledge. AWS has 30+ security services, and understanding when to use Amazon GuardDuty vs AWS Security Hub vs Amazon Inspector (vs all three together) requires specialized experience.&lt;/p&gt;

&lt;p&gt;Security misconfigurations are the leading cause of AWS breaches, ranging from IAM policies with wildcard actions allowing overly broad permissions to security groups allowing unrestricted access on critical ports. Your team might not have the visibility to catch these issues before they become incidents. &lt;a href="https://towardsthecloud.com/blog/aws-security-misconfigurations" rel="noopener noreferrer"&gt;Common AWS security misconfigurations&lt;/a&gt; often hide in plain sight because teams don't know what to look for.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Compliance Trigger
&lt;/h3&gt;

&lt;p&gt;Compliance deadlines create urgency that makes partner engagement obvious. SOC 2 audits, HIPAA assessments, PCI DSS certifications, and FedRAMP authorizations all require controls mapped to specific frameworks. AWS supports over 143 security standards and compliance certifications, but implementing the right controls for your specific requirements takes experience.&lt;/p&gt;

&lt;p&gt;Partners who've guided organizations through these audits know where teams typically struggle and how to avoid common pitfalls. They've seen what auditors actually focus on, not just what the frameworks say.&lt;/p&gt;

&lt;h3&gt;
  
  
  Post-Incident Reality Check
&lt;/h3&gt;

&lt;p&gt;After a security event, rapid response requires expertise you may not have. Incident response readiness gaps are common: no defined IR plan, lack of forensic readiness, and unclear escalation paths. AWS Security Incident Response Specialization Partners provide 24/7 monitoring, access to the AWS Customer Incident Response Team (CIRT), and pre-built runbooks for common scenarios.&lt;/p&gt;

&lt;p&gt;If you're dealing with the aftermath of a security incident, professional help isn't optional. It's essential for root cause analysis, remediation validation, and preventing recurrence.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Shared Responsibility Reality
&lt;/h3&gt;

&lt;p&gt;AWS operates under a &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/shared-responsibility.html" rel="noopener noreferrer"&gt;Shared Responsibility Model&lt;/a&gt;. AWS secures the infrastructure (security OF the cloud), but you're responsible for everything you deploy on it (security IN the cloud). This includes your IAM policies, security group configurations, S3 bucket settings, encryption choices, and application security.&lt;/p&gt;

&lt;p&gt;Partners add value specifically in your responsibility domain. They help you implement least-privilege access, configure proper detection and response, protect data, and maintain compliance. This is where most organizations struggle, and where experienced partners deliver real value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of AWS Security Providers (And Who They're Really For)
&lt;/h2&gt;

&lt;p&gt;Not all AWS security providers are the same. Understanding the categories helps you narrow your search to providers that actually match your situation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Big 4 and Large System Integrators
&lt;/h3&gt;

&lt;p&gt;Deloitte, Accenture, PwC, EY, and large SIs bring global scale and deep benches. They can staff large teams across time zones and have established relationships with enterprise compliance and procurement processes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Large enterprises with complex multi-year transformations, global compliance requirements across multiple jurisdictions, and organizations where procurement mandates large vendor relationships.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trade-offs&lt;/strong&gt;: Higher cost (often $300+/hour), junior staff frequently doing the actual work while seniors handle sales and oversight, longer engagement start times due to contracting complexity, and less flexibility for scope changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Boutique AWS Specialists
&lt;/h3&gt;

&lt;p&gt;Smaller firms (typically 10-100 people) with deep AWS focus. These partners often have senior engineers on every engagement because they don't have layers of junior staff to deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Mid-market companies needing specific AWS expertise, organizations wanting direct access to senior practitioners, faster engagement timelines, and teams that value knowledge transfer over dependency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trade-offs&lt;/strong&gt;: Limited capacity for very large engagements, may not cover every possible specialization, and availability can be constrained during busy periods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transparent note&lt;/strong&gt;: This is our category. We'll address our specific fit honestly in the final section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Independent Consultants
&lt;/h3&gt;

&lt;p&gt;Individual experts or very small teams (1-5 people) who work directly with clients. Often former Big Tech or enterprise security architects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Specific projects with well-defined scope, organizations with budget constraints, short engagements where a single expert is sufficient, and technical advisory roles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trade-offs&lt;/strong&gt;: Availability risk (one person can only do so much), limited capacity for ongoing work, no backup coverage if the consultant is unavailable, and less formal structure for compliance evidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Professional Services
&lt;/h3&gt;

&lt;p&gt;AWS's own consulting arm. They have unique access to internal AWS methodologies based on Amazon's internal practices and direct connection to AWS service teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for&lt;/strong&gt;: Complex migrations requiring direct AWS involvement, organizations that need AWS's endorsement for stakeholder confidence, and largest enterprises with budget for premium rates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trade-offs&lt;/strong&gt;: $300+/hour pricing puts it out of reach for most organizations, availability can be constrained by demand, and they may still recommend partners for implementation work. Read more about &lt;a href="https://towardsthecloud.com/blog/aws-professional-services" rel="noopener noreferrer"&gt;AWS Professional Services pricing and alternatives&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider Type&lt;/th&gt;
&lt;th&gt;Typical Size&lt;/th&gt;
&lt;th&gt;Cost Range&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;th&gt;Key Trade-off&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Big 4/SI&lt;/td&gt;
&lt;td&gt;Global&lt;/td&gt;
&lt;td&gt;$250-400+/hr&lt;/td&gt;
&lt;td&gt;Large enterprise, global compliance&lt;/td&gt;
&lt;td&gt;Junior staff, slow start&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boutique&lt;/td&gt;
&lt;td&gt;10-100 people&lt;/td&gt;
&lt;td&gt;$150-250/hr&lt;/td&gt;
&lt;td&gt;Mid-market, AWS depth&lt;/td&gt;
&lt;td&gt;Limited capacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Independent&lt;/td&gt;
&lt;td&gt;1-5 people&lt;/td&gt;
&lt;td&gt;$100-200/hr&lt;/td&gt;
&lt;td&gt;Specific projects&lt;/td&gt;
&lt;td&gt;Availability risk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS ProServe&lt;/td&gt;
&lt;td&gt;AWS&lt;/td&gt;
&lt;td&gt;$300+/hr&lt;/td&gt;
&lt;td&gt;Complex migrations&lt;/td&gt;
&lt;td&gt;Premium pricing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  10-Point Evaluation Checklist for AWS Security Partners
&lt;/h2&gt;

&lt;p&gt;With provider types understood, here's how to evaluate specific partners. These criteria separate qualified partners from those who just claim expertise.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Credentials That Actually Matter
&lt;/h3&gt;

&lt;p&gt;AWS Partner Network validations aren't marketing fluff. They represent genuine technical assessment by AWS. Here's what to verify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. AWS Security Competency or MSSP Competency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://aws.amazon.com/security/partner-solutions/" rel="noopener noreferrer"&gt;AWS Security Competency&lt;/a&gt; validates partners with deep expertise in securing AWS environments. The reimagined &lt;a href="https://aws.amazon.com/blogs/apn/updates-to-the-aws-mssp-competency-deliver-turnkey-security-solutions-for-customers/" rel="noopener noreferrer"&gt;AWS MSSP Competency&lt;/a&gt; (updated in 2025) covers seven categories: Infrastructure Security, Workload Security, Application Security, Data Protection, Identity &amp;amp; Access Management, Incident Response, and Cyber Recovery. Verify claims directly on the AWS Partner Solutions page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Partner tier level (Select, Advanced, or Premier)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Higher tiers require more customer success evidence and technical validation. Select tier is minimum for Security Hub integration and competency eligibility. Advanced and Premier indicate deeper AWS investment and proven customer outcomes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Foundational Technical Review (FTR) completed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Partners with the "Reviewed by AWS" badge have passed AWS's technical validation process. FTR is required for access to AWS Partner Network programs, funding programs, and the AWS Competency Program. Partners without it haven't met AWS's technical bar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. AWS Certified Security - Specialty holders on team&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The AWS Certified Security - Specialty (SCS-C03, updated December 2025 with enhanced AI/ML security focus) validates deep security knowledge. Ask how many team members hold this certification and whether certified individuals will work on your project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Service Delivery designations for relevant services&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AWS validates partners with deep experience in specific services. Security-relevant Service Delivery designations include AWS WAF, AWS Config, AWS Control Tower, AWS Security Hub, and Amazon GuardDuty. These indicate proven implementation experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Depth Indicators
&lt;/h3&gt;

&lt;p&gt;Credentials establish eligibility. These criteria verify actual technical capability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. AWS Well-Architected Review capability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Partners should be trained to conduct &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/welcome.html" rel="noopener noreferrer"&gt;AWS Well-Architected Reviews&lt;/a&gt;, specifically the Security Pillar with its seven design principles and seven best practice areas. Ask for examples of Security Pillar findings they've remediated for clients.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Multi-account and multi-region expertise&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Real AWS security requires understanding AWS Organizations, Control Tower, centralized logging, cross-account IAM, and Service Control Policies. If your environment spans multiple accounts, partners must demonstrate this expertise. Review &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-strategy" rel="noopener noreferrer"&gt;AWS multi-account security architecture&lt;/a&gt; to understand what to look for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Automation capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Security that depends on manual processes fails at scale. Partners should demonstrate infrastructure as code experience (CDK, Terraform, CloudFormation), AWS Config rules for automated compliance, and Security Hub automation for response orchestration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delivery Model Fit
&lt;/h3&gt;

&lt;p&gt;Technical skills matter, but so does how the engagement actually works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Engagement model matches your needs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consulting (project-based), retainer (ongoing advisory), or managed services (they operate it for you) represent different engagement models. Choose based on your internal capabilities and preferences. If you want to build internal capability, pure managed services might create dependency rather than growth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Knowledge transfer included as explicit deliverable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good partners make you more capable, not more dependent. Documentation, training sessions, and enablement should be explicit deliverables, not afterthoughts. If knowledge transfer isn't mentioned in the proposal, ask about it directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Red Flags When Evaluating Security Partners
&lt;/h2&gt;

&lt;p&gt;Knowing what to look for is half the equation. Here's what should make you walk away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cannot verify AWS credentials on the AWS Partner Solutions page.&lt;/strong&gt; Every competency, specialization, and Service Delivery designation is publicly verifiable. If a partner claims credentials that don't appear on AWS's site, that's a major red flag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Senior staff sells, junior staff delivers.&lt;/strong&gt; The architect who impresses you in the sales presentation should be the one working on your project. Ask specifically: "Who will be doing the actual work on our engagement?" If the answer is vague or references "our team," dig deeper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No customer references in your industry or scale.&lt;/strong&gt; Partners should be able to provide references from similar organizations. "Trust us, we're great" isn't evidence. No references means no proven track record you can validate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overpromising on compliance outcomes.&lt;/strong&gt; No partner can guarantee you'll pass an audit. They can improve your chances significantly, but compliance ultimately depends on your organization's implementation and evidence. Guarantees indicate either dishonesty or lack of compliance experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lock-in through complexity.&lt;/strong&gt; Good partners simplify your environment and make it more maintainable. If a proposed solution creates dependencies you can't manage yourself, that's a feature for them and a bug for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero knowledge transfer in the proposal.&lt;/strong&gt; If the engagement doesn't explicitly include documentation, training, or enablement, you're being set up for ongoing dependency rather than growing internal capability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cookie-cutter solutions without discovery.&lt;/strong&gt; Your environment isn't identical to everyone else's. Partners who propose solutions before understanding your specific situation are selling a product, not providing expertise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions to Ask in Discovery Calls (And What Good Answers Look Like)
&lt;/h2&gt;

&lt;p&gt;Use these questions to dig beneath surface-level sales pitches. I've included guidance on what good answers actually sound like. For transparency on what our security review process entails, see our &lt;a href="https://towardsthecloud.com/blog/aws-security-review-process" rel="noopener noreferrer"&gt;AWS security review process guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation Questions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;"Which AWS Security Competency categories are you validated in?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good answer: Specific categories with verification instructions. "We hold AWS Security Competency and MSSP Competency in Infrastructure Security and Data Protection. You can verify this on the AWS Partner Solutions page by searching our company name."&lt;/p&gt;

&lt;p&gt;Bad answer: Vague references to being an "AWS Partner" without specifics, or inability to point you to verification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"How many team members hold AWS Certified Security - Specialty?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good answer: Specific numbers with context. "We have 4 Security Specialty certified engineers out of our team of 12, and two of them would be assigned to your project."&lt;/p&gt;

&lt;p&gt;Bad answer: "Our team is highly certified" without specifics, or deflection to other certifications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Can you share customer references in our industry?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good answer: "Yes, we've worked with three SaaS companies similar to your size going through SOC 2. I can connect you with two of them after we sign an NDA."&lt;/p&gt;

&lt;p&gt;Bad answer: "We have extensive experience" without specific references, or only references from vastly different industries/scales.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Capability Questions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;"Are you trained to conduct AWS Well-Architected Reviews?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good answer: "Yes, we're AWS Well-Architected Partners. In Security Pillar reviews, we commonly find issues around unused IAM permissions, missing VPC Flow Logs, and encryption gaps. Here's an example of findings we remediated for a client."&lt;/p&gt;

&lt;p&gt;Bad answer: Unfamiliarity with the Well-Architected Framework or inability to discuss Security Pillar specifics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"How do you approach multi-account security management?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good answer: References to &lt;a href="https://towardsthecloud.com/blog/aws-organizations-best-practices" rel="noopener noreferrer"&gt;AWS Organizations governance&lt;/a&gt;, Control Tower, centralized logging to a dedicated Security account, cross-account IAM roles, and Service Control Policies. Specific examples of multi-account architectures they've implemented.&lt;/p&gt;

&lt;p&gt;Bad answer: Single-account focused answers or unfamiliarity with AWS Organizations features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"What's your automation approach for security controls?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good answer: Specific tools and patterns. "We implement security controls using CDK with cdk-nag for compliance validation, AWS Config rules for continuous monitoring, and Security Hub automation rules for response. Everything is version-controlled and can be reviewed by your team."&lt;/p&gt;

&lt;p&gt;Bad answer: Manual processes or vague references to "automation" without specifics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Engagement Model Questions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;"Who specifically will work on our project?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good answer: Named individuals with credentials. "John, our principal security architect (Security Specialty certified), will lead the engagement. Sarah, a senior engineer (Solutions Architect Professional), will handle implementation. Both will be on your calls."&lt;/p&gt;

&lt;p&gt;Bad answer: "Our team will be assigned" without naming individuals, or names without credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"How do you handle knowledge transfer?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good answer: "Knowledge transfer is an explicit deliverable. We provide documentation, two training sessions for your team during the engagement, and a recorded walkthrough of everything we implement. The goal is that your team can maintain and extend the work after we're done."&lt;/p&gt;

&lt;p&gt;Bad answer: Knowledge transfer not mentioned, or treated as an afterthought rather than a core deliverable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"What happens after the initial engagement?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good answer: "We provide 30 days of support after engagement completion. For ongoing needs, we offer retainer options, but our goal is that you don't need us for day-to-day operations. The implementation should be self-documenting and maintainable by your team."&lt;/p&gt;

&lt;p&gt;Bad answer: Immediately pitching ongoing managed services, or answers that imply you'll always need them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Price vs Value: Understanding Engagement Models
&lt;/h2&gt;

&lt;p&gt;AWS doesn't publish partner pricing benchmarks, which makes this conversation harder than it should be. Here's what I can share based on market experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Pricing Structures
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Hourly consulting ($100-300+/hour)&lt;/strong&gt; is typical for advisory work and project-based engagements. Boutique partners usually fall in the $150-250 range, while Big 4 and AWS Professional Services command $250-400+.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project-based pricing&lt;/strong&gt; (fixed price for defined scope) works well for assessments, security reviews, and specific remediation projects. This shifts risk to the partner but requires clear scope definition upfront.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monthly retainer&lt;/strong&gt; provides ongoing advisory or fractional security leadership. Good for organizations that need regular guidance but can't justify full-time security hires.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Percentage of AWS spend&lt;/strong&gt; is common for MSSP (managed security) arrangements where partners take operational responsibility for security monitoring and response.&lt;/p&gt;

&lt;h3&gt;
  
  
  When Premium Makes Sense (And When It Doesn't)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Premium pricing is justified when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Critical compliance deadlines create urgency (SOC 2 audit in 60 days)&lt;/li&gt;
&lt;li&gt;Complex multi-account environments require deep expertise&lt;/li&gt;
&lt;li&gt;Active security incidents need immediate response&lt;/li&gt;
&lt;li&gt;Your industry requires specific compliance knowledge (healthcare, financial services)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Premium pricing is less justified when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard security assessments with flexible timelines&lt;/li&gt;
&lt;li&gt;Well-defined projects with clear scope&lt;/li&gt;
&lt;li&gt;Your internal team can handle implementation with advisory guidance&lt;/li&gt;
&lt;li&gt;You have time to build internal capability rather than outsource&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The value question&lt;/strong&gt;: Beyond hourly rates, evaluate what capability you build vs. what you outsource. An engagement that costs more but leaves your team more capable may deliver better long-term value than a cheaper engagement that creates dependency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Approach: Transparent Self-Positioning
&lt;/h2&gt;

&lt;p&gt;I promised honesty about where we fit, so here it is.&lt;/p&gt;

&lt;h3&gt;
  
  
  What We Do Well
&lt;/h3&gt;

&lt;p&gt;Towards the Cloud is a boutique AWS consultancy. Our engagement model means senior engineers on every project, not junior staff doing the work while seniors manage accounts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our strengths:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS-native architecture using CDK and infrastructure as code&lt;/li&gt;
&lt;li&gt;Multi-account security foundations and landing zones&lt;/li&gt;
&lt;li&gt;SOC 2 preparation and security review processes&lt;/li&gt;
&lt;li&gt;Direct access to decision-makers (you talk to the people doing the work)&lt;/li&gt;
&lt;li&gt;Knowledge transfer as explicit focus (we want you to learn, not depend)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a transparent breakdown of what our security review process looks like from discovery call through deliverables, see our &lt;a href="https://towardsthecloud.com/blog/aws-security-review-process" rel="noopener noreferrer"&gt;AWS security review process guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We've helped organizations establish secure AWS foundations, prepare for compliance audits, and implement the security controls that make auditors happy and keep data protected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who We're Not Right For
&lt;/h3&gt;

&lt;p&gt;Here's where honesty matters most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We're probably not the right fit if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need global 24/7 managed security operations (we're a small team in European time zones)&lt;/li&gt;
&lt;li&gt;You're a large enterprise requiring Big 4 relationships for procurement or stakeholder confidence&lt;/li&gt;
&lt;li&gt;You need purely managed security where someone else operates everything (we're consulting-focused)&lt;/li&gt;
&lt;li&gt;Your industry requires specialized certifications we don't hold (FedRAMP, specific government clearances)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If this sounds like you&lt;/strong&gt;, consider the Big 4 (Deloitte, Accenture, PwC) for enterprise requirements or AWS MSSP Competency partners for managed security operations. These providers exist for good reasons, and they may be better suited to your specific needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making Your Decision
&lt;/h2&gt;

&lt;p&gt;Choosing an AWS security partner isn't about finding the "best" provider. It's about finding the right fit for your specific situation, timeline, and internal capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use the 10-point checklist&lt;/strong&gt; to evaluate any partner you're considering, including us. Verify credentials on AWS's Partner Solutions page. Ask the discovery call questions and listen for specific, evidence-backed answers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch for red flags&lt;/strong&gt; that indicate a partner might create problems rather than solve them. Trust your instincts when something feels off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Match provider type to your needs&lt;/strong&gt;: Big 4 for enterprise complexity, boutique specialists for AWS depth and senior access, independents for specific projects, AWS ProServe for direct AWS involvement.&lt;/p&gt;

&lt;p&gt;The right partner will make your AWS environment more secure, more compliant, and more manageable. The wrong partner will create complexity, dependency, and frustration.&lt;/p&gt;

&lt;p&gt;If you want to evaluate your current security posture before engaging any partner, start with our &lt;a href="https://towardsthecloud.com/blog/aws-security-review-checklist" rel="noopener noreferrer"&gt;AWS security review checklist&lt;/a&gt;. It's the same framework we use for paid engagements, and it will help you understand where you stand.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>awssecurity</category>
      <category>awspartner</category>
      <category>securityconsulting</category>
      <category>awscompetency</category>
    </item>
    <item>
      <title>AWS CDK Best Practices: The Complete Guide [2026]</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 17:29:00 +0000</pubDate>
      <link>https://forem.com/dannysteenman/aws-cdk-best-practices-the-complete-guide-2026-2nhg</link>
      <guid>https://forem.com/dannysteenman/aws-cdk-best-practices-the-complete-guide-2026-2nhg</guid>
      <description>&lt;p&gt;Most CDK tutorials teach you how to deploy your first Lambda function. Few prepare you for what happens when your team grows to 10 engineers, your stacks multiply to 50, and a refactoring mistake deletes your production database.&lt;/p&gt;

&lt;p&gt;This guide covers the AWS CDK best practices that prevent those disasters. By the end, you'll understand AWS's official best practice categories, know how to structure projects with Projen (yes, it's a necessity, not optional), test your infrastructure code, implement security guardrails with cdk-nag, and avoid the anti-patterns that cause production incidents.&lt;/p&gt;

&lt;p&gt;I've based these recommendations on AWS's official documentation, the AWS re:Invent 2023 advanced CDK session (embedded below), and the patterns I've implemented in the &lt;a href="https://github.com/towardsthecloud/aws-cdk-starter-kit" rel="noopener noreferrer"&gt;aws-cdk-starter-kit&lt;/a&gt; that you can use as a reference implementation.&lt;/p&gt;

&lt;p&gt;If you're new to CDK, start with our &lt;a href="https://towardsthecloud.com/blog/aws-cdk" rel="noopener noreferrer"&gt;beginner's guide to AWS CDK&lt;/a&gt; and &lt;a href="https://towardsthecloud.com/blog/install-aws-cdk" rel="noopener noreferrer"&gt;install AWS CDK&lt;/a&gt; before diving into best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why CDK Best Practices Matter
&lt;/h2&gt;

&lt;p&gt;Before diving into tactical advice, let me explain why investing time in best practices pays dividends.&lt;/p&gt;

&lt;p&gt;The AWS CDK was built around a model where your entire application is defined in code, not just business logic but also infrastructure and configuration. At deployment time, CDK synthesizes a cloud assembly containing CloudFormation templates for all target environments plus file assets like Lambda code and Docker images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This everything-in-code model is powerful but dangerous without guardrails.&lt;/strong&gt; Every commit in your main branch represents a complete, deployable version of your application. That's great for automation but means mistakes propagate quickly.&lt;/p&gt;

&lt;p&gt;The difference between a working CDK app and a production-ready CDK app comes down to following proven patterns that prevent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data loss from logical ID changes that accidentally replace databases&lt;/li&gt;
&lt;li&gt;Security incidents from overly permissive IAM policies&lt;/li&gt;
&lt;li&gt;Cost explosions from untagged resources and orphaned assets&lt;/li&gt;
&lt;li&gt;Deployment failures from circular dependencies and oversized stacks&lt;/li&gt;
&lt;li&gt;Team friction from unclear ownership boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Cost of Ignoring Best Practices
&lt;/h3&gt;

&lt;p&gt;Let me give you some concrete examples of what goes wrong without best practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logical ID changes destroy stateful resources.&lt;/strong&gt; In CDK, every resource gets a logical ID derived from its construct ID and position in the tree. Change either one, and CloudFormation sees it as a new resource, replacing the old one. For a DynamoDB table or RDS database, "replace" means "delete the old one and create a new empty one." I've seen teams lose production data this way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardcoded names prevent multi-environment deployment.&lt;/strong&gt; If you hardcode &lt;code&gt;bucketName: 'my-app-assets'&lt;/code&gt;, you can't deploy the same stack twice in the same account, not for dev/staging/prod environments, not even for testing. Names are precious resources in AWS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Untested infrastructure breaks production.&lt;/strong&gt; Without tests asserting your Lambda has the right memory configuration or your security group allows the correct ports, you're deploying blind. CloudFormation will happily deploy misconfigured infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS's Four Categories of Best Practices
&lt;/h3&gt;

&lt;p&gt;AWS organizes CDK best practices into four broad categories that I'll cover throughout this guide:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Organization best practices&lt;/strong&gt;: How to structure teams and adoption at the organizational level&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coding best practices&lt;/strong&gt;: How to organize CDK code, repositories, and packages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Construct best practices&lt;/strong&gt;: How to develop reusable, composable constructs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application best practices&lt;/strong&gt;: How to combine constructs and make architectural decisions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you understand why best practices matter, let's start with the foundation: how you structure your CDK project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Structure and Projen (Essential Tooling)
&lt;/h2&gt;

&lt;p&gt;Project structure might seem like a minor concern, but it determines how maintainable your CDK application becomes as it grows. More importantly, how you manage that structure matters even more than the structure itself.&lt;/p&gt;

&lt;p&gt;I'm going to make a strong statement here: &lt;strong&gt;Projen is a necessity for CDK projects, not an optional nice-to-have.&lt;/strong&gt; If you're still manually maintaining &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;tsconfig.json&lt;/code&gt;, and other configuration files, you're creating technical debt that will slow you down.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Projen is a Necessity, Not Optional
&lt;/h3&gt;

&lt;p&gt;Let me explain why manual configuration management is an anti-pattern.&lt;/p&gt;

&lt;p&gt;When you run &lt;code&gt;cdk init&lt;/code&gt;, you get a basic project with configuration files you're expected to maintain by hand. This works fine for a weekend project. But in a team environment, those files drift. Someone updates a dependency in &lt;code&gt;package.json&lt;/code&gt; but forgets to update &lt;code&gt;tsconfig.json&lt;/code&gt;. Someone else copies configuration from Stack Overflow without understanding it. Six months later, you have a mess of conflicting settings that nobody fully understands.&lt;/p&gt;

&lt;p&gt;Projen solves this by treating configuration as code. Instead of editing &lt;code&gt;package.json&lt;/code&gt; directly, you define your project in a &lt;code&gt;.projenrc.ts&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;awscdk&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;projen&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;awscdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AwsCdkTypeScriptApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;cdkVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2.175.0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;defaultReleaseBranch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;main&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-cdk-app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;projenrcTs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="c1"&gt;// Dependencies&lt;/span&gt;
  &lt;span class="na"&gt;deps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-cdk/aws-lambda-python-alpha&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;devDeps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cdk-nag&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="c1"&gt;// Testing&lt;/span&gt;
  &lt;span class="na"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;jestOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;jestConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;testMatch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;**/*.test.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;// Linting&lt;/span&gt;
  &lt;span class="na"&gt;eslint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;prettier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;synth&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;npx projen&lt;/code&gt;, and Projen generates all your configuration files consistently. The generated files include a warning not to edit them manually, because Projen owns them.&lt;/p&gt;

&lt;p&gt;This approach provides several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No configuration drift&lt;/strong&gt;: Every team member gets identical configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated dependency management&lt;/strong&gt;: Projen keeps dependencies compatible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in best practices&lt;/strong&gt;: ESLint, Jest, and TypeScript are pre-configured correctly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy upgrades&lt;/strong&gt;: Update the Projen version to get the latest recommended settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Projen isn't some obscure tool either. It's the underlying technology for blueprint synthesis in Amazon CodeCatalyst. AWS uses it internally because manual configuration doesn't scale.&lt;/p&gt;

&lt;p&gt;For a deep dive on project organization patterns, see my &lt;a href="https://towardsthecloud.com/blog/aws-cdk-project-structure" rel="noopener noreferrer"&gt;detailed guide on structuring your CDK project&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The aws-cdk-starter-kit: Your Reference Implementation
&lt;/h3&gt;

&lt;p&gt;Rather than just telling you what best practices look like, I've created a reference implementation you can clone and study: the &lt;a href="https://github.com/towardsthecloud/aws-cdk-starter-kit" rel="noopener noreferrer"&gt;aws-cdk-starter-kit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This repository demonstrates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Projen configuration&lt;/strong&gt; for CDK TypeScript projects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Project structure&lt;/strong&gt; that scales from starter to enterprise&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing setup&lt;/strong&gt; with Jest and CDK assertions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security validation&lt;/strong&gt; with cdk-nag integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD workflows&lt;/strong&gt; using GitHub Actions with OpenID Connect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use it as a starting point for new projects or as a reference when restructuring existing ones. The starter kit implements every best practice covered in this guide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repository Organization Patterns
&lt;/h3&gt;

&lt;p&gt;AWS recommends that every CDK application starts with a single package in a single repository. This keeps things simple and avoids premature complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resist the urge to put multiple applications in the same repository&lt;/strong&gt;, especially if you're using automated pipelines. Here's why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changes to one application trigger deployment of all applications&lt;/li&gt;
&lt;li&gt;A broken build in one app prevents deployment of others&lt;/li&gt;
&lt;li&gt;The "blast radius" of any change increases dramatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you need to share code between applications, move shared constructs to their own repository and publish them as packages via CodeArtifact or npm. Shared packages require their own testing strategy because they must be validated independently from the applications that consume them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure and Runtime Code Colocation
&lt;/h3&gt;

&lt;p&gt;One of CDK's superpowers is bundling runtime code (Lambda functions, Docker images) alongside infrastructure definitions. Embrace this by colocating related code in self-contained constructs.&lt;/p&gt;

&lt;p&gt;For example, a construct that creates a Lambda function should include the Lambda's source code in the same directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lib/
├── api-handler/
│   ├── api-handler-construct.ts    # CDK construct
│   ├── handler.ts                  # Lambda runtime code
│   └── handler.test.ts             # Lambda unit tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This colocation enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Synchronized versioning&lt;/strong&gt;: Infrastructure and code evolve together&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolated testing&lt;/strong&gt;: Test the construct and its runtime code independently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy sharing&lt;/strong&gt;: Publish the entire construct as a reusable package&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With your project properly structured, let's dive into how to design constructs effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Construct Design Best Practices
&lt;/h2&gt;

&lt;p&gt;Constructs are the building blocks of every CDK application. Understanding how to design and use them correctly determines whether your infrastructure code is reusable and maintainable or a tangled mess.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding L1, L2, and L3 Constructs
&lt;/h3&gt;

&lt;p&gt;AWS CDK constructs come in three levels of abstraction, and knowing when to use each is fundamental to CDK development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L1 Constructs (CFN Resources)&lt;/strong&gt; map directly to single CloudFormation resources. They're named with a &lt;code&gt;Cfn&lt;/code&gt; prefix (like &lt;code&gt;CfnBucket&lt;/code&gt;) and offer no abstraction. You get complete control over every property, but you're responsible for all the configuration. New CloudFormation resources become available as L1 constructs within about a week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L2 Constructs (Curated Constructs)&lt;/strong&gt; provide a higher-level, intent-based API with sensible defaults. A &lt;code&gt;Bucket&lt;/code&gt; (L2) versus &lt;code&gt;CfnBucket&lt;/code&gt; (L1) includes best-practice security policies by default, helper methods for permissions (&lt;code&gt;.grantRead()&lt;/code&gt;), and generates boilerplate automatically. Most of your CDK code should use L2 constructs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L3 Constructs (Patterns)&lt;/strong&gt; combine multiple resources into complete architectures. &lt;code&gt;ApplicationLoadBalancedFargateService&lt;/code&gt; creates a Fargate service with a load balancer, target groups, security groups, and IAM roles, all properly configured to work together.&lt;/p&gt;

&lt;p&gt;For a comprehensive explanation of construct levels with code examples, see my &lt;a href="https://towardsthecloud.com/blog/aws-cdk-construct" rel="noopener noreferrer"&gt;deep dive on CDK constructs&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model with Constructs, Deploy with Stacks
&lt;/h3&gt;

&lt;p&gt;This principle from AWS is worth memorizing: &lt;strong&gt;Model your application with constructs, but use stacks only for deployment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everything in a &lt;a href="https://towardsthecloud.com/blog/aws-cdk-stack" rel="noopener noreferrer"&gt;CDK stack&lt;/a&gt; deploys together. If you model your website as a Stack containing S3, API Gateway, Lambda, and RDS, you can't reuse that website in another context without copying code.&lt;/p&gt;

&lt;p&gt;Instead, model the website as a Construct containing those resources. Then instantiate that construct in stacks for different deployment scenarios:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The construct models the application&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WebsiteConstruct&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;WebsiteProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// S3, API Gateway, Lambda, RDS defined here&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Stacks define deployment boundaries&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DevStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebsiteConstruct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Website&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProdStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebsiteConstruct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Website&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation improves reusability, testing, and modularity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Protecting Logical IDs for Stateful Resources
&lt;/h3&gt;

&lt;p&gt;Every resource in CDK gets a logical ID derived from its construct ID and position in the construct tree. &lt;strong&gt;Changing a logical ID causes CloudFormation to replace the resource&lt;/strong&gt;, which for stateful resources like databases means data loss.&lt;/p&gt;

&lt;p&gt;Protect yourself by writing unit tests that assert logical IDs remain stable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;database logical ID remains stable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TestStack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// This test fails if you accidentally rename the database construct&lt;/span&gt;
  &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AWS::DynamoDB::Table&lt;/span&gt;&lt;span class="dl"&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;// Asserts the logical ID contains 'UserTable'&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to rename constructs or move resources between stacks, use the new &lt;strong&gt;CDK Refactor&lt;/strong&gt; feature (available since September 2025) which safely reorganizes infrastructure without replacing resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constructs Aren't Enough for Compliance
&lt;/h3&gt;

&lt;p&gt;Many enterprises create wrapper constructs (sometimes called L2+ constructs) that enforce security policies like encryption or specific IAM configurations. While useful for surfacing guidance early in development, &lt;strong&gt;don't rely on wrapper constructs as your sole compliance mechanism&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Developers can bypass your wrappers by using L1 constructs directly or third-party constructs from Construct Hub. Instead, enforce compliance at multiple levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service Control Policies (SCPs)&lt;/strong&gt; and permission boundaries at the AWS Organizations level&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cdk-nag&lt;/strong&gt; to validate constructs before deployment (covered below)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudFormation Guard&lt;/strong&gt; for template-level validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aspects&lt;/strong&gt; to apply cross-cutting validations to all constructs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you understand construct design, let's look at the coding patterns that keep your CDK code maintainable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding Best Practices
&lt;/h2&gt;

&lt;p&gt;These coding patterns apply to all CDK projects regardless of size. Following them from the start saves significant refactoring later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start Simple, Add Complexity Only When Needed
&lt;/h3&gt;

&lt;p&gt;The guiding principle from AWS is simple: keep things as simple as possible, but no simpler. Don't architect for every possible scenario upfront. CDK enables refactoring, so you can add complexity when requirements actually demand it.&lt;/p&gt;

&lt;p&gt;If you're building a single Lambda function, don't create an abstract "FunctionFactory" pattern on day one. Start with the simplest thing that works. Add abstraction when you have a second, third, or fourth function that genuinely needs it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make Decisions at Synthesis Time
&lt;/h3&gt;

&lt;p&gt;Although CloudFormation supports deploy-time decisions using Conditions, &lt;code&gt;Fn::If&lt;/code&gt;, and Parameters, AWS recommends against using them with CDK. The types of values and operations available in CloudFormation conditions are limited compared to TypeScript or Python.&lt;/p&gt;

&lt;p&gt;Instead, make all decisions in your CDK code using programming language features:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Good: Decision at synthesis time&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prod&lt;/span&gt;&lt;span class="dl"&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;new&lt;/span&gt; &lt;span class="nc"&gt;Alarm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HighErrorAlarm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;evaluationPeriods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&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;// Avoid: CloudFormation conditions&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isProd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CfnCondition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IsProd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;conditionEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Treat CloudFormation as an implementation detail for reliable deployments, not as a programming language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Generated Resource Names
&lt;/h3&gt;

&lt;p&gt;Hardcoding resource names like &lt;code&gt;bucketName: 'my-app-data'&lt;/code&gt; creates several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can't deploy the stack twice in the same account (dev and prod environments)&lt;/li&gt;
&lt;li&gt;You can't replace the resource if an immutable property changes&lt;/li&gt;
&lt;li&gt;CloudFormation can't safely replace resources (old and new need the same name)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let CDK generate names instead. Pass generated names to consumers through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Environment variables for Lambda functions&lt;/li&gt;
&lt;li&gt;AWS Systems Manager Parameter Store&lt;/li&gt;
&lt;li&gt;References between stacks in the same CDK app&lt;/li&gt;
&lt;li&gt;Static &lt;code&gt;from&lt;/code&gt; methods like &lt;code&gt;Table.fromTableArn()&lt;/code&gt; for cross-app references&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Define Removal Policies for Stateful Resources
&lt;/h3&gt;

&lt;p&gt;By default, CloudFormation retains stateful resources when you delete a stack, leaving orphaned S3 buckets and DynamoDB tables in your account. CDK provides explicit removal policies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DataBucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;removalPolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RemovalPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RETAIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Default: keeps bucket on stack delete&lt;/span&gt;
  &lt;span class="c1"&gt;// RemovalPolicy.DESTROY, // Deletes bucket when stack is deleted&lt;/span&gt;
  &lt;span class="c1"&gt;// RemovalPolicy.SNAPSHOT, // For databases: snapshot before delete&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For resources that don't expose a &lt;code&gt;removalPolicy&lt;/code&gt; prop, use the escape hatch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cfnBucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Resource&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;CfnBucket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;cfnBucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;applyRemovalPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;RemovalPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DESTROY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure with Properties, Not Environment Variables
&lt;/h3&gt;

&lt;p&gt;Environment variable lookups inside constructs are a common anti-pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Anti-pattern: Creates machine dependency&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyConstruct&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ENVIRONMENT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Don't do this&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a dependency on the machine where synthesis runs and introduces configuration that lives outside your codebase.&lt;/p&gt;

&lt;p&gt;Instead, accept configuration through a properties object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Good: Full configurability in code&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;MyConstructProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyConstruct&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MyConstructProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Configuration explicit in code&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Environment variables should be limited to the top-level of your CDK app for development convenience, never inside constructs or stacks.&lt;/p&gt;

&lt;p&gt;Writing good code is only half the battle. Next, let's ensure your CDK code actually works as expected through testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Your CDK Code
&lt;/h2&gt;

&lt;p&gt;Testing infrastructure code might seem unusual if you're used to only testing application logic. But CDK makes infrastructure testable, and you should take advantage of that.&lt;/p&gt;

&lt;p&gt;Untested CDK code is a liability. You're trusting that your Lambda has the right memory, your security group allows the correct ports, and your IAM policies follow least privilege, all without verification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two Testing Approaches: Assertions vs Snapshots
&lt;/h3&gt;

&lt;p&gt;The CDK assertions module supports two complementary testing approaches:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fine-grained assertions&lt;/strong&gt; test specific aspects of your synthesized CloudFormation templates. They're useful for verifying critical properties and catching regressions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lambda function has correct memory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TestStack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasResourceProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AWS::Lambda::Function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;MemorySize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Snapshot tests&lt;/strong&gt; compare your entire synthesized template against a stored baseline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stack matches snapshot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TestStack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toJSON&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;toMatchSnapshot&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Snapshots enable confident refactoring because any template change triggers a test failure. However, CDK version upgrades can change generated templates, so don't rely solely on snapshots.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up Your Testing Framework
&lt;/h3&gt;

&lt;p&gt;For TypeScript projects, CDK uses Jest. If you're using Projen (which you should be), testing is already configured. Otherwise, add these dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^29.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^29.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ts-jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^29.0.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create tests following the naming convention &lt;code&gt;*.test.ts&lt;/code&gt; in your &lt;code&gt;test/&lt;/code&gt; directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fine-Grained Assertion Examples
&lt;/h3&gt;

&lt;p&gt;Here are practical examples of assertions you should write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Match&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib/assertions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyStack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../lib/my-stack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyStack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;beforeAll&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;TestStack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;S3 bucket has encryption enabled&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasResourceProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AWS::S3::Bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;BucketEncryption&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;ServerSideEncryptionConfiguration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayWith&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
          &lt;span class="nx"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectLike&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;ServerSideEncryptionByDefault&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;SSEAlgorithm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws:kms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="p"&gt;]),&lt;/span&gt;
      &lt;span class="p"&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;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lambda function uses correct runtime&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasResourceProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AWS::Lambda::Function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nodejs20.x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;IAM role follows least privilege&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasResourceProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AWS::IAM::Policy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;PolicyDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayWith&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
          &lt;span class="nx"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectLike&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;Effect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Allow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayWith&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s3:GetObject&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
            &lt;span class="c1"&gt;// Not s3:* or s3:GetObject*&lt;/span&gt;
          &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="p"&gt;]),&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Integration Testing with integ-tests-alpha
&lt;/h3&gt;

&lt;p&gt;For testing that requires actual AWS resources, use the &lt;code&gt;@aws-cdk/integ-tests-alpha&lt;/code&gt; module. Integration tests deploy real infrastructure and verify behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IntegTest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ExpectedResult&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-cdk/integ-tests-alpha&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;integ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntegTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ApiIntegTest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;testCases&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Make assertions against deployed resources&lt;/span&gt;
&lt;span class="nx"&gt;integ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assertions&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;httpApiCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/health&lt;/span&gt;&lt;span class="dl"&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;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ExpectedResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectLike&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Integration tests are slower and cost money (they deploy real resources), so use them sparingly for critical paths.&lt;/p&gt;

&lt;p&gt;With tested infrastructure, let's ensure it's also secure with CDK's security features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security and Compliance Best Practices
&lt;/h2&gt;

&lt;p&gt;Security in CDK goes beyond writing secure code. It includes managing permissions for deployments, enforcing least privilege between resources, and validating infrastructure before it reaches production.&lt;/p&gt;

&lt;h3&gt;
  
  
  IAM Best Practices and Grant Methods
&lt;/h3&gt;

&lt;p&gt;L2 constructs provide &lt;code&gt;grant&lt;/code&gt; methods that create least-privilege IAM policies automatically. Always prefer these over manual policy definitions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Good: Uses grant method for least privilege&lt;/span&gt;
&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grantRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lambdaFunction&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Also good: Specific permissions when needed&lt;/span&gt;
&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grantReadWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lambdaFunction&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Avoid: Overly permissive manual policies&lt;/span&gt;
&lt;span class="nx"&gt;lambdaFunction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addToRolePolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PolicyStatement&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s3:*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Too permissive&lt;/span&gt;
  &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;   &lt;span class="c1"&gt;// Too broad&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each grant method creates a unique IAM role with only the permissions needed. If you need custom permissions, be explicit about actions and resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;lambdaFunction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addToRolePolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PolicyStatement&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s3:GetObject&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s3:ListBucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arnForObjects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Validating with cdk-nag
&lt;/h3&gt;

&lt;p&gt;cdk-nag is an open-source tool that checks your CDK applications against compliance rule packs. It uses CDK Aspects to validate every construct in your application.&lt;/p&gt;

&lt;p&gt;Available rule packs include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS Solutions&lt;/strong&gt;: General AWS best practices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HIPAA Security&lt;/strong&gt;: Healthcare compliance rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NIST 800-53 rev 4/5&lt;/strong&gt;: Government security controls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PCI DSS 3.2.1&lt;/strong&gt;: Payment card industry standards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add cdk-nag to your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AwsSolutionsChecks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HIPAASecurityChecks&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cdk-nag&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Aspects&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Apply compliance checks to all stacks&lt;/span&gt;
&lt;span class="nx"&gt;Aspects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AwsSolutionsChecks&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;verbose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="nx"&gt;Aspects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HIPAASecurityChecks&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;verbose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cdk-nag reports violations during synthesis, catching issues before deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Error at /MyStack/Bucket/Resource] AwsSolutions-S1: The S3 Bucket does not have server access logging enabled.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can suppress specific rules when you have a valid reason:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NagSuppressions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cdk-nag&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;NagSuppressions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addResourceSuppressions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AwsSolutions-S1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Access logging handled by CloudTrail data events&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For detailed implementation steps, see the &lt;a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/check-aws-cdk-applications-or-cloudformation-templates-for-best-practices-by-using-cdk-nag-rule-packs.html" rel="noopener noreferrer"&gt;AWS Prescriptive Guidance on cdk-nag implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Aspects for Cross-Cutting Concerns
&lt;/h3&gt;

&lt;p&gt;Aspects use the visitor pattern to apply operations across all constructs in your application. They're powerful for enforcing standards that apply everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read-only aspects&lt;/strong&gt; validate without modifying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BucketVersioningChecker&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IAspect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IConstruct&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;versioned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Annotations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bucket must have versioning enabled&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Aspects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BucketVersioningChecker&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Mutating aspects&lt;/strong&gt; modify constructs during synthesis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaggingAspect&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IAspect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IConstruct&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ManagedBy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CDK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Aspects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TaggingAspect&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With secure, tested code, let's set up continuous delivery with GitHub Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  CI/CD with GitHub Actions
&lt;/h2&gt;

&lt;p&gt;For CDK deployments, I recommend GitHub Actions over CDK Pipelines. While CDK Pipelines is a valid option, GitHub Actions provides a simpler, more widely understood approach that integrates better with existing workflows.&lt;/p&gt;

&lt;p&gt;The critical piece is using OpenID Connect (OIDC) for AWS authentication instead of long-lived credentials. Storing AWS access keys in GitHub secrets is a security anti-pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why GitHub Actions Over CDK Pipelines
&lt;/h3&gt;

&lt;p&gt;CDK Pipelines adds significant complexity to your CDK application. Your pipeline becomes CDK code that deploys itself, which can be confusing to debug and requires understanding both CodePipeline and CDK internals.&lt;/p&gt;

&lt;p&gt;GitHub Actions, by contrast, is platform-agnostic and widely understood. Most developers already know how to work with GitHub Actions workflows. When something fails, you're debugging a YAML workflow, not synthesized CodePipeline resources.&lt;/p&gt;

&lt;p&gt;Additionally, GitHub Actions with OIDC provides better security than CDK Pipelines' default bootstrap roles. You have explicit control over the IAM trust policy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure AWS Access with OpenID Connect
&lt;/h3&gt;

&lt;p&gt;OpenID Connect (OIDC) lets GitHub Actions assume an IAM role without storing long-lived credentials. GitHub acts as an identity provider, and AWS trusts tokens from specific repositories and branches.&lt;/p&gt;

&lt;p&gt;Setting up OIDC requires:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating a GitHub OIDC provider in your AWS account&lt;/li&gt;
&lt;li&gt;Creating an IAM role with a trust policy for GitHub&lt;/li&gt;
&lt;li&gt;Configuring your workflow to use OIDC authentication&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For step-by-step instructions, see my detailed guides on setting up OpenID Connect with &lt;a href="https://towardsthecloud.com/blog/aws-cdk-openid-connect-github" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; or &lt;a href="https://towardsthecloud.com/blog/aws-cdk-openid-connect-bitbucket" rel="noopener noreferrer"&gt;Bitbucket&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Actions Workflow Structure
&lt;/h3&gt;

&lt;p&gt;Here's a production-ready workflow structure for CDK deployments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CDK Deploy&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-and-test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;20'&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;npm'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run linting&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run lint&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Synthesize CDK&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx cdk synth&lt;/span&gt;

  &lt;span class="na"&gt;deploy-dev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build-and-test&lt;/span&gt;
    &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.ref == 'refs/heads/main'&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;development&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure AWS credentials&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;role-to-assume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::123456789012:role/GitHubDeployRole&lt;/span&gt;
          &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;20'&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;npm'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to dev&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx cdk deploy --all --require-approval never&lt;/span&gt;

  &lt;span class="na"&gt;deploy-prod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy-dev&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure AWS credentials&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;role-to-assume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::987654321098:role/GitHubDeployRole&lt;/span&gt;
          &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;20'&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;npm'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to production&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx cdk deploy --all --require-approval never&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a complete CI/CD implementation, check the &lt;a href="https://towardsthecloud.com/docs/aws-cdk-starter-kit/configuration/ci-cd-workflows" rel="noopener noreferrer"&gt;aws-cdk-starter-kit CI/CD documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Environment Deployment Patterns
&lt;/h3&gt;

&lt;p&gt;For multi-environment deployments, use GitHub environments with protection rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Development&lt;/strong&gt;: Deploys automatically on push to main&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staging&lt;/strong&gt;: Requires manual approval before deployment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production&lt;/strong&gt;: Requires manual approval and passes all staging tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configure environment protection in GitHub repository settings. The &lt;code&gt;environment&lt;/code&gt; key in your workflow jobs enforces these rules.&lt;/p&gt;

&lt;p&gt;Before bootstrapping each environment, ensure you've &lt;a href="https://towardsthecloud.com/blog/aws-cdk-bootstrap" rel="noopener noreferrer"&gt;configured CDK bootstrap&lt;/a&gt; with appropriate trust relationships for your GitHub OIDC role.&lt;/p&gt;

&lt;p&gt;Now that you know the best practices, let's look at what NOT to do: the anti-patterns that cause production incidents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Anti-Patterns to Avoid
&lt;/h2&gt;

&lt;p&gt;Knowing what to avoid is as important as knowing what to do. These anti-patterns cause real problems in production CDK applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hardcoding Physical Resource Names
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Anti-pattern: Hardcoded names&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DataBucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;bucketName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-company-data-bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Don't do this&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Consequence&lt;/strong&gt;: You can't deploy this stack twice in the same account. Want dev and prod in the same account? Want to test a feature branch? Can't do it. The name is taken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Let CDK generate names. Pass them to consumers through environment variables, Parameter Store, or stack references.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment Variable Lookups in Constructs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Anti-pattern: Environment variable lookup in construct&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyConstruct&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_REGION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Machine dependency&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Consequence&lt;/strong&gt;: Your infrastructure depends on whatever machine runs synthesis. Works on your laptop, fails in CI. Works today, fails tomorrow when someone changes their shell profile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Accept all configuration through properties. Environment variables belong only at the top level of your app for development convenience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual Infrastructure Modifications
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern&lt;/strong&gt;: Making changes through the AWS Console or CLI after CDK deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consequence&lt;/strong&gt;: Configuration drift. Your CDK code says one thing, AWS has something different. Next deployment either fails mysteriously or overwrites your manual changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: All infrastructure changes go through CDK code in version control. If you need a quick fix, make it in code and deploy, even for "temporary" changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bypassing Code Review and Testing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern&lt;/strong&gt;: Running &lt;code&gt;cdk deploy&lt;/code&gt; directly from your laptop to production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consequence&lt;/strong&gt;: Untested, unreviewed changes reach production. No audit trail. When something breaks, nobody knows what changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: All production deployments go through CI/CD with pull request reviews and automated tests. No exceptions, not even for "quick fixes."&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple Applications in One Repository
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern&lt;/strong&gt;: Multiple CDK apps sharing a single repository with a shared pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consequence&lt;/strong&gt;: Changing one application triggers deployment of all applications. A bug in App A prevents deployment of App B. The blast radius of any change is massive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: One application per repository. Share code through published packages, not filesystem proximity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checking In Secrets
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern&lt;/strong&gt;: Committing credentials, API keys, database passwords, or sensitive configuration to version control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Anti-pattern: Secrets in code&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyFunction&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;super-secret-password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Never do this&lt;/span&gt;
    &lt;span class="na"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sk-1234567890abcdef&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// This either&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Consequence&lt;/strong&gt;: Security breach waiting to happen. Secrets in Git history persist even after deletion. Automated scanners constantly search public repositories for exposed credentials. Even in private repositories, anyone with read access sees your secrets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Use AWS Secrets Manager or Systems Manager Parameter Store for all secrets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Secret&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib/aws-secretsmanager&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dbSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromSecretNameV2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DbSecret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prod/db/password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyFunction&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;DB_SECRET_ARN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dbSecret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secretArn&lt;/span&gt;&lt;span class="p"&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;// Grant the function permission to read the secret&lt;/span&gt;
&lt;span class="nx"&gt;dbSecret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grantRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add secret patterns to &lt;code&gt;.gitignore&lt;/code&gt; (&lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;*.pem&lt;/code&gt;, &lt;code&gt;credentials.json&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Use pre-commit hooks like &lt;a href="https://github.com/awslabs/git-secrets" rel="noopener noreferrer"&gt;git-secrets&lt;/a&gt; to scan for accidentally committed credentials&lt;/li&gt;
&lt;li&gt;Rotate any secrets that were ever committed, even briefly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond avoiding mistakes, there are also optimization opportunities for performance and cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance and Cost Optimization
&lt;/h2&gt;

&lt;p&gt;CDK applications can accumulate waste over time if you're not proactive about optimization. Here are the key areas to address.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tagging for Cost Allocation
&lt;/h3&gt;

&lt;p&gt;Tags propagate from parent constructs to all taggable children. Apply tags at the app or stack level to ensure every resource is tagged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Tags&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Project&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyProject&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;Tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CostCenter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;engineering&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tags appear in your AWS Cost Explorer, enabling cost allocation by project, environment, or team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Managing CDK Assets with Garbage Collection
&lt;/h3&gt;

&lt;p&gt;Over time, CDK bootstrap buckets and ECR repositories accumulate old assets from previous deployments. This increases storage costs unnecessarily.&lt;/p&gt;

&lt;p&gt;CDK Garbage Collection (currently in preview) cleans up isolated assets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk gc &lt;span class="nt"&gt;--unstable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command works at the environment level, identifying and deleting assets that are no longer referenced by any deployed stack. Configure safety buffers to avoid deleting assets needed for rollbacks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk gc &lt;span class="nt"&gt;--unstable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gc &lt;span class="nt"&gt;--rollback-buffer-days&lt;/span&gt; 14 &lt;span class="nt"&gt;--created-buffer-days&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: Don't run garbage collection during active deployments. Wait until all deployments are complete.&lt;/p&gt;

&lt;p&gt;Finally, let's look at the newest CDK features you should know about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recent CDK Features (2024-2025)
&lt;/h2&gt;

&lt;p&gt;CDK continues to evolve rapidly. These recent features address longstanding pain points and open new possibilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  CDK Refactor for Safe Infrastructure Changes
&lt;/h3&gt;

&lt;p&gt;Released in September 2025, CDK Refactor enables safe refactoring of infrastructure by renaming constructs, moving resources between stacks, and reorganizing CDK applications without replacing existing resources.&lt;/p&gt;

&lt;p&gt;Previously, renaming a construct or moving it to a different stack caused CloudFormation to delete the old resource and create a new one. For stateful resources like databases, this was catastrophic.&lt;/p&gt;

&lt;p&gt;CDK Refactor uses CloudFormation's refactor capabilities to compute the mapping between old and new logical IDs automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk refactor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use cases include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Breaking monolithic stacks into domain-specific stacks&lt;/li&gt;
&lt;li&gt;Renaming constructs to follow naming conventions&lt;/li&gt;
&lt;li&gt;Reorganizing applications after team structure changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This feature is available in all AWS Regions where CDK is supported.&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI and Library Split
&lt;/h3&gt;

&lt;p&gt;Starting February 2025, the CDK CLI and CDK Construct Library have independent release cadences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CDK CLI versions&lt;/strong&gt;: 2.1000.0, 2.1001.0, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CDK Construct Library versions&lt;/strong&gt;: 2.175.0, 2.176.0, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CLI source code moved to a new GitHub repository: &lt;a href="https://github.com/aws/aws-cdk-cli" rel="noopener noreferrer"&gt;github.com/aws/aws-cdk-cli&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical impact&lt;/strong&gt;: Keep your CDK CLI at the latest version. The CLI is backward-compatible with all Construct Library versions released before it. Update your CI/CD pipelines to install the latest 2.x CLI rather than pinning specific versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  New L2 Constructs
&lt;/h3&gt;

&lt;p&gt;Several services gained L2 constructs in 2024-2025:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon Data Firehose L2&lt;/strong&gt; (February 2025): Define streaming data infrastructure with familiar programming patterns. Programmatically configure delivery streams to S3, Redshift, and other destinations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS AppSync Events L2&lt;/strong&gt; (February 2025): Create WebSocket APIs for real-time applications. Define event APIs and channel namespaces, grant access to specific channels, and integrate with Lambda functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon EKS v2 L2&lt;/strong&gt; (alpha): Uses native CloudFormation resources and modern Access Entry-based authentication. Supports EKS Auto Mode and multiple clusters per stack.&lt;/p&gt;

&lt;p&gt;These new L2 constructs replace verbose L1 configurations with intent-based APIs that include sensible defaults.&lt;/p&gt;

&lt;p&gt;For even more advanced patterns, check out this AWS re:Invent session from experts with 4+ years of CDK experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Patterns: Learning from 4 Years of CDK (Video)
&lt;/h2&gt;

&lt;p&gt;This AWS re:Invent 2023 session (COM302) covers advanced CDK patterns from engineers who have used CDK in production for over four years. The talk goes deeper into topics like testing strategies, organizational patterns, and lessons learned from large-scale deployments.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Wzawix9bMAE"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Key topics covered include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organizational patterns for multi-team CDK adoption&lt;/li&gt;
&lt;li&gt;Advanced testing strategies beyond unit tests&lt;/li&gt;
&lt;li&gt;Performance optimization for large CDK applications&lt;/li&gt;
&lt;li&gt;Governance and compliance at scale&lt;/li&gt;
&lt;li&gt;Real-world failure scenarios and how to avoid them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The session complements this guide by providing visual explanations and live demonstrations of advanced patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your CDK Best Practices Checklist
&lt;/h2&gt;

&lt;p&gt;Here's what to remember from this guide:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use Projen&lt;/strong&gt; for project configuration management, not manual file editing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model with constructs, deploy with stacks&lt;/strong&gt; to maximize reusability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test your infrastructure&lt;/strong&gt; with fine-grained assertions and snapshots&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate with cdk-nag&lt;/strong&gt; before deployment to catch compliance issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use GitHub Actions with OIDC&lt;/strong&gt; for secure CI/CD without long-lived credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid anti-patterns&lt;/strong&gt; like hardcoded names, environment variable lookups, and manual changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Let CDK generate resource names&lt;/strong&gt; and pass them to consumers explicitly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define removal policies&lt;/strong&gt; for all stateful resources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tag everything&lt;/strong&gt; for cost allocation and governance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep CDK CLI updated&lt;/strong&gt; to get the latest features and compatibility&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Your next step&lt;/strong&gt;: Clone the &lt;a href="https://github.com/towardsthecloud/aws-cdk-starter-kit" rel="noopener noreferrer"&gt;aws-cdk-starter-kit&lt;/a&gt; and explore how it implements these best practices. Use it as a starting point for your next project or as a reference when restructuring existing applications.&lt;/p&gt;

&lt;p&gt;For more detailed guidance on specific topics, check out these related guides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://towardsthecloud.com/blog/aws-cdk" rel="noopener noreferrer"&gt;What is AWS CDK?&lt;/a&gt; for a beginner-friendly introduction to CDK fundamentals&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://towardsthecloud.com/blog/aws-cdk-project-structure" rel="noopener noreferrer"&gt;AWS CDK Project Structure&lt;/a&gt; for deeper project organization patterns&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://towardsthecloud.com/blog/aws-cdk-construct" rel="noopener noreferrer"&gt;AWS CDK Constructs&lt;/a&gt; for mastering L1, L2, and L3 constructs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://towardsthecloud.com/blog/aws-cdk-stack" rel="noopener noreferrer"&gt;AWS CDK Stacks&lt;/a&gt; for understanding stack lifecycle and patterns&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://towardsthecloud.com/blog/aws-cdk-openid-connect-github" rel="noopener noreferrer"&gt;Configure OpenID Connect for GitHub&lt;/a&gt; for OIDC setup details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What best practices have made the biggest difference in your CDK projects? I'd love to hear about patterns that have worked well for your team.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>awscdk</category>
      <category>cdkbestpractices</category>
      <category>projen</category>
      <category>cdknag</category>
    </item>
    <item>
      <title>AWS CloudOps Engineer Exam Guide: SOA-C03 Prep &amp; Study Plan [2026]</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 17:28:56 +0000</pubDate>
      <link>https://forem.com/dannysteenman/aws-cloudops-engineer-exam-guide-soa-c03-prep-study-plan-2026-15nn</link>
      <guid>https://forem.com/dannysteenman/aws-cloudops-engineer-exam-guide-soa-c03-prep-study-plan-2026-15nn</guid>
      <description>&lt;p&gt;The AWS Certified SysOps Administrator exam you might have prepared for no longer exists. As of September 2025, it's the AWS Certified CloudOps Engineer Associate (SOA-C03), a significant update that brings containers, modern operations practices, and multi-account architectures into scope.&lt;/p&gt;

&lt;p&gt;This isn't just a name change. The exam content has evolved substantially, and many outdated study guides are still ranking in search results. If you're using SOA-C02 materials, you're studying for the wrong exam.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This guide gives you a complete preparation roadmap&lt;/strong&gt;: personalized study timelines based on your experience level, domain-by-domain breakdown with service coverage, free and paid resource recommendations, hands-on practice strategies, and exam day tactics. Everything is based on the official SOA-C03 exam guide and AWS Training and Certification resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the AWS CloudOps Engineer Associate Certification?
&lt;/h2&gt;

&lt;p&gt;The AWS Certified CloudOps Engineer Associate validates your expertise in deploying, operating, and maintaining workloads on AWS. It's designed for system administrators, operations engineers, and DevOps professionals who manage production AWS environments.&lt;/p&gt;

&lt;p&gt;This certification sits at the Associate level in AWS's certification hierarchy, which means it expects hands-on implementation skills, not just theoretical knowledge. You'll need to demonstrate practical understanding of monitoring, automation, security, and cost optimization across AWS services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Exam Details (SOA-C03)
&lt;/h3&gt;

&lt;p&gt;Here's what you need to know about the exam itself:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Detail&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Specification&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Exam Code&lt;/td&gt;
&lt;td&gt;SOA-C03&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price&lt;/td&gt;
&lt;td&gt;$150 USD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Duration&lt;/td&gt;
&lt;td&gt;180 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Format&lt;/td&gt;
&lt;td&gt;Multiple-choice, multiple-response, ordering, matching, case study&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delivery&lt;/td&gt;
&lt;td&gt;Pearson VUE test center or online proctoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Passing Score&lt;/td&gt;
&lt;td&gt;Scaled scoring (AWS doesn't disclose exact threshold)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Questions&lt;/td&gt;
&lt;td&gt;50-65 questions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Follow this &lt;a href="https://towardsthecloud.com/blog/pass-aws-certification-exam" rel="noopener noreferrer"&gt;advice on getting 30 minutes extra time&lt;/a&gt; to permanently receive additional time for all your AWS exams.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Changed: From SysOps Administrator to CloudOps Engineer
&lt;/h3&gt;

&lt;p&gt;AWS announced the certification rename in July 2025, with registration opening on September 9, 2025. The last day to take the previous SOA-C02 exam was September 29, 2025, meaning only SOA-C03 is available now.&lt;/p&gt;

&lt;p&gt;The name change reflects the industry's shift in terminology. "CloudOps" better describes the modern role of cloud operations professionals who manage, monitor, and automate cloud infrastructure. But the changes go deeper than branding:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key differences in SOA-C03:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Containers are now in-scope&lt;/strong&gt;: Amazon ECS, EKS, and ECR are testable topics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Greater emphasis on multi-account, multi-Region architectures&lt;/strong&gt;: Understanding &lt;a href="https://towardsthecloud.com/blog/aws-organizations" rel="noopener noreferrer"&gt;AWS Organizations&lt;/a&gt; and &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-strategy" rel="noopener noreferrer"&gt;multi-account strategy&lt;/a&gt; is more important than ever&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increased focus on automation and infrastructure as code&lt;/strong&gt;: Expect deeper questions on CloudFormation, Systems Manager, and Config&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More modern services and features&lt;/strong&gt;: Updated content reflects AWS services released through 2025&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New question types&lt;/strong&gt;: Ordering, matching, and case study questions test procedural knowledge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No task statements were removed from the previous exam, only additions and reorganization. If you studied for SOA-C02, you have a foundation, but you need to fill the gaps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact on existing certifications&lt;/strong&gt;: If you already hold the AWS Certified SysOps Administrator Associate, your certification remains valid until its expiration date. It won't automatically rename. You'll only earn the "CloudOps Engineer" title by passing the new SOA-C03 exam.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who Should Take This Exam?
&lt;/h3&gt;

&lt;p&gt;AWS designed this certification for professionals who manage AWS production environments. You're a good fit if you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have at least 1-2 years of hands-on experience operating AWS workloads&lt;/li&gt;
&lt;li&gt;Know how to troubleshoot applications using AWS monitoring and logging services&lt;/li&gt;
&lt;li&gt;Understand fundamental networking concepts (DNS, TCP/IP, firewalls, VPCs)&lt;/li&gt;
&lt;li&gt;Can implement highly available, performant architectures&lt;/li&gt;
&lt;li&gt;Work with or aspire to work in cloud operations, DevOps, or platform engineering roles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't an entry-level certification. If you're brand new to AWS, consider starting with the Cloud Practitioner certification to build foundational knowledge first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is the CloudOps Exam Right for You?
&lt;/h2&gt;

&lt;p&gt;Before committing weeks or months to exam preparation, make sure CloudOps Engineer aligns with your career goals and current skill level. The wrong certification path wastes time and money.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites and Recommended Background
&lt;/h3&gt;

&lt;p&gt;AWS doesn't mandate specific prerequisites, but the Associate level assumes you can do more than recognize service names. You need implementation experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended background:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hands-on experience managing, monitoring, and maintaining cloud infrastructure&lt;/li&gt;
&lt;li&gt;Familiarity with AWS core services (EC2, VPC, IAM, S3, CloudWatch)&lt;/li&gt;
&lt;li&gt;Understanding of operational concepts like monitoring, logging, backup, and disaster recovery&lt;/li&gt;
&lt;li&gt;Experience with at least one infrastructure as code tool (CloudFormation, CDK, Terraform)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Timeline expectations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you're transitioning from on-premises infrastructure roles: 3-6 months to master AWS fundamentals before focused exam prep&lt;/li&gt;
&lt;li&gt;If you have AWS experience but not in operations: 4-8 weeks of targeted study&lt;/li&gt;
&lt;li&gt;If you already work in AWS operations daily: 2-4 weeks of exam-focused preparation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Should You Get Cloud Practitioner First?
&lt;/h3&gt;

&lt;p&gt;The short answer: it depends on your background.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with Cloud Practitioner if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're completely new to AWS&lt;/li&gt;
&lt;li&gt;You don't have hands-on cloud experience&lt;/li&gt;
&lt;li&gt;You want to validate foundational knowledge before investing in Associate-level prep&lt;/li&gt;
&lt;li&gt;Your organization values or requires foundational certification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Skip to CloudOps Engineer directly if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have 6+ months of hands-on AWS experience&lt;/li&gt;
&lt;li&gt;You already work with CloudWatch, VPC, IAM, or EC2 regularly&lt;/li&gt;
&lt;li&gt;You've built or managed infrastructure on AWS&lt;/li&gt;
&lt;li&gt;You hold other cloud certifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cloud Practitioner adds 2-3 weeks to your total preparation time but builds a strong conceptual foundation. For complete beginners, it's worth the investment. For working cloud professionals, it's often unnecessary.&lt;/p&gt;

&lt;p&gt;Read the &lt;a href="https://towardsthecloud.com/blog/aws-cloud-practitioner-exam-guide" rel="noopener noreferrer"&gt;AWS Cloud Practitioner exam guide&lt;/a&gt; if you decide the foundational path makes sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  CloudOps vs Solutions Architect vs Developer Associate
&lt;/h3&gt;

&lt;p&gt;AWS offers three Associate-level certifications, each targeting different roles and skill sets. Choosing the right one accelerates your career in the direction you want to go.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Certification&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Primary Focus&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Solutions Architect Associate&lt;/td&gt;
&lt;td&gt;Designing cost-effective, scalable architectures&lt;/td&gt;
&lt;td&gt;Architects who design systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer Associate&lt;/td&gt;
&lt;td&gt;Building and deploying applications on AWS&lt;/td&gt;
&lt;td&gt;Developers writing code for AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudOps Engineer Associate&lt;/td&gt;
&lt;td&gt;Operating and maintaining production workloads&lt;/td&gt;
&lt;td&gt;Operations engineers, SysAdmins, DevOps&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;CloudOps Engineer&lt;/strong&gt; focuses on the operational lifecycle: monitoring, logging, remediation, automation, and optimization. You're tested on keeping systems running, not designing them from scratch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://towardsthecloud.com/blog/aws-solutions-architect-associate-exam-guide" rel="noopener noreferrer"&gt;Solutions Architect Associate&lt;/a&gt;&lt;/strong&gt; focuses on architectural decisions: choosing the right services, designing for availability, and optimizing costs at the design phase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://towardsthecloud.com/blog/aws-developer-associate-exam-guide" rel="noopener noreferrer"&gt;Developer Associate&lt;/a&gt;&lt;/strong&gt; focuses on application development: CI/CD pipelines, serverless applications, SDK usage, and debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Career progression insight&lt;/strong&gt;: Many professionals earn multiple Associate certifications. CloudOps + Developer leads naturally to the &lt;a href="https://towardsthecloud.com/blog/aws-devops-engineer-professional-exam-guide" rel="noopener noreferrer"&gt;AWS DevOps Engineer Professional certification&lt;/a&gt;, which validates expertise in both development and operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Study Timeline: Choose Your Path
&lt;/h2&gt;

&lt;p&gt;Generic advice like "study for several weeks to months" isn't helpful. Your optimal timeline depends on your starting point. Here are four concrete paths based on experience level.&lt;/p&gt;

&lt;p&gt;The timelines below assume you're dedicating 1-2 hours daily to focused study. Adjust proportionally if you have more or less time available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complete Beginner Path (8 Weeks)
&lt;/h3&gt;

&lt;p&gt;This path is for you if you're new to AWS or have minimal cloud experience. You'll build foundational knowledge before diving into operations-specific content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 1-2: AWS Fundamentals&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete Cloud Practitioner-level content on AWS Skill Builder&lt;/li&gt;
&lt;li&gt;Focus on core services: EC2, S3, VPC, IAM&lt;/li&gt;
&lt;li&gt;Understand the AWS global infrastructure and pricing model&lt;/li&gt;
&lt;li&gt;Goal: Pass a Cloud Practitioner practice assessment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 3-4: Core CloudOps Services&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deep dive into CloudWatch (metrics, alarms, logs, dashboards)&lt;/li&gt;
&lt;li&gt;Learn IAM policies, roles, and permission boundaries&lt;/li&gt;
&lt;li&gt;Study VPC components, security groups, and network ACLs&lt;/li&gt;
&lt;li&gt;Hands-on: Set up basic monitoring for an EC2 instance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 5-6: Advanced Operations Topics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Systems Manager (Session Manager, Patch Manager, Automation)&lt;/li&gt;
&lt;li&gt;CloudFormation fundamentals and stack operations&lt;/li&gt;
&lt;li&gt;AWS Config rules and compliance automation&lt;/li&gt;
&lt;li&gt;Container basics: ECS task definitions and services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 7: Practice Exams and Gap Identification&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take your first full practice exam&lt;/li&gt;
&lt;li&gt;Score and categorize weak areas by domain&lt;/li&gt;
&lt;li&gt;Create targeted study plan for final week&lt;/li&gt;
&lt;li&gt;Review all incorrect answers thoroughly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 8: Targeted Review and Exam&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus 70% of time on weak domains identified&lt;/li&gt;
&lt;li&gt;Light review of strong areas to maintain knowledge&lt;/li&gt;
&lt;li&gt;Take final practice exam (aim for 80%+)&lt;/li&gt;
&lt;li&gt;Schedule and take the exam&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cloud Practitioner Holder Path (6 Weeks)
&lt;/h3&gt;

&lt;p&gt;You've already validated foundational AWS knowledge. Now you'll focus on operational depth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 1-2: Monitoring and Logging Deep Dive&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudWatch metrics, alarms, and composite alarms&lt;/li&gt;
&lt;li&gt;CloudWatch Logs, Logs Insights queries, and &lt;a href="https://towardsthecloud.com/blog/amazon-cloudwatch-set-logs-retention-policy" rel="noopener noreferrer"&gt;log retention management&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AWS X-Ray for distributed tracing&lt;/li&gt;
&lt;li&gt;CloudTrail for API logging and security analysis&lt;/li&gt;
&lt;li&gt;Hands-on: Build a monitoring dashboard and configure alarms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 3-4: Automation and Security&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Systems Manager capabilities (Automation, Run Command, State Manager)&lt;/li&gt;
&lt;li&gt;AWS Config rules and auto-remediation&lt;/li&gt;
&lt;li&gt;EventBridge rules and targets for automation&lt;/li&gt;
&lt;li&gt;IAM best practices, Organizations, and &lt;a href="https://towardsthecloud.com/blog/aws-scp-service-control-policies" rel="noopener noreferrer"&gt;Service Control Policies (SCPs)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hands-on: Create an automation runbook&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 5: Containers and Multi-Account Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://towardsthecloud.com/blog/amazon-ecs-vs-aws-fargate" rel="noopener noreferrer"&gt;ECS vs Fargate&lt;/a&gt; and when to use each&lt;/li&gt;
&lt;li&gt;&lt;a href="https://towardsthecloud.com/blog/amazon-ecs-task-role-vs-execution-role" rel="noopener noreferrer"&gt;ECS task roles vs execution roles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;EKS cluster operations basics&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://towardsthecloud.com/blog/aws-organizations" rel="noopener noreferrer"&gt;AWS Organizations&lt;/a&gt; and &lt;a href="https://towardsthecloud.com/blog/aws-control-tower-vs-aws-organizations" rel="noopener noreferrer"&gt;Control Tower vs Organizations&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hands-on: Deploy a containerized application on ECS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 6: Practice Exams and Exam&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take 2-3 practice exams from different sources&lt;/li&gt;
&lt;li&gt;Deep review of all incorrect answers&lt;/li&gt;
&lt;li&gt;Final review of high-weight domains&lt;/li&gt;
&lt;li&gt;Schedule and take the exam&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Solutions Architect Associate Holder Path (4 Weeks)
&lt;/h3&gt;

&lt;p&gt;You understand AWS architecture. Now you'll learn to operate and maintain what you've designed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 1: Monitoring Deep Dive&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudWatch metrics you didn't need for SAA (detailed monitoring, custom metrics)&lt;/li&gt;
&lt;li&gt;CloudWatch Logs Insights query syntax&lt;/li&gt;
&lt;li&gt;Alarm actions and composite alarms&lt;/li&gt;
&lt;li&gt;Container Insights for ECS/EKS monitoring&lt;/li&gt;
&lt;li&gt;&lt;a href="https://towardsthecloud.com/blog/aws-cli-trigger-cloudwatch-alarm" rel="noopener noreferrer"&gt;Testing CloudWatch alarms&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 2: Automation and Remediation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Systems Manager Automation documents&lt;/li&gt;
&lt;li&gt;AWS Config rules with auto-remediation&lt;/li&gt;
&lt;li&gt;EventBridge rules for operational automation&lt;/li&gt;
&lt;li&gt;Patch management and compliance enforcement&lt;/li&gt;
&lt;li&gt;SSM Parameter Store vs Secrets Manager operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 3: New SOA-C03 Content&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Container operations: &lt;a href="https://towardsthecloud.com/blog/amazon-ecs-execute-command-access-container" rel="noopener noreferrer"&gt;ECS execute command&lt;/a&gt;, task definitions&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://towardsthecloud.com/blog/amazon-ecs-vs-amazon-ec2" rel="noopener noreferrer"&gt;ECS vs EC2&lt;/a&gt; decision framework&lt;/li&gt;
&lt;li&gt;Multi-account operations with Organizations&lt;/li&gt;
&lt;li&gt;AWS Backup and disaster recovery&lt;/li&gt;
&lt;li&gt;Cost optimization with Compute Optimizer and Trusted Advisor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Week 4: Practice Exams and Exam&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus on operations-specific scenarios&lt;/li&gt;
&lt;li&gt;Compare your SAA knowledge to CloudOps requirements&lt;/li&gt;
&lt;li&gt;Take 2 full practice exams&lt;/li&gt;
&lt;li&gt;Schedule and take the exam&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Working Cloud Engineer Path (2 Weeks)
&lt;/h3&gt;

&lt;p&gt;You operate AWS daily. Your goal is validating what you know and filling specific gaps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Days 1-3: Assessment and Gap Identification&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download and review the official SOA-C03 exam guide&lt;/li&gt;
&lt;li&gt;Take a practice assessment on AWS Skill Builder&lt;/li&gt;
&lt;li&gt;Identify weak domains from your score report&lt;/li&gt;
&lt;li&gt;Create targeted study list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Days 4-7: Fill Knowledge Gaps&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Focus on any unfamiliar services or concepts&lt;/li&gt;
&lt;li&gt;Containers if you don't use them daily&lt;/li&gt;
&lt;li&gt;Multi-account architecture if you work single-account&lt;/li&gt;
&lt;li&gt;Cost optimization services (Compute Optimizer, Trusted Advisor)&lt;/li&gt;
&lt;li&gt;Review documentation for services you use but don't fully understand&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Days 8-10: Practice Exams&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take 2-3 full-length practice exams&lt;/li&gt;
&lt;li&gt;Time yourself to simulate exam conditions&lt;/li&gt;
&lt;li&gt;Review ALL answer explanations, not just wrong ones&lt;/li&gt;
&lt;li&gt;Identify any remaining gaps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Days 11-14: Final Review and Exam&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Light review of flagged topics&lt;/li&gt;
&lt;li&gt;Quick refresher on exam domains and weightings&lt;/li&gt;
&lt;li&gt;Rest the day before the exam&lt;/li&gt;
&lt;li&gt;Take the exam&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best CloudOps Exam Study Resources
&lt;/h2&gt;

&lt;p&gt;The right resources make preparation efficient. The wrong ones waste time on outdated content or topics not covered on the exam. Here's what actually works for SOA-C03.&lt;/p&gt;

&lt;h3&gt;
  
  
  Free Resources: AWS Skill Builder and Documentation
&lt;/h3&gt;

&lt;p&gt;AWS provides substantial free preparation materials. For budget-conscious learners, you can pass using only free resources, though it requires more self-direction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Skill Builder (Free Tier):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exam Prep Plan: AWS Certified CloudOps Engineer - Associate (SOA-C03)&lt;/li&gt;
&lt;li&gt;Individual courses for each exam domain&lt;/li&gt;
&lt;li&gt;Free practice questions to understand exam format&lt;/li&gt;
&lt;li&gt;Self-paced digital courses covering core services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AWS Documentation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service FAQs (especially CloudWatch, Systems Manager, Config)&lt;/li&gt;
&lt;li&gt;Best practices whitepapers (operations, security, cost optimization)&lt;/li&gt;
&lt;li&gt;Service user guides for deep technical understanding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AWS Builder Labs (Limited Free):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hands-on labs in actual AWS environments&lt;/li&gt;
&lt;li&gt;Specific labs: "Configuring metrics and alarms in Amazon CloudWatch"&lt;/li&gt;
&lt;li&gt;AWS Jam challenges for gamified learning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solutions-Focused Immersion Days (SFIDs):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free, live virtual events led by AWS experts&lt;/li&gt;
&lt;li&gt;Cover core AWS services with hands-on components&lt;/li&gt;
&lt;li&gt;Check the AWS Training site for upcoming sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more options, see &lt;a href="https://towardsthecloud.com/blog/best-free-aws-learning-resources" rel="noopener noreferrer"&gt;11 best free AWS learning resources&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paid Resources Worth Considering
&lt;/h3&gt;

&lt;p&gt;Paid resources accelerate learning and provide structured paths. They're not required but often worth the investment for time savings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Skill Builder Subscription ($29/month):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full access to all labs and hands-on experiences&lt;/li&gt;
&lt;li&gt;AWS SimuLearn for exam-style practice&lt;/li&gt;
&lt;li&gt;Additional practice question sets&lt;/li&gt;
&lt;li&gt;AWS Cloud Quest gamified learning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Video Courses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stephane Maarek's courses (Udemy) are highly regarded in the community&lt;/li&gt;
&lt;li&gt;Look for courses explicitly updated for SOA-C03&lt;/li&gt;
&lt;li&gt;Avoid any course still referencing SOA-C02&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Practice Exams:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tutorials Dojo practice exams (Jon Bonso) are frequently recommended&lt;/li&gt;
&lt;li&gt;Official AWS practice question sets&lt;/li&gt;
&lt;li&gt;Look for providers with updated SOA-C03 content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Verify any resource is updated for SOA-C03. Content created before September 2025 is for the retired SOA-C02 exam and missing container coverage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recommended Resource Combinations
&lt;/h3&gt;

&lt;p&gt;Not sure how to combine resources? Here are three approaches based on budget and learning style.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Budget Path (Free Only):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWS Skill Builder free courses&lt;/li&gt;
&lt;li&gt;AWS documentation and whitepapers&lt;/li&gt;
&lt;li&gt;Official free practice questions&lt;/li&gt;
&lt;li&gt;AWS Free Tier for hands-on practice&lt;/li&gt;
&lt;li&gt;Timeline: Add 1-2 weeks for self-directed learning&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Balanced Path ($50-100):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWS Skill Builder free tier for courses&lt;/li&gt;
&lt;li&gt;One paid video course (Udemy, ~$15-20 on sale)&lt;/li&gt;
&lt;li&gt;One practice exam set (Tutorials Dojo, ~$15)&lt;/li&gt;
&lt;li&gt;AWS Free Tier for hands-on practice&lt;/li&gt;
&lt;li&gt;Best value for most learners&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Accelerated Path ($150-200):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWS Skill Builder subscription for full lab access&lt;/li&gt;
&lt;li&gt;Paid video course for structured learning&lt;/li&gt;
&lt;li&gt;Multiple practice exam sources for variety&lt;/li&gt;
&lt;li&gt;Timeline: Can compress study by 1-2 weeks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;By learning style:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visual learners&lt;/strong&gt;: Prioritize video courses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hands-on learners&lt;/strong&gt;: Invest in Skill Builder subscription for labs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readers&lt;/strong&gt;: AWS documentation and whitepapers work well&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test-takers&lt;/strong&gt;: Multiple practice exam sources reveal gaps faster&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SOA-C03 Exam Domains and What to Study
&lt;/h2&gt;

&lt;p&gt;The exam covers five domains. Understanding what each domain tests helps you allocate study time effectively and recognize question patterns during the exam.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Domain&lt;/th&gt;
&lt;th&gt;Weight&lt;/th&gt;
&lt;th&gt;Focus Areas&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring, Logging, Analysis, Remediation &amp;amp; Performance&lt;/td&gt;
&lt;td&gt;22%&lt;/td&gt;
&lt;td&gt;CloudWatch, X-Ray, troubleshooting, cost optimization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reliability and Business Continuity&lt;/td&gt;
&lt;td&gt;22%&lt;/td&gt;
&lt;td&gt;High availability, Auto Scaling, backup, disaster recovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment, Provisioning, and Automation&lt;/td&gt;
&lt;td&gt;22%&lt;/td&gt;
&lt;td&gt;CloudFormation, Systems Manager, IaC, CI/CD basics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Networking and Content Delivery&lt;/td&gt;
&lt;td&gt;18%&lt;/td&gt;
&lt;td&gt;VPC, Route 53, CloudFront, load balancing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security and Compliance&lt;/td&gt;
&lt;td&gt;16%&lt;/td&gt;
&lt;td&gt;IAM, encryption, compliance, Organizations, SCPs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Domain 1: Monitoring, Logging, Analysis, Remediation, and Performance Optimization (22%)&lt;/strong&gt; is tied for the highest weight. This domain now includes performance and cost optimization that was previously a separate domain in SOA-C02. You'll need deep CloudWatch expertise plus understanding of remediation automation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain 2: Reliability and Business Continuity (22%)&lt;/strong&gt; tests your ability to implement highly available, scalable systems. Key topics include Auto Scaling, load balancing, backup strategies, and disaster recovery procedures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain 3: Deployment, Provisioning, and Automation (22%)&lt;/strong&gt; focuses on infrastructure as code and deployment automation. CloudFormation, Systems Manager, and deployment strategies are critical here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain 4: Security and Compliance (16%)&lt;/strong&gt; covers implementing security controls, managing identities, and ensuring compliance. IAM, encryption, and governance tools like Organizations and SCPs are key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain 5: Networking and Content Delivery (18%)&lt;/strong&gt; tests VPC configuration, connectivity options, DNS with Route 53, and content delivery with CloudFront.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain 1: Monitoring, Logging, Analysis, Remediation, and Performance Optimization
&lt;/h3&gt;

&lt;p&gt;This domain tests your ability to implement metrics, alarms, and log filters, primarily using CloudWatch. You should also know how to remediate issues automatically using EventBridge and Systems Manager. In SOA-C03, this domain now includes cost and performance optimization that was previously a separate domain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key services to know deeply:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch&lt;/strong&gt;: Metrics (standard and custom), alarms, composite alarms, dashboards, Logs, Logs Insights, Container Insights&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudTrail&lt;/strong&gt;: API logging, log file integrity, integration with CloudWatch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS X-Ray&lt;/strong&gt;: Distributed tracing, service maps, trace analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EventBridge&lt;/strong&gt;: Event patterns, rules, targets, scheduling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Systems Manager&lt;/strong&gt;: Automation documents, Run Command, remediation actions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Explorer&lt;/strong&gt;: Cost analysis, forecasting, recommendations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Budgets&lt;/strong&gt;: Budget alerts, actions, notifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trusted Advisor&lt;/strong&gt;: Checks across cost, security, performance, fault tolerance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute Optimizer&lt;/strong&gt;: EC2 and Lambda right-sizing recommendations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you should be able to do:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure CloudWatch alarms with appropriate statistics and periods&lt;/li&gt;
&lt;li&gt;Write CloudWatch Logs Insights queries to analyze log data&lt;/li&gt;
&lt;li&gt;Set up automated remediation using Config rules and SSM Automation&lt;/li&gt;
&lt;li&gt;Design monitoring dashboards for operational visibility&lt;/li&gt;
&lt;li&gt;Analyze costs and identify optimization opportunities&lt;/li&gt;
&lt;li&gt;Right-size EC2 instances based on utilization data&lt;/li&gt;
&lt;li&gt;Implement S3 lifecycle policies for cost optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CloudWatch statistics you must know:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Statistic&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SampleCount&lt;/td&gt;
&lt;td&gt;Number of data points in the period&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sum&lt;/td&gt;
&lt;td&gt;Total value (e.g., total requests)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average&lt;/td&gt;
&lt;td&gt;Typical value over time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Minimum&lt;/td&gt;
&lt;td&gt;Lowest observed value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum&lt;/td&gt;
&lt;td&gt;Highest observed value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Percentile (p99, p95)&lt;/td&gt;
&lt;td&gt;Latency analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;EC2 placement groups:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Strategy&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cluster&lt;/td&gt;
&lt;td&gt;Low latency, high throughput (HPC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Partition&lt;/td&gt;
&lt;td&gt;Large distributed workloads (Hadoop, Cassandra)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spread&lt;/td&gt;
&lt;td&gt;Critical instances that must avoid correlated failures&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Domain 2: Reliability and Business Continuity
&lt;/h3&gt;

&lt;p&gt;This domain focuses on implementing scalability, elasticity, and high availability. You need to understand how to design and operate resilient systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key services to know deeply:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auto Scaling&lt;/strong&gt;: Scaling policies, health checks, lifecycle hooks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elastic Load Balancing&lt;/strong&gt;: ALB, NLB, target groups, health checks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route 53&lt;/strong&gt;: Health checks, routing policies, failover configurations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Backup&lt;/strong&gt;: Backup plans, retention policies, cross-Region backup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elastic Disaster Recovery&lt;/strong&gt;: DR strategies, recovery processes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Route 53 routing policies you must know:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Policy&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Simple&lt;/td&gt;
&lt;td&gt;Single resource, basic routing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weighted&lt;/td&gt;
&lt;td&gt;A/B testing, gradual migrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;Route to lowest-latency Region&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failover&lt;/td&gt;
&lt;td&gt;Active-passive high availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Geolocation&lt;/td&gt;
&lt;td&gt;Region-specific content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Geoproximity&lt;/td&gt;
&lt;td&gt;Custom traffic distribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multivalue&lt;/td&gt;
&lt;td&gt;DNS-level load balancing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What you should be able to do:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure Auto Scaling policies (target tracking, step, scheduled)&lt;/li&gt;
&lt;li&gt;Set up Route 53 health checks with failover routing&lt;/li&gt;
&lt;li&gt;Implement backup strategies with appropriate retention&lt;/li&gt;
&lt;li&gt;Design multi-Region architectures for disaster recovery&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Domain 3: Deployment, Provisioning, and Automation
&lt;/h3&gt;

&lt;p&gt;This domain tests infrastructure as code and deployment strategies. You need to understand CloudFormation deeply and know various deployment patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key services to know deeply:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudFormation&lt;/strong&gt;: Template anatomy, stack operations, helper scripts, drift detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS CDK&lt;/strong&gt;: &lt;a href="https://towardsthecloud.com/blog/aws-cdk" rel="noopener noreferrer"&gt;What is AWS CDK&lt;/a&gt;, &lt;a href="https://towardsthecloud.com/blog/aws-cdk-construct" rel="noopener noreferrer"&gt;CDK constructs&lt;/a&gt;, synthesizing templates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Systems Manager&lt;/strong&gt;: State Manager, Automation, Patch Manager, Parameter Store&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Config&lt;/strong&gt;: Rules, conformance packs, remediation actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CloudFormation helper scripts:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Script&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;cfn-init&lt;/td&gt;
&lt;td&gt;Execute metadata configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cfn-hup&lt;/td&gt;
&lt;td&gt;Monitor and apply metadata changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cfn-signal&lt;/td&gt;
&lt;td&gt;Signal completion of CreationPolicy/WaitCondition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cfn-get-metadata&lt;/td&gt;
&lt;td&gt;View stack metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Deployment strategies you must understand:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhqagmtkvl51o8ssbn8dt.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhqagmtkvl51o8ssbn8dt.webp" alt="AWS DevOps Deployment strategies cheat sheet" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you should be able to do:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write and troubleshoot CloudFormation templates&lt;/li&gt;
&lt;li&gt;Implement blue/green and rolling deployments&lt;/li&gt;
&lt;li&gt;Configure Systems Manager for patching and automation&lt;/li&gt;
&lt;li&gt;Use Config rules to enforce compliance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For deeper DevOps content, see the &lt;a href="https://towardsthecloud.com/blog/aws-devops-engineer-professional-exam-guide" rel="noopener noreferrer"&gt;AWS DevOps Engineer Professional exam guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain 4: Security and Compliance
&lt;/h3&gt;

&lt;p&gt;This domain covers IAM, encryption, and compliance enforcement. You need to understand both preventive and detective security controls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key services to know deeply:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IAM&lt;/strong&gt;: Policies, roles, permission boundaries, identity federation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Organizations&lt;/strong&gt;: &lt;a href="https://towardsthecloud.com/blog/aws-scp-service-control-policies" rel="noopener noreferrer"&gt;SCPs&lt;/a&gt;, &lt;a href="https://towardsthecloud.com/blog/aws-scp-examples" rel="noopener noreferrer"&gt;SCP examples&lt;/a&gt;, organizational structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KMS&lt;/strong&gt;: Key management, encryption contexts, key policies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets Manager&lt;/strong&gt;: Secret rotation, cross-account access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Hub&lt;/strong&gt;: Findings, compliance standards, integrations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Config&lt;/strong&gt;: Compliance rules, remediation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you should be able to do:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write and troubleshoot IAM policies&lt;/li&gt;
&lt;li&gt;Implement encryption at rest and in transit&lt;/li&gt;
&lt;li&gt;Configure compliance automation with Config rules&lt;/li&gt;
&lt;li&gt;Understand multi-account security with Organizations and SCPs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a deeper dive, read the &lt;a href="https://towardsthecloud.com/blog/aws-security-specialty-exam-guide" rel="noopener noreferrer"&gt;AWS Security Specialty exam guide&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain 5: Networking and Content Delivery
&lt;/h3&gt;

&lt;p&gt;This domain tests VPC configuration, connectivity options, and content delivery. You need to troubleshoot network issues and optimize content delivery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key services to know deeply:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC&lt;/strong&gt;: Subnets, route tables, security groups, NACLs, endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elastic Load Balancing&lt;/strong&gt;: ALB, NLB, connection draining, sticky sessions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudFront&lt;/strong&gt;: Distributions, origins, caching, Origin Access Control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route 53&lt;/strong&gt;: DNS records, routing policies, hosted zones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct Connect&lt;/strong&gt;: Connections, virtual interfaces, redundancy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;VPC components table:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Component&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Subnets&lt;/td&gt;
&lt;td&gt;IP address ranges for resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Route Tables&lt;/td&gt;
&lt;td&gt;Traffic routing between subnets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internet Gateway&lt;/td&gt;
&lt;td&gt;Public internet connectivity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NAT Gateway&lt;/td&gt;
&lt;td&gt;Outbound internet for private subnets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Virtual Private Gateway&lt;/td&gt;
&lt;td&gt;VPN connectivity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security Groups&lt;/td&gt;
&lt;td&gt;Stateful firewall at instance level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NACLs&lt;/td&gt;
&lt;td&gt;Stateless firewall at subnet level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VPC Endpoints&lt;/td&gt;
&lt;td&gt;Private connectivity to AWS services&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What you should be able to do:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design and troubleshoot VPC architectures&lt;/li&gt;
&lt;li&gt;Configure load balancers with appropriate health checks&lt;/li&gt;
&lt;li&gt;Set up CloudFront distributions with S3 origins&lt;/li&gt;
&lt;li&gt;Troubleshoot connectivity issues using VPC Flow Logs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  New in SOA-C03: Container Services
&lt;/h2&gt;

&lt;p&gt;Containers are the most significant addition to SOA-C03. If you haven't worked with ECS or EKS, this section is essential. Even if you have container experience, make sure you understand the operational aspects tested on the exam.&lt;/p&gt;

&lt;p&gt;The exam focuses on operating containers, not developing containerized applications. You need to know how to deploy, monitor, and troubleshoot container workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon ECS for CloudOps
&lt;/h3&gt;

&lt;p&gt;Amazon Elastic Container Service (ECS) is AWS's container orchestration service. It's the primary container service covered on the exam due to its AWS-native integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key concepts you must understand:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task Definitions&lt;/strong&gt;: The blueprint for your containers. Know the difference between &lt;a href="https://towardsthecloud.com/blog/amazon-ecs-task-role-vs-execution-role" rel="noopener noreferrer"&gt;task roles and execution roles&lt;/a&gt;, as this is a common exam topic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Launch Types&lt;/strong&gt;: Understand when to choose &lt;a href="https://towardsthecloud.com/blog/amazon-ecs-vs-aws-fargate" rel="noopener noreferrer"&gt;ECS with Fargate vs EC2&lt;/a&gt; and the operational implications of each:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fargate&lt;/strong&gt;: AWS manages the infrastructure. Less operational overhead, but less control over the underlying compute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2&lt;/strong&gt;: You manage the container instances. More control, but more operational responsibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a broader comparison, see &lt;a href="https://towardsthecloud.com/blog/amazon-ecs-vs-amazon-ec2" rel="noopener noreferrer"&gt;Amazon ECS vs Amazon EC2&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ECS Exec&lt;/strong&gt;: Know how to &lt;a href="https://towardsthecloud.com/blog/amazon-ecs-execute-command-access-container" rel="noopener noreferrer"&gt;access containers using ECS execute command&lt;/a&gt; for troubleshooting. This requires the SSM agent and appropriate IAM permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Container Insights&lt;/strong&gt;: CloudWatch Container Insights provides automatic dashboards for ECS metrics. You should know how to enable it and what metrics it collects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon EKS for CloudOps
&lt;/h3&gt;

&lt;p&gt;Amazon Elastic Kubernetes Service (EKS) is AWS's managed Kubernetes service. The exam tests operational knowledge, not Kubernetes administration depth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key concepts for the exam:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cluster management&lt;/strong&gt;: Creating, updating, and maintaining EKS clusters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node groups&lt;/strong&gt;: Managed and self-managed node groups&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fargate profiles&lt;/strong&gt;: Running pods on Fargate without managing nodes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM integration&lt;/strong&gt;: IAM roles for service accounts (IRSA)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging&lt;/strong&gt;: Control plane logging to CloudWatch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ECS vs EKS decision criteria:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Choose ECS When&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Choose EKS When&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS-native simplicity&lt;/td&gt;
&lt;td&gt;Kubernetes expertise exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tight AWS service integration&lt;/td&gt;
&lt;td&gt;Multi-cloud portability needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Smaller operational team&lt;/td&gt;
&lt;td&gt;Complex scheduling requirements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New to containers&lt;/td&gt;
&lt;td&gt;Existing K8s workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Container Monitoring and Operations
&lt;/h3&gt;

&lt;p&gt;Container monitoring integrates with CloudWatch but requires specific configuration. The exam tests your understanding of container-specific observability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CloudWatch Container Insights:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic collection of CPU, memory, network, and storage metrics&lt;/li&gt;
&lt;li&gt;Pre-built dashboards for ECS and EKS&lt;/li&gt;
&lt;li&gt;Per-container and per-task metrics&lt;/li&gt;
&lt;li&gt;Integration with CloudWatch alarms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Log aggregation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ECS: Configure the awslogs log driver in task definitions&lt;/li&gt;
&lt;li&gt;EKS: Use Fluent Bit or CloudWatch agent for log forwarding&lt;/li&gt;
&lt;li&gt;Know how to query container logs with Logs Insights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;X-Ray integration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trace requests across containerized microservices&lt;/li&gt;
&lt;li&gt;Instrument containers with the X-Ray SDK or daemon&lt;/li&gt;
&lt;li&gt;Analyze service maps for performance bottlenecks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common troubleshooting scenarios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Container health check failures&lt;/li&gt;
&lt;li&gt;Task placement failures (insufficient resources)&lt;/li&gt;
&lt;li&gt;Networking issues (security groups, service discovery)&lt;/li&gt;
&lt;li&gt;IAM permission errors (task role vs execution role)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hands-On Practice Strategy
&lt;/h2&gt;

&lt;p&gt;Reading about AWS services won't prepare you for scenario-based questions. You need hands-on experience to understand how services behave in practice. This section covers how to practice safely without unexpected AWS bills.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Hands-On Experience is Critical
&lt;/h3&gt;

&lt;p&gt;The CloudOps exam includes scenario-based questions that assume practical knowledge. You're not just choosing the correct service; you're choosing the correct configuration, parameter, or troubleshooting step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Examples of what hands-on teaches you:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudWatch alarm states and how they transition&lt;/li&gt;
&lt;li&gt;What happens when a Config rule finds non-compliant resources&lt;/li&gt;
&lt;li&gt;How Auto Scaling behaves during scale-in events&lt;/li&gt;
&lt;li&gt;Why certain IAM policies don't work as expected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exam may also include lab-style questions where you perform tasks in a simulated AWS environment. Familiarity with the console and CLI gives you an advantage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up Your Practice Environment
&lt;/h3&gt;

&lt;p&gt;Create a dedicated AWS account for exam practice. This keeps your practice resources separate and makes cleanup easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new AWS account (or use an existing sandbox account)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set up billing alerts immediately&lt;/strong&gt;: Configure Budget alerts at $5, $10, and $20 thresholds&lt;/li&gt;
&lt;li&gt;Enable Cost Explorer for spend visibility&lt;/li&gt;
&lt;li&gt;Create an IAM user for practice (avoid using root for daily activities)&lt;/li&gt;
&lt;li&gt;Tag all resources with &lt;code&gt;Project: CloudOps-Prep&lt;/code&gt; for easy cleanup&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Cost control practices:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use t3.micro or t3.small instances (Free Tier eligible)&lt;/li&gt;
&lt;li&gt;Stop or terminate resources after each practice session&lt;/li&gt;
&lt;li&gt;Set CloudWatch alarms on billing metrics&lt;/li&gt;
&lt;li&gt;Avoid services with high hourly costs (large RDS instances, NAT Gateways)&lt;/li&gt;
&lt;li&gt;Use AWS Budgets actions to stop resources if budget exceeded&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Essential Lab Scenarios
&lt;/h3&gt;

&lt;p&gt;Focus on labs that align with exam domains. Here are priority scenarios to practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitoring and Logging:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create custom CloudWatch metrics from an application&lt;/li&gt;
&lt;li&gt;Configure CloudWatch alarms with different statistics&lt;/li&gt;
&lt;li&gt;Write CloudWatch Logs Insights queries&lt;/li&gt;
&lt;li&gt;Set up CloudTrail logging and analyze events&lt;/li&gt;
&lt;li&gt;Enable Container Insights for an ECS cluster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Automation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a Systems Manager Automation document&lt;/li&gt;
&lt;li&gt;Configure Config rules with auto-remediation&lt;/li&gt;
&lt;li&gt;Set up EventBridge rules to trigger Lambda functions&lt;/li&gt;
&lt;li&gt;Use Systems Manager Run Command across multiple instances&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Deployment:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy a CloudFormation stack with parameters and outputs&lt;/li&gt;
&lt;li&gt;Perform a stack update and observe change sets&lt;/li&gt;
&lt;li&gt;Create a blue/green deployment using CodeDeploy&lt;/li&gt;
&lt;li&gt;Deploy a container application on ECS Fargate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Security:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write IAM policies and test with IAM Policy Simulator&lt;/li&gt;
&lt;li&gt;Configure KMS keys and use them for S3 encryption&lt;/li&gt;
&lt;li&gt;Set up Secrets Manager with automatic rotation&lt;/li&gt;
&lt;li&gt;Implement Config rules for compliance checking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Networking:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a VPC with public and private subnets&lt;/li&gt;
&lt;li&gt;Configure VPC endpoints for S3 and DynamoDB&lt;/li&gt;
&lt;li&gt;Set up an Application Load Balancer with path-based routing&lt;/li&gt;
&lt;li&gt;Troubleshoot connectivity using VPC Flow Logs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Free Tier Optimization and Cost Control
&lt;/h3&gt;

&lt;p&gt;AWS Free Tier includes many services useful for exam preparation. Know the limits to avoid charges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free Tier services useful for CloudOps prep:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EC2: 750 hours/month of t2.micro (t3.micro in some Regions)&lt;/li&gt;
&lt;li&gt;S3: 5GB storage, 20,000 GET requests, 2,000 PUT requests&lt;/li&gt;
&lt;li&gt;Lambda: 1 million requests, 400,000 GB-seconds&lt;/li&gt;
&lt;li&gt;CloudWatch: 10 custom metrics, 10 alarms, 5GB log ingestion&lt;/li&gt;
&lt;li&gt;DynamoDB: 25GB storage, 25 read/write capacity units&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Services to avoid or use carefully:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NAT Gateway: $0.045/hour plus data processing charges&lt;/li&gt;
&lt;li&gt;Large RDS instances: Use db.t3.micro for practice&lt;/li&gt;
&lt;li&gt;Elastic IPs: Free when attached, charged when not&lt;/li&gt;
&lt;li&gt;EKS: $0.10/hour for the control plane&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cleanup automation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schedule Lambda functions to stop EC2 instances nightly&lt;/li&gt;
&lt;li&gt;Use CloudFormation to deploy and destroy entire environments&lt;/li&gt;
&lt;li&gt;Tag resources and use Resource Groups for bulk operations&lt;/li&gt;
&lt;li&gt;Review Cost Explorer weekly during preparation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practice Exams and Self-Assessment
&lt;/h2&gt;

&lt;p&gt;Practice exams are essential for exam readiness, but timing and technique matter. Taking practice exams too early wastes them; taking them wrong reduces their value.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Start Taking Practice Exams
&lt;/h3&gt;

&lt;p&gt;Don't burn through practice exams before you've studied the content. They're most valuable for identifying gaps, not learning new material.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended timing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First practice exam&lt;/strong&gt;: At 50-60% of your study timeline. Use this to identify major gaps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Second practice exam&lt;/strong&gt;: At 75-80% of timeline. Measure improvement and find remaining gaps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Final practice exam(s)&lt;/strong&gt;: In the last few days. Validate readiness and build confidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Save official AWS practice questions for last&lt;/strong&gt;. Third-party practice exams are good for learning; official questions are best for final validation since they match the actual exam style most closely.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Use Practice Exams Effectively
&lt;/h3&gt;

&lt;p&gt;Taking a practice exam and checking your score isn't enough. The real value comes from deep review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;During the practice exam:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time yourself to simulate real conditions (roughly 2 minutes per question)&lt;/li&gt;
&lt;li&gt;Flag questions where you're uncertain&lt;/li&gt;
&lt;li&gt;Use process of elimination on difficult questions&lt;/li&gt;
&lt;li&gt;Don't look up answers during the exam&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After the practice exam:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review EVERY answer explanation, including questions you got right&lt;/li&gt;
&lt;li&gt;For wrong answers, understand why each option is correct or incorrect&lt;/li&gt;
&lt;li&gt;Track your performance by domain&lt;/li&gt;
&lt;li&gt;Note patterns in question types you struggle with&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Process of elimination strategy:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eliminate obviously wrong answers first&lt;/li&gt;
&lt;li&gt;Look for keywords that indicate correct/incorrect (always, never, must)&lt;/li&gt;
&lt;li&gt;Consider the scenario carefully; answers often depend on specific details&lt;/li&gt;
&lt;li&gt;When stuck between two options, consider which is more operationally sound&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Identifying and Addressing Weak Areas
&lt;/h3&gt;

&lt;p&gt;Use practice exam results to create a targeted remediation plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tracking weak areas:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After each practice exam, record your score by domain&lt;/li&gt;
&lt;li&gt;Calculate percentage correct per domain&lt;/li&gt;
&lt;li&gt;Identify domains below 70% as priorities&lt;/li&gt;
&lt;li&gt;Note specific services or concepts you consistently miss&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Remediation approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Below 60% in a domain&lt;/strong&gt;: Return to learning resources for that domain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;60-70% in a domain&lt;/strong&gt;: Review specific weak topics, do targeted labs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Above 70% in a domain&lt;/strong&gt;: Light review to maintain knowledge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to schedule the exam:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistently scoring 80%+ on practice exams&lt;/li&gt;
&lt;li&gt;No domain below 70%&lt;/li&gt;
&lt;li&gt;Comfortable with question pacing&lt;/li&gt;
&lt;li&gt;Feeling confident about container and multi-account content&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Exam Day Preparation
&lt;/h2&gt;

&lt;p&gt;Exam day logistics can affect your performance. Knowing what to expect eliminates surprises and lets you focus on the questions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Online Proctored vs Test Center
&lt;/h3&gt;

&lt;p&gt;Both options are valid. Choose based on your environment and preferences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Online proctored (at home):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convenience of taking the exam from your location&lt;/li&gt;
&lt;li&gt;Requires private, quiet space&lt;/li&gt;
&lt;li&gt;Must complete system test 24 hours before exam&lt;/li&gt;
&lt;li&gt;Video scan of room required before starting&lt;/li&gt;
&lt;li&gt;Camera and microphone monitored throughout&lt;/li&gt;
&lt;li&gt;Risk: Technical issues can disrupt your exam&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Test center (Pearson VUE):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dedicated testing environment&lt;/li&gt;
&lt;li&gt;No concerns about home distractions&lt;/li&gt;
&lt;li&gt;Technical setup handled by the center&lt;/li&gt;
&lt;li&gt;May require travel time&lt;/li&gt;
&lt;li&gt;Limited scheduling flexibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;: If you have a quiet, private space and reliable internet, online proctoring is convenient. If your home environment is unpredictable, a test center provides a controlled setting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Requirements and Security Measures
&lt;/h3&gt;

&lt;p&gt;For online proctored exams, technical preparation prevents day-of issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;24 hours before exam:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete the system test on Pearson VUE&lt;/li&gt;
&lt;li&gt;Verify webcam and microphone work&lt;/li&gt;
&lt;li&gt;Test your internet connection stability&lt;/li&gt;
&lt;li&gt;Clear your desk and testing area&lt;/li&gt;
&lt;li&gt;Prepare your government-issued ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Room requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Private room with closed door&lt;/li&gt;
&lt;li&gt;Clear desk (only computer and ID allowed)&lt;/li&gt;
&lt;li&gt;No notes, phones, or additional monitors&lt;/li&gt;
&lt;li&gt;No one else in the room during the exam&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prohibited items:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cell phones and smart watches&lt;/li&gt;
&lt;li&gt;Notes, books, or reference materials&lt;/li&gt;
&lt;li&gt;Additional monitors or screens&lt;/li&gt;
&lt;li&gt;Headphones or earbuds&lt;/li&gt;
&lt;li&gt;Food and drinks (water may be allowed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ID requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Government-issued ID (passport, driver's license)&lt;/li&gt;
&lt;li&gt;Name on ID must exactly match your AWS Certification account&lt;/li&gt;
&lt;li&gt;ID must be valid (not expired)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Time Management and Test-Taking Strategies
&lt;/h3&gt;

&lt;p&gt;With 65 questions in 180 minutes, you have approximately 2.5 minutes per question. That's adequate but requires discipline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pacing strategy:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First pass: Answer questions you're confident about (mark uncertain ones for review)&lt;/li&gt;
&lt;li&gt;Second pass: Return to flagged questions&lt;/li&gt;
&lt;li&gt;Final 15 minutes: Review flagged questions, don't second-guess confident answers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Question approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the entire question, including all answer options&lt;/li&gt;
&lt;li&gt;Identify what the question is actually asking (troubleshooting, best practice, most cost-effective)&lt;/li&gt;
&lt;li&gt;Eliminate obviously wrong answers&lt;/li&gt;
&lt;li&gt;Look for keywords that indicate the correct approach&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common traps:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Most" questions: Multiple answers may be correct, but one is MOST correct&lt;/li&gt;
&lt;li&gt;Scenario details matter: The answer often depends on specific requirements mentioned&lt;/li&gt;
&lt;li&gt;Cost questions: "Most cost-effective" isn't always cheapest, it's best value&lt;/li&gt;
&lt;li&gt;Time constraints: "Fastest" or "quickest" may override other considerations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Don't change answers&lt;/strong&gt;: Unless you're certain your first answer was wrong, stick with it. Second-guessing often leads to changing correct answers to incorrect ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  What If You Don't Pass?
&lt;/h2&gt;

&lt;p&gt;Failing the exam is disappointing but not disqualifying. Many successful certified professionals didn't pass on their first attempt. The key is using the experience to improve.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Your Score Report
&lt;/h3&gt;

&lt;p&gt;AWS provides a score report after the exam, even for failures. This report is your roadmap for improvement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the score report includes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overall scaled score (pass threshold is not disclosed)&lt;/li&gt;
&lt;li&gt;Performance by domain (meets expectations, needs improvement)&lt;/li&gt;
&lt;li&gt;No specific question-level feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Interpreting domain scores:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Meets expectations": You demonstrated competency in this domain&lt;/li&gt;
&lt;li&gt;"Needs improvement": This domain contributed to your failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: AWS uses scaled scoring, so raw percentage doesn't directly translate to your score. A 65% raw score might be passing or failing depending on question difficulty weighting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Your Retake Study Plan
&lt;/h3&gt;

&lt;p&gt;Use your score report to create a targeted study plan for your retake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retake rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;14-day waiting period before retake&lt;/li&gt;
&lt;li&gt;Full exam fee required ($150 USD)&lt;/li&gt;
&lt;li&gt;No limit on retake attempts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Study plan for retake:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Focus 70% of study time on "needs improvement" domains&lt;/li&gt;
&lt;li&gt;Allocate 30% to maintaining strength in passing domains&lt;/li&gt;
&lt;li&gt;Use different resources than your first attempt (different perspective helps)&lt;/li&gt;
&lt;li&gt;Take practice exams from sources you haven't used before&lt;/li&gt;
&lt;li&gt;Increase hands-on practice in weak areas&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Typical retake timeline:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most candidates retake 2-4 weeks after failure&lt;/li&gt;
&lt;li&gt;Rushing the retake often leads to similar results&lt;/li&gt;
&lt;li&gt;Better to add 1-2 weeks of focused study than fail again&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Psychological approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One failure doesn't define your capability&lt;/li&gt;
&lt;li&gt;Many AWS experts failed certifications before passing&lt;/li&gt;
&lt;li&gt;Treat the first attempt as an expensive practice exam&lt;/li&gt;
&lt;li&gt;Focus on what you learned, not what you lost&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  After Passing: Career Benefits and Next Steps
&lt;/h2&gt;

&lt;p&gt;Passing the CloudOps Engineer exam validates your operational expertise. Here's what to do with that achievement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Certification Validity and Recertification
&lt;/h3&gt;

&lt;p&gt;AWS certifications are valid for three years from your pass date. After that, you must recertify to maintain your status.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recertification options:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pass the current version of the CloudOps Engineer exam&lt;/li&gt;
&lt;li&gt;Pass the AWS DevOps Engineer Professional exam (recertifies both CloudOps and any Developer Associate)&lt;/li&gt;
&lt;li&gt;Pass a higher-level certification that includes CloudOps content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Your certification badge:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Digital badge available through AWS Certification&lt;/li&gt;
&lt;li&gt;Shareable on LinkedIn, email signatures, and professional profiles&lt;/li&gt;
&lt;li&gt;Verifiable by employers through AWS's verification system&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Career Value and Job Opportunities
&lt;/h3&gt;

&lt;p&gt;The CloudOps Engineer certification demonstrates to employers that you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manage production AWS workloads&lt;/li&gt;
&lt;li&gt;Implement monitoring and automated remediation&lt;/li&gt;
&lt;li&gt;Design resilient and cost-optimized infrastructure&lt;/li&gt;
&lt;li&gt;Work with modern container technologies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Roles that value this certification:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloud Operations Engineer&lt;/li&gt;
&lt;li&gt;DevOps Engineer&lt;/li&gt;
&lt;li&gt;Platform Engineer&lt;/li&gt;
&lt;li&gt;Site Reliability Engineer (SRE)&lt;/li&gt;
&lt;li&gt;Systems Administrator (cloud-focused)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Salary impact&lt;/strong&gt;: While certification alone doesn't guarantee salary increases, it validates skills that are in demand. Combine certification with demonstrated experience for maximum career impact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next Certifications to Consider
&lt;/h3&gt;

&lt;p&gt;CloudOps Engineer positions you well for several certification paths.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Natural progression:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS DevOps Engineer Professional&lt;/strong&gt;: If you have or pursue the Developer Associate, this Professional certification validates combined development and operations expertise. It recertifies both Associate certifications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Solutions Architect Professional&lt;/strong&gt;: Broadens your expertise from operations to architecture. Good if you want to move into solution design roles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Specialty certifications:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://towardsthecloud.com/blog/aws-security-specialty-exam-guide" rel="noopener noreferrer"&gt;AWS Security Specialty&lt;/a&gt;&lt;/strong&gt;: Deep expertise in security architecture and operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Advanced Networking Specialty&lt;/strong&gt;: Deep expertise in network design and troubleshooting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Data Engineer Associate&lt;/strong&gt;: If you work with data pipelines and analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommended path for operations professionals:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CloudOps Engineer Associate (you are here)&lt;/li&gt;
&lt;li&gt;Developer Associate (complements operations with development skills)&lt;/li&gt;
&lt;li&gt;DevOps Engineer Professional (validates full DevOps expertise)&lt;/li&gt;
&lt;/ol&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>cloudops</category>
      <category>soac03</category>
      <category>certification</category>
      <category>examguide</category>
    </item>
    <item>
      <title>AWS Security Review Checklist: Complete Self-Assessment Guide</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 17:28:28 +0000</pubDate>
      <link>https://forem.com/dannysteenman/aws-security-review-checklist-complete-self-assessment-guide-34g8</link>
      <guid>https://forem.com/dannysteenman/aws-security-review-checklist-complete-self-assessment-guide-34g8</guid>
      <description>&lt;p&gt;Every AWS breach starts with a misconfiguration someone missed. I've seen it in security reviews: one overly permissive IAM role, one security group with 0.0.0.0/0, one S3 bucket with public access. These aren't sophisticated attacks. They're &lt;a href="https://towardsthecloud.com/blog/aws-security-misconfigurations" rel="noopener noreferrer"&gt;basic misconfigurations&lt;/a&gt; that appear in 90% of accounts and violate &lt;a href="https://towardsthecloud.com/blog/aws-security-best-practices" rel="noopener noreferrer"&gt;AWS security best practices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This AWS security review checklist is the exact one I use for paid assessments. Now it's yours.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But there's a reason companies still hire me. The checklist identifies problems. Professional experience determines which problems actually matter for your specific environment, how to remediate without breaking things, and what architectural patterns prevent these issues from recurring.&lt;/p&gt;

&lt;p&gt;This AWS security review checklist follows the &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/welcome.html" rel="noopener noreferrer"&gt;AWS Well-Architected Security Pillar&lt;/a&gt;, which organizes security into seven best practice areas: security foundations, identity and access management, detection, infrastructure protection, data protection, incident response, and application security. For the full 57-question checklist across all six pillars, see the &lt;a href="https://towardsthecloud.com/blog/aws-well-architected-review-checklist" rel="noopener noreferrer"&gt;AWS Well-Architected Review checklist&lt;/a&gt;. I've organized this checklist into the domains that matter most for practical security assessments.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you'll be able to systematically assess your AWS security posture, prioritize findings by risk level, and remediate issues with specific steps. Whether you're preparing for a compliance audit, doing proactive security hygiene, or validating your current controls, this checklist gives you a structured approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use This Checklist
&lt;/h2&gt;

&lt;p&gt;Before diving into specific checks, let me explain how this assessment is structured. Understanding the approach helps you get maximum value from your time investment.&lt;/p&gt;

&lt;p&gt;Each checklist item includes a risk level indicator, specific instructions on what to check, what a "pass" looks like, what a "fail" looks like, and remediation steps. I've organized items by security domain, but you should start with the critical items across all domains before working through high and medium priorities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time Estimates by Depth Level
&lt;/h3&gt;

&lt;p&gt;Your time investment depends on what you need to accomplish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Security Scan (1-2 hours)&lt;/strong&gt;: Critical items only across all domains. This catches the misconfigurations most likely to result in a breach. Good for monthly spot-checks or when you need fast validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standard Security Review (4-8 hours)&lt;/strong&gt;: All checklist items at a reasonable depth. You'll check configurations, review findings, and document issues. Good for quarterly assessments or pre-audit preparation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comprehensive Assessment (2-3 days)&lt;/strong&gt;: Full checklist plus remediation implementation. You'll not only identify issues but fix them and verify the fixes. Good for annual deep dives or post-incident hardening.&lt;/p&gt;

&lt;p&gt;Multi-account environments multiply these estimates. A standard review of 10 accounts takes 40-80 hours unless you've configured centralized security services with aggregated findings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Required Tools and Access
&lt;/h3&gt;

&lt;p&gt;Before starting, ensure you have the necessary permissions and tools configured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IAM Permissions&lt;/strong&gt;: At minimum, you need the &lt;code&gt;SecurityAudit&lt;/code&gt; AWS managed policy attached to your IAM role. This provides read-only access to security configurations across services. For a comprehensive review, &lt;code&gt;ViewOnlyAccess&lt;/code&gt; combined with &lt;code&gt;SecurityAudit&lt;/code&gt; covers most scenarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS CLI&lt;/strong&gt;: Many checks are faster via CLI than console. Configure your CLI with the appropriate profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws sts get-caller-identity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This confirms your identity and permissions before you begin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Services&lt;/strong&gt;: Several items require specific services to be enabled. If they're not already running, enable them now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Security Hub (aggregates findings from multiple sources)&lt;/li&gt;
&lt;li&gt;AWS Config (tracks configuration compliance)&lt;/li&gt;
&lt;li&gt;Amazon GuardDuty (threat detection)&lt;/li&gt;
&lt;li&gt;AWS CloudTrail (API activity logging)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AWS accounts on Business Support or higher, AWS Trusted Advisor provides additional security checks that complement this assessment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Risk Level Indicators Explained
&lt;/h3&gt;

&lt;p&gt;Each checklist item has a risk indicator that helps you prioritize.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[CRITICAL]&lt;/strong&gt;: Immediate action required. These represent active security risks that attackers could exploit today. Missing MFA on root, public S3 buckets, security groups with 0.0.0.0/0 for SSH. Fix these before doing anything else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH]&lt;/strong&gt;: Fix within 30 days. Significant exposure that increases your attack surface or violates security best practices. Unencrypted data, missing logging, overly permissive IAM policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM]&lt;/strong&gt;: Address within a quarter. Best practice deviations that improve your security posture but don't represent immediate exploitable risk. Defense-in-depth enhancements, documentation improvements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[LOW]&lt;/strong&gt;: Nice to have. Enhancements that provide marginal security improvement. Address these when you have capacity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-Assessment: Scope and Inventory
&lt;/h2&gt;

&lt;p&gt;You can't assess what you don't know exists. Before running through checklists, document what you're reviewing. This scoping phase ensures nothing falls through the cracks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Document Your AWS Footprint
&lt;/h3&gt;

&lt;p&gt;Start by mapping your environment. This information shapes how you approach the assessment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Account Inventory&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many AWS accounts are you assessing? List account IDs and their purposes.&lt;/li&gt;
&lt;li&gt;Are accounts organized under AWS Organizations? Document the OU structure.&lt;/li&gt;
&lt;li&gt;Which account is your management account? (It has different security considerations.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Regional Usage&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which AWS regions contain active resources?&lt;/li&gt;
&lt;li&gt;Do you have resources in regions you don't expect? (This could indicate compromise.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Services in Use&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compute: EC2, Lambda, ECS, EKS?&lt;/li&gt;
&lt;li&gt;Storage: S3, EBS, EFS?&lt;/li&gt;
&lt;li&gt;Databases: RDS, DynamoDB, ElastiCache?&lt;/li&gt;
&lt;li&gt;Networking: VPC, CloudFront, API Gateway?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integration Points&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Third-party tools with AWS access&lt;/li&gt;
&lt;li&gt;CI/CD pipelines deploying to AWS&lt;/li&gt;
&lt;li&gt;SaaS applications with IAM roles&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Essential Security Tools to Enable First
&lt;/h3&gt;

&lt;p&gt;Some security tools need to run before the assessment to provide useful data. If these aren't enabled, turn them on now and schedule your assessment for when they've collected baseline data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Security Hub&lt;/strong&gt;: Aggregates findings from GuardDuty, Inspector, Macie, IAM Access Analyzer, and Config. Enable with the AWS Foundational Security Best Practices standard at minimum. Security Hub provides a security score and prioritized findings that make assessments dramatically faster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws securityhub enable-security-hub &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-default-standards&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;AWS Config&lt;/strong&gt;: Records configuration changes and evaluates compliance against rules. Enable recording for all resource types in all regions. Without Config, you lose visibility into what changed and when.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon GuardDuty&lt;/strong&gt;: Continuous threat detection analyzing CloudTrail, VPC Flow Logs, and DNS logs. Enable in all regions. GuardDuty findings often surface issues this checklist helps you investigate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS CloudTrail&lt;/strong&gt;: Records all AWS API calls. Create an organization trail if using AWS Organizations, or at minimum a multi-region trail in each account. Log file validation must be enabled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Account vs Single Account Scope
&lt;/h3&gt;

&lt;p&gt;The assessment approach differs based on your account structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Single Account&lt;/strong&gt;: Apply this checklist directly. All items are relevant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-Account with Organizations&lt;/strong&gt;: Centralized controls (SCPs, organization trails, delegated administrators) apply at the organization level. Individual account checks still apply to each member account. Use Security Hub with cross-account aggregation to view findings centrally.&lt;/p&gt;

&lt;p&gt;If you're managing multiple accounts, your &lt;a href="https://towardsthecloud.com/blog/aws-organizations-best-practices" rel="noopener noreferrer"&gt;AWS Organizations best practices&lt;/a&gt; configuration directly impacts security. Review organization-level controls in addition to individual account settings.&lt;/p&gt;

&lt;p&gt;For guidance on multi-account identity management, see &lt;a href="https://towardsthecloud.com/blog/aws-iam-identity-center" rel="noopener noreferrer"&gt;AWS IAM Identity Center&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identity and Access Management Checklist (15 Items)
&lt;/h2&gt;

&lt;p&gt;IAM misconfigurations cause more breaches than any other category. In security reviews I conduct, IAM issues appear in nearly every environment. One overly permissive policy can expose your entire AWS account.&lt;/p&gt;

&lt;p&gt;This section covers root account security, IAM user and role configuration, and credential management. Start here because IAM is where the highest-risk misconfigurations live.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Root account has MFA enabled&lt;/td&gt;
&lt;td&gt;CRITICAL&lt;/td&gt;
&lt;td&gt;Root Account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Root account has no access keys&lt;/td&gt;
&lt;td&gt;CRITICAL&lt;/td&gt;
&lt;td&gt;Root Account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Root account not used in last 90 days&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Root Account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Alternate contacts configured&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Root Account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;All IAM users with console access have MFA&lt;/td&gt;
&lt;td&gt;CRITICAL&lt;/td&gt;
&lt;td&gt;Users &amp;amp; Roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;No IAM users have administrative access&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Users &amp;amp; Roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;IAM password policy meets complexity requirements&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Users &amp;amp; Roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;No inline policies on IAM users&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Users &amp;amp; Roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;IAM Access Analyzer enabled and findings reviewed&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Users &amp;amp; Roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Permissions boundaries for sensitive roles&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Users &amp;amp; Roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Access keys rotated within 90 days&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Unused IAM users removed (90+ days inactive)&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;Unused access keys disabled or deleted&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;IAM roles used instead of access keys&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;No credentials stored in code or env variables&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Root Account Security (4 items)
&lt;/h3&gt;

&lt;p&gt;The root user has unrestricted access to everything in your account. No IAM policy, no SCP, nothing can limit it. Root account compromise means complete account compromise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[CRITICAL] Root account has MFA enabled&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; IAM &amp;gt; Security recommendations, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam get-account-summary &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'SummaryMap.AccountMFAEnabled'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Returns &lt;code&gt;1&lt;/code&gt; (MFA enabled)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Returns &lt;code&gt;0&lt;/code&gt; (MFA not enabled)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable hardware MFA (YubiKey or FIDO security key) on the root account immediately. Virtual MFA is acceptable but hardware MFA is strongly preferred for root. AWS offers free MFA security keys to eligible US account owners.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[CRITICAL] Root account has no access keys&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; IAM &amp;gt; Security recommendations, or check root user's security credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: No access keys exist for root user&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Access keys present (active or inactive)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Delete root access keys immediately. There is no legitimate reason for root access keys to exist. Any workload can use IAM roles. If you "need" root keys, you're doing something wrong.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] Root account not used in last 90 days&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; IAM &amp;gt; Credential report, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam generate-credential-report
  aws iam get-credential-report &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Content'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;root_account&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: &lt;code&gt;password_last_used&lt;/code&gt; is older than 90 days or "N/A"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Recent root usage indicates operational use of root credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Stop using root for daily operations. Create IAM users or roles for all administrative tasks. Root should only be used for account recovery and specific tasks that require root (like changing support plans or closing the account).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] Alternate contacts configured&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; Account Settings &amp;gt; Alternate contacts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Billing, Operations, and Security contacts are configured with valid email addresses (not the root email)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Alternate contacts missing or using root email&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Configure contacts with group distribution lists (e.g., &lt;a href="mailto:security@company.com"&gt;security@company.com&lt;/a&gt;) so AWS notifications reach the right people even when individuals leave the organization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IAM User and Role Configuration (6 items)
&lt;/h3&gt;

&lt;p&gt;Most environments rely too heavily on IAM users with long-term credentials. Roles with temporary credentials are more secure and should be the default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[CRITICAL] All IAM users with console access have MFA enabled&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; IAM &amp;gt; Users, filter by console access, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam list-users &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Users[*].UserName'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text | xargs &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; aws iam list-mfa-devices &lt;span class="nt"&gt;--user-name&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Every user with password-enabled login has at least one MFA device&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Users with console access but no MFA&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Require MFA for all console users. Use IAM policies with &lt;code&gt;aws:MultiFactorAuthPresent&lt;/code&gt; conditions for sensitive operations. Better yet, migrate to IAM Identity Center with enforced MFA.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] No IAM users have administrative access (use roles instead)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; IAM &amp;gt; Users, check attached policies, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam list-users &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Users[*].UserName'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text | xargs &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'echo "User: {}"; aws iam list-attached-user-policies --user-name {}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: No users have &lt;code&gt;AdministratorAccess&lt;/code&gt; or equivalent broad policies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: IAM users with admin access for daily operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Create IAM roles for administrative tasks. Use IAM Identity Center permission sets. Humans should assume roles, not have direct admin policies attached. This creates an audit trail and allows MFA enforcement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] IAM password policy meets complexity requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; IAM &amp;gt; Account settings, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam get-account-password-policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Minimum 14 characters, requires uppercase, lowercase, numbers, symbols, password expiration within 90 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Weak password policy or no policy configured&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Update the password policy:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam update-account-password-policy &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--minimum-password-length&lt;/span&gt; 14 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--require-symbols&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--require-numbers&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--require-uppercase-characters&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--require-lowercase-characters&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--max-password-age&lt;/span&gt; 90 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--password-reuse-prevention&lt;/span&gt; 24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;[HIGH] No inline policies on IAM users (use managed policies)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; IAM &amp;gt; Users &amp;gt; select user &amp;gt; Permissions tab, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam list-users &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Users[*].UserName'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text | xargs &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'echo "User: {}"; aws iam list-user-policies --user-name {}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: No inline policies; all permissions via managed policies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Users with inline policies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Convert inline policies to customer managed policies. Managed policies are easier to audit, update, and reuse. Inline policies hide permissions and make reviews harder.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] IAM Access Analyzer enabled and findings reviewed&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; IAM &amp;gt; Access Analyzer, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws accessanalyzer list-analyzers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Analyzer exists and active findings have been reviewed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: No analyzer configured or unreviewed findings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Create an Access Analyzer:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws accessanalyzer create-analyzer &lt;span class="nt"&gt;--analyzer-name&lt;/span&gt; account-analyzer &lt;span class="nt"&gt;--type&lt;/span&gt; ACCOUNT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review findings weekly. Access Analyzer identifies resources shared with external accounts, unused permissions, and overly broad policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] Permissions boundaries implemented for sensitive roles&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review IAM roles used by development teams or automation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Roles that can create other roles have permission boundaries preventing privilege escalation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Roles can create new roles with any permissions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Implement permission boundaries for delegated administration. This prevents teams from granting themselves more access than intended. See AWS documentation on &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html" rel="noopener noreferrer"&gt;permissions boundaries&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Credential Management (5 items)
&lt;/h3&gt;

&lt;p&gt;Long-term credentials (access keys) are a significant attack surface. Temporary credentials through roles are always preferred.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] Access keys rotated within 90 days&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; IAM &amp;gt; Credential report, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam generate-credential-report
  aws iam get-credential-report &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Content'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: No active access keys older than 90 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Keys older than 90 days in use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Rotate keys following AWS guidance: create new key, update applications, verify new key works, disable old key, delete old key after grace period. Better: migrate to IAM roles and eliminate access keys entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] Unused IAM users removed (no activity in 90+ days)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Credential report &lt;code&gt;password_last_used&lt;/code&gt; and &lt;code&gt;access_key_*_last_used&lt;/code&gt; columns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All users show activity within 90 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Users with no activity for 90+ days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Disable inactive users first (allows recovery if needed), then delete after confirmation. Implement user lifecycle processes that deactivate accounts when employees leave.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] Unused access keys disabled or deleted&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Credential report &lt;code&gt;access_key_*_last_used_date&lt;/code&gt; columns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: No active keys unused for 90+ days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Active keys with no recent usage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Deactivate unused keys:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam update-access-key &lt;span class="nt"&gt;--user-name&lt;/span&gt; USER_NAME &lt;span class="nt"&gt;--access-key-id&lt;/span&gt; ACCESS_KEY_ID &lt;span class="nt"&gt;--status&lt;/span&gt; Inactive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete after confirming nothing breaks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] IAM roles used instead of access keys for applications&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review applications and services for credential sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: EC2 uses instance profiles, Lambda uses execution roles, ECS uses task roles, external services use IAM Roles Anywhere&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Applications using long-term access keys in config files or environment variables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Migrate to IAM roles. For workloads outside AWS (CI/CD, on-premises), use IAM Roles Anywhere with X.509 certificates or OIDC federation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] No credentials stored in code or environment variables&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Code scanning, environment variable review, Secrets Manager usage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Credentials retrieved from Secrets Manager or Parameter Store at runtime&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Credentials in source code, config files, or environment variables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Use AWS Secrets Manager for database credentials and API keys. Use Parameter Store for non-sensitive configuration. Implement CodeGuru Reviewer or git-secrets to prevent credential commits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Network Security Checklist (12 Items)
&lt;/h2&gt;

&lt;p&gt;Network security determines what can communicate with what. A single misconfigured security group can expose your database to the entire internet. These checks verify your network perimeter is properly protected.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Production workloads in private subnets&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;VPC Config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;VPC Flow Logs enabled for all VPCs&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;VPC Config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Multiple Availability Zones used&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;VPC Config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;VPC endpoints configured for AWS service access&lt;/td&gt;
&lt;td&gt;LOW&lt;/td&gt;
&lt;td&gt;VPC Config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;No security groups allow SSH (22) from 0.0.0.0/0&lt;/td&gt;
&lt;td&gt;CRITICAL&lt;/td&gt;
&lt;td&gt;Security Groups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;No security groups allow RDP (3389) from 0.0.0.0/0&lt;/td&gt;
&lt;td&gt;CRITICAL&lt;/td&gt;
&lt;td&gt;Security Groups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Default security groups have no rules&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Security Groups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Security group rules documented with descriptions&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Security Groups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;NACLs configured for additional subnet protection&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Security Groups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;AWS WAF configured for public-facing applications&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Internet-Facing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;CloudFront distributions use HTTPS only&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Internet-Facing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Shield Advanced considered for critical apps&lt;/td&gt;
&lt;td&gt;LOW&lt;/td&gt;
&lt;td&gt;Internet-Facing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  VPC Configuration (4 items)
&lt;/h3&gt;

&lt;p&gt;Proper VPC design creates layers of defense. Resources should be segmented by security zone with network controls between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] Production workloads in private subnets&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; VPC &amp;gt; Subnets, verify subnet route tables, or identify EC2 instances in subnets with internet gateway routes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Application servers, databases, and sensitive workloads have no direct internet gateway route&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Production resources in subnets with 0.0.0.0/0 route to internet gateway&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Move resources to private subnets. Use NAT Gateway for outbound internet access. Use Application Load Balancer in public subnets to route traffic to private resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] VPC Flow Logs enabled for all VPCs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; VPC &amp;gt; Your VPCs &amp;gt; select VPC &amp;gt; Flow Logs tab, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 describe-vpcs &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Vpcs[*].VpcId'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text | xargs &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; aws ec2 describe-flow-logs &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;resource-id,Values&lt;span class="o"&gt;={}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Every VPC has flow logs enabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: VPCs without flow logs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable flow logs for each VPC:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 create-flow-logs &lt;span class="nt"&gt;--resource-type&lt;/span&gt; VPC &lt;span class="nt"&gt;--resource-ids&lt;/span&gt; vpc-xxxx &lt;span class="nt"&gt;--traffic-type&lt;/span&gt; ALL &lt;span class="nt"&gt;--log-destination-type&lt;/span&gt; cloud-watch-logs &lt;span class="nt"&gt;--log-group-name&lt;/span&gt; vpc-flow-logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flow logs are essential for security investigation and GuardDuty threat detection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] Multiple Availability Zones used&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review subnet configuration across AZs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Resources distributed across at least 2 AZs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: All resources in single AZ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Create subnets in multiple AZs. Configure Auto Scaling groups and load balancers for multi-AZ. This improves both availability and security (limits blast radius).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[LOW] VPC endpoints configured for AWS service access&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; VPC &amp;gt; Endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Gateway endpoints for S3 and DynamoDB; interface endpoints for commonly used services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: All AWS API calls traverse internet gateway&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Create VPC endpoints for frequently accessed AWS services. This reduces internet exposure and often improves latency. Start with S3 (gateway endpoint, free) and security services like CloudTrail, Security Hub.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Groups and NACLs (5 items)
&lt;/h3&gt;

&lt;p&gt;Security groups are your primary network firewall. Misconfigurations here are among the most common and dangerous findings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[CRITICAL] No security groups allow SSH (22) from 0.0.0.0/0&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; EC2 &amp;gt; Security Groups, filter for port 22 rules, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 describe-security-groups &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ip-permission.from-port,Values&lt;span class="o"&gt;=&lt;/span&gt;22 &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ip-permission.cidr,Values&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'0.0.0.0/0'&lt;/span&gt; &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'SecurityGroups[*].[GroupId,GroupName]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: No results returned&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Security groups with SSH open to internet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Remove 0.0.0.0/0 rules for SSH. Use AWS Systems Manager Session Manager instead, which requires no open inbound ports. If SSH must be used, restrict to specific bastion host or VPN IP ranges.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[CRITICAL] No security groups allow RDP (3389) from 0.0.0.0/0&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Same approach as SSH but for port 3389
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 describe-security-groups &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ip-permission.from-port,Values&lt;span class="o"&gt;=&lt;/span&gt;3389 &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ip-permission.cidr,Values&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'0.0.0.0/0'&lt;/span&gt; &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'SecurityGroups[*].[GroupId,GroupName]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: No results returned&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Security groups with RDP open to internet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Remove 0.0.0.0/0 rules for RDP. Use Session Manager for Windows instance access. If RDP is required, use a bastion host in a separate VPC with restricted access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] Default security groups have no inbound or outbound rules&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; EC2 &amp;gt; Security Groups, filter for "default", or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 describe-security-groups &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;group-name,Values&lt;span class="o"&gt;=&lt;/span&gt;default &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'SecurityGroups[*].[VpcId,IpPermissions,IpPermissionsEgress]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Default security groups have no rules (empty IpPermissions arrays)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Default security groups with rules (default allows all traffic within the group)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Remove all rules from default security groups. Create purpose-specific security groups for resources. Never use default security groups for actual workloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] Security group rules documented with descriptions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review security group rules for Description field&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All rules have meaningful descriptions explaining their purpose&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Rules with empty or generic descriptions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Add descriptions to all security group rules explaining what traffic they allow and why. This helps during audits and incident investigation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] NACLs configured for additional subnet protection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; VPC &amp;gt; Network ACLs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Custom NACLs with appropriate rules for sensitive subnets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Using only default NACL (allows all traffic)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Create custom NACLs for database and sensitive subnets. NACLs are stateless, so both inbound and outbound rules are needed. They provide defense-in-depth beyond security groups.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Internet-Facing Resources (3 items)
&lt;/h3&gt;

&lt;p&gt;Resources exposed to the internet need additional protection layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] AWS WAF configured for public-facing applications&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; WAF &amp;amp; Shield &amp;gt; Web ACLs, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws wafv2 list-web-acls &lt;span class="nt"&gt;--scope&lt;/span&gt; REGIONAL
  aws wafv2 list-web-acls &lt;span class="nt"&gt;--scope&lt;/span&gt; CLOUDFRONT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: WAF associated with all public-facing ALBs, API Gateways, and CloudFront distributions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Internet-facing resources without WAF protection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Create WAF web ACLs with AWS Managed Rules (Core Rule Set, Known Bad Inputs). Associate with all public resources. Enable rate limiting to protect against volumetric attacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] CloudFront distributions use HTTPS only&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; CloudFront &amp;gt; Distributions, check Viewer Protocol Policy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All distributions configured for "Redirect HTTP to HTTPS" or "HTTPS Only"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Distributions allowing HTTP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Update viewer protocol policy to redirect HTTP to HTTPS. Ensure custom SSL certificates are configured if using custom domains. Enforce minimum TLS 1.2.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[LOW] Shield Advanced considered for critical applications&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; WAF &amp;amp; Shield &amp;gt; AWS Shield&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Shield Advanced enabled for business-critical applications, or documented decision to accept Shield Standard protection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: No consideration of DDoS protection for critical applications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Evaluate Shield Advanced for applications where downtime has significant business impact. Shield Standard (free) protects against common attacks. Shield Advanced adds 24/7 DDoS Response Team access and cost protection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Data Protection Checklist (10 Items)
&lt;/h2&gt;

&lt;p&gt;Encryption is your last line of defense. If other controls fail and attackers access your data, proper encryption ensures they get encrypted garbage instead of readable customer data.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;EBS encryption enabled by default&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Encryption at Rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;RDS instances encrypted&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Encryption at Rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;S3 default encryption configured on all buckets&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Encryption at Rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Customer managed KMS keys for sensitive workloads&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Encryption at Rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;S3 bucket policies require HTTPS&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Encryption in Transit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;RDS connections use SSL/TLS&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Encryption in Transit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Load balancers terminate TLS with modern policies&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Encryption in Transit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;S3 Block Public Access enabled at account level&lt;/td&gt;
&lt;td&gt;CRITICAL&lt;/td&gt;
&lt;td&gt;S3 Security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;No buckets with public access (unless required)&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;S3 Security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;S3 versioning enabled for critical buckets&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;S3 Security&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Encryption at Rest (4 items)
&lt;/h3&gt;

&lt;p&gt;All data stored in AWS should be encrypted. Since January 2023, S3 encrypts new objects by default, but other services and legacy data need verification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] EBS encryption enabled by default&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; EC2 &amp;gt; Settings &amp;gt; EBS encryption, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 get-ebs-encryption-by-default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: &lt;code&gt;EbsEncryptionByDefault: true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: &lt;code&gt;EbsEncryptionByDefault: false&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable account-wide EBS encryption:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 enable-ebs-encryption-by-default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This applies to all new volumes. Existing unencrypted volumes require creating encrypted snapshots and new volumes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] RDS instances encrypted&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; RDS &amp;gt; Databases, check Encryption column, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws rds describe-db-instances &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'DBInstances[*].[DBInstanceIdentifier,StorageEncrypted]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All instances show &lt;code&gt;StorageEncrypted: true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Unencrypted RDS instances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: RDS encryption uses AES-256 and cannot be enabled on existing unencrypted instances. Create an encrypted snapshot, then restore to a new encrypted instance. Plan for migration and testing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] S3 default encryption configured on all buckets&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; S3 &amp;gt; select bucket &amp;gt; Properties &amp;gt; Default encryption, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3api list-buckets &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Buckets[*].Name'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text | xargs &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'echo "Bucket: {}"; aws s3api get-bucket-encryption --bucket {} 2&amp;gt;&amp;amp;1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All buckets have default encryption configured (SSE-S3 or SSE-KMS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Buckets without default encryption (legacy buckets created before January 2023)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable default encryption:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3api put-bucket-encryption &lt;span class="nt"&gt;--bucket&lt;/span&gt; BUCKET_NAME &lt;span class="nt"&gt;--server-side-encryption-configuration&lt;/span&gt; &lt;span class="s1"&gt;'{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;[MEDIUM] Customer managed KMS keys for sensitive workloads&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review KMS key usage for sensitive data stores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Sensitive data encrypted with customer managed keys (you control key policy)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Relying solely on AWS managed keys for data requiring strict access control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Create customer managed KMS keys for sensitive workloads. This provides audit trails via CloudTrail, fine-grained access control via key policies, and cross-account sharing capabilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Encryption in Transit (3 items)
&lt;/h3&gt;

&lt;p&gt;Data moving between systems needs protection from interception and tampering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] S3 bucket policies require HTTPS (aws:SecureTransport)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review bucket policies for SecureTransport condition, or use Config rule &lt;code&gt;s3-bucket-ssl-requests-only&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All buckets have policies denying requests without SecureTransport&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Buckets accessible over HTTP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Add this policy to all buckets:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Deny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::BUCKET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::BUCKET/*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"Bool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"aws:SecureTransport"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;[HIGH] RDS connections use SSL/TLS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review RDS parameter groups for &lt;code&gt;rds.force_ssl&lt;/code&gt; parameter, check application connection strings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: SSL/TLS enforced at database level or all applications use SSL connections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Unencrypted database connections possible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: For PostgreSQL, set &lt;code&gt;rds.force_ssl=1&lt;/code&gt; in parameter group. For MySQL, set &lt;code&gt;require_secure_transport=ON&lt;/code&gt;. Update application connection strings to use SSL and verify certificates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] Load balancers terminate TLS with modern security policies&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; EC2 &amp;gt; Load Balancers &amp;gt; select ALB &amp;gt; Listeners, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws elbv2 describe-listeners &lt;span class="nt"&gt;--load-balancer-arn&lt;/span&gt; ALB_ARN &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Listeners[*].[Protocol,SslPolicy]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: HTTPS listeners using ELBSecurityPolicy-TLS13-1-2-2021-06 or newer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: HTTP only or outdated TLS policies (TLS 1.0, 1.1)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Update listener security policy to enforce TLS 1.2 minimum. TLS 1.3 preferred for modern applications. Remove HTTP listeners unless needed for redirect-only.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  S3 Bucket Security (3 items)
&lt;/h3&gt;

&lt;p&gt;S3 misconfigurations have caused some of the highest-profile cloud data breaches. These checks are critical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[CRITICAL] S3 Block Public Access enabled at account level&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; S3 &amp;gt; Block Public Access settings for this account, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3control get-public-access-block &lt;span class="nt"&gt;--account-id&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; Account &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All four settings enabled (BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy, RestrictPublicBuckets)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Any setting disabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable all Block Public Access settings at account level:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3control put-public-access-block &lt;span class="nt"&gt;--account-id&lt;/span&gt; ACCOUNT_ID &lt;span class="nt"&gt;--public-access-block-configuration&lt;/span&gt; &lt;span class="s2"&gt;"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents accidental public bucket creation. For buckets that legitimately need public access, use CloudFront with Origin Access Control instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] No buckets with public access (unless explicitly required)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; S3, check "Access" column, or use IAM Access Analyzer for S3&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: No buckets show "Public" or "Objects can be public" (except documented exceptions)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Buckets with public access that shouldn't be public&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Review each public bucket. Most public buckets should use CloudFront instead. If public access is required, document the business justification and ensure Block Public Access is still enabled at account level (bucket-level settings override).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] S3 versioning enabled for critical buckets&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; S3 &amp;gt; select bucket &amp;gt; Properties &amp;gt; Bucket Versioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Versioning enabled for buckets containing important data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Critical data in non-versioned buckets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable versioning to protect against accidental deletion and ransomware:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3api put-bucket-versioning &lt;span class="nt"&gt;--bucket&lt;/span&gt; BUCKET_NAME &lt;span class="nt"&gt;--versioning-configuration&lt;/span&gt; &lt;span class="nv"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider S3 Object Lock for compliance requirements preventing even root from deleting objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logging and Detection Checklist (8 Items)
&lt;/h2&gt;

&lt;p&gt;Without proper logging, you can't investigate incidents or detect threats. These services form your security visibility foundation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;CloudTrail enabled with multi-region trail&lt;/td&gt;
&lt;td&gt;CRITICAL&lt;/td&gt;
&lt;td&gt;CloudTrail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;CloudTrail log file validation enabled&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;CloudTrail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;CloudTrail logs encrypted with KMS&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;CloudTrail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;GuardDuty enabled in all regions&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Security Hub enabled with FSBP standard&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;AWS Config enabled with recording in all regions&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;CloudWatch alarms for critical security events&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Alerting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;GuardDuty findings routed with notifications&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Alerting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  CloudTrail Configuration (3 items)
&lt;/h3&gt;

&lt;p&gt;CloudTrail records every AWS API call. It's the foundation of AWS audit trails and essential for security investigation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[CRITICAL] CloudTrail enabled with multi-region trail&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; CloudTrail &amp;gt; Trails, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws cloudtrail describe-trails &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'trailList[*].[Name,IsMultiRegionTrail,IsOrganizationTrail]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: At least one trail with &lt;code&gt;IsMultiRegionTrail: true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Single-region trails only or no trails&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Create a multi-region trail:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws cloudtrail create-trail &lt;span class="nt"&gt;--name&lt;/span&gt; organization-trail &lt;span class="nt"&gt;--s3-bucket-name&lt;/span&gt; cloudtrail-logs-bucket &lt;span class="nt"&gt;--is-multi-region-trail&lt;/span&gt; &lt;span class="nt"&gt;--enable-log-file-validation&lt;/span&gt;
  aws cloudtrail start-logging &lt;span class="nt"&gt;--name&lt;/span&gt; organization-trail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For AWS Organizations, create an organization trail for all accounts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] CloudTrail log file validation enabled&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; CloudTrail &amp;gt; Trails &amp;gt; select trail, check Log file validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: &lt;code&gt;LogFileValidationEnabled: true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Log file validation disabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable log file validation when creating trail or update existing trail. Validation uses SHA-256 digests to detect log tampering.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] CloudTrail logs encrypted with KMS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; CloudTrail &amp;gt; Trails &amp;gt; select trail, check KMS key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Trail configured with KMS encryption key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Using S3-managed keys (SSE-S3) or no encryption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Update trail to use KMS encryption. This provides additional access control through key policy and audit trail of who accessed logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Monitoring Services (3 items)
&lt;/h3&gt;

&lt;p&gt;These services analyze logs and configurations to detect threats and misconfigurations automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] GuardDuty enabled in all regions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; GuardDuty, check each region, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="k"&gt;for &lt;/span&gt;region &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;aws ec2 describe-regions &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Regions[*].RegionName'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Region: &lt;/span&gt;&lt;span class="nv"&gt;$region&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    aws guardduty list-detectors &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="nv"&gt;$region&lt;/span&gt;
  &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Detector exists in every region&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: GuardDuty disabled in some regions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable GuardDuty in all regions. Attackers can operate in any region, and disabled regions create blind spots. Enable all protection plans (S3, EKS, Malware, RDS, Lambda).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] Security Hub enabled with AWS Foundational Security Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; Security Hub &amp;gt; Security standards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Security Hub enabled with FSBP standard active&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Security Hub disabled or no standards enabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable Security Hub with default standards:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws securityhub enable-security-hub &lt;span class="nt"&gt;--enable-default-standards&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review your security score weekly and address Critical and High findings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] AWS Config enabled with recording in all regions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; Config &amp;gt; Settings, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws configservice describe-configuration-recorder-status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Configuration recorder recording in all regions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Config not enabled or limited regions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable Config with all resource types. Deploy conformance packs for automated compliance checking against CIS Benchmarks and AWS Foundational Best Practices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Alerting and Response (2 items)
&lt;/h3&gt;

&lt;p&gt;Detection without alerting is just logging. You need to know when threats are detected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] CloudWatch alarms for critical security events (root login, unauthorized API calls)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; CloudWatch &amp;gt; Alarms, review security-related alarms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Alarms configured for root login, IAM changes, CloudTrail configuration changes, security group changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: No security event alarms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Create metric filters and alarms for critical events. At minimum: root account usage, IAM policy changes, CloudTrail modifications, failed console logins, security group changes. Route alerts to SNS topics monitored by your security team.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] GuardDuty findings routed to Security Hub with automated notifications&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Security Hub shows GuardDuty findings, EventBridge rules for findings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: GuardDuty findings appear in Security Hub, high-severity findings trigger notifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: No integration or alerting for findings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: GuardDuty integrates with Security Hub automatically when both are enabled. Create EventBridge rules to route high and critical findings to SNS for immediate notification:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"aws.securityhub"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"detail-type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Security Hub Findings - Imported"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"findings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"Severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"Label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CRITICAL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HIGH"&lt;/span&gt;&lt;span class="p"&gt;]}}}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Compute Security Checklist (10 Items)
&lt;/h2&gt;

&lt;p&gt;Compute resources, including EC2 instances, Lambda functions, and containers, run your workloads. Misconfigurations here can expose your applications and data.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Risk&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;IMDSv2 required on all instances (IMDSv1 disabled)&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;EC2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;No EC2 instances with administrative IAM roles&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;EC2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Systems Manager Session Manager used instead of SSH&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;EC2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Amazon Inspector scanning enabled&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;EC2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;All Lambda functions using supported runtimes&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Lambda&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Lambda functions have least privilege IAM roles&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Lambda&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Lambda code scanning enabled in Inspector&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Lambda&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;ECR image scanning enabled&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;EKS clusters using supported Kubernetes versions&lt;/td&gt;
&lt;td&gt;HIGH&lt;/td&gt;
&lt;td&gt;Containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Container images scanned in CI/CD before deployment&lt;/td&gt;
&lt;td&gt;MEDIUM&lt;/td&gt;
&lt;td&gt;Containers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  EC2 Instance Security (4 items)
&lt;/h3&gt;

&lt;p&gt;EC2 instances require configuration beyond the defaults to be secure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] IMDSv2 required on all instances (IMDSv1 disabled)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; EC2 &amp;gt; Instances &amp;gt; select instance &amp;gt; Actions &amp;gt; Instance settings &amp;gt; Modify instance metadata options, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 describe-instances &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Reservations[*].Instances[*].[InstanceId,MetadataOptions.HttpTokens]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All instances show &lt;code&gt;HttpTokens: required&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Instances with &lt;code&gt;HttpTokens: optional&lt;/code&gt; (allows IMDSv1)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: IMDSv1 is vulnerable to SSRF attacks. Require IMDSv2:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 modify-instance-metadata-options &lt;span class="nt"&gt;--instance-id&lt;/span&gt; i-xxxx &lt;span class="nt"&gt;--http-tokens&lt;/span&gt; required &lt;span class="nt"&gt;--http-endpoint&lt;/span&gt; enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set account-wide default for new instances via EC2 settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] No EC2 instances with administrative IAM roles&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review instance profiles for attached policies
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 describe-instances &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Reservations[*].Instances[*].[InstanceId,IamInstanceProfile.Arn]'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check each role for admin policies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: No instance roles have &lt;code&gt;AdministratorAccess&lt;/code&gt; or equivalent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Instances with admin IAM roles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Replace admin policies with specific permissions needed for the workload. Use IAM Access Analyzer to generate least-privilege policies based on actual usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] Systems Manager Session Manager used instead of SSH keys&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review how teams access instances, check for SSH key pairs in use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Session Manager is primary access method, SSH keys eliminated or minimized&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: SSH keys distributed to team members for instance access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Configure Session Manager for instance access. Install SSM Agent (pre-installed on Amazon Linux 2+). Create IAM policies allowing &lt;code&gt;ssm:StartSession&lt;/code&gt;. Session Manager provides audit logging and eliminates exposed SSH ports.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] Amazon Inspector scanning enabled&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; Inspector &amp;gt; Account management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Inspector enabled for EC2, ECR, and Lambda scanning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Inspector not enabled or scanning disabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable Inspector for continuous vulnerability scanning. Inspector scans for OS vulnerabilities, application dependencies, and network exposure. Integrates with Security Hub for centralized findings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lambda Function Security (3 items)
&lt;/h3&gt;

&lt;p&gt;Lambda functions have unique security considerations around runtime versions and IAM permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] All functions using supported runtimes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; Lambda &amp;gt; Functions, check Runtime column, or:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws lambda list-functions &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Functions[*].[FunctionName,Runtime]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All functions use runtimes in standard support (not deprecated)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Functions using deprecated runtimes (Python 3.7, Node.js 14, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Upgrade functions to supported runtimes. Deprecated runtimes receive no security patches. Review &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html" rel="noopener noreferrer"&gt;AWS Lambda runtime support policy&lt;/a&gt; for current deprecation schedule.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] Lambda functions have least privilege IAM roles&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review Lambda execution role policies for each function&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Functions have specific permissions for their needs (e.g., specific DynamoDB tables, specific S3 buckets)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Functions with &lt;code&gt;*&lt;/code&gt; resources or broad service permissions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Refine IAM policies to specific resources. Use IAM Access Analyzer to identify unused permissions. Common mistake: &lt;code&gt;dynamodb:*&lt;/code&gt; when function only needs &lt;code&gt;GetItem&lt;/code&gt; on one table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] Lambda code scanning enabled in Inspector&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; Inspector &amp;gt; Account management &amp;gt; Lambda scanning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Lambda standard scanning and Lambda code scanning enabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Code scanning not enabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable Lambda code scanning to identify vulnerabilities in custom code, not just dependencies. This catches security issues in your application logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Container Security (3 items)
&lt;/h3&gt;

&lt;p&gt;Container environments add layers that each need security attention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] ECR image scanning enabled&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; ECR &amp;gt; Repositories &amp;gt; select repo &amp;gt; Scan on push&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Scan on push enabled, or Inspector scanning configured for ECR&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: No image scanning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Enable scan on push for all repositories. Better: enable Inspector enhanced scanning which rescans as new CVEs are published, not just at push time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[HIGH] EKS clusters using supported Kubernetes versions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Console &amp;gt; EKS &amp;gt; Clusters, check Kubernetes version&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: All clusters on supported versions (check &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html" rel="noopener noreferrer"&gt;Amazon EKS Kubernetes versions&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Clusters on deprecated versions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Plan cluster upgrades to supported versions. Deprecated versions don't receive security patches. EKS supports versions for approximately 14 months after release.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;[MEDIUM] Container images scanned in CI/CD before deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to check&lt;/strong&gt;: Review CI/CD pipeline configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass&lt;/strong&gt;: Pipeline fails on critical vulnerabilities before images reach production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail&lt;/strong&gt;: Images deployed without scanning or without failing on findings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remediation&lt;/strong&gt;: Integrate Inspector or ECR scanning into CI/CD. Set thresholds to fail builds on critical vulnerabilities. This shifts security left and catches issues before production.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prioritizing Your Findings
&lt;/h2&gt;

&lt;p&gt;You've run through the checklist and found issues. Now what? Not everything needs fixing immediately. Risk-based prioritization ensures you address the most dangerous issues first.&lt;/p&gt;

&lt;p&gt;The framework below helps you decide what to fix now versus what can wait. This is based on actual risk, not just the severity label I've assigned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Risk-Based Prioritization Framework
&lt;/h3&gt;

&lt;p&gt;When evaluating each finding, consider four factors:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Severity&lt;/strong&gt;: How bad is the potential impact if this is exploited? Root account without MFA is severe because it enables complete account takeover. An unused security group is less severe because it's not currently attached to anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exploitability&lt;/strong&gt;: How easy is this to exploit? A security group allowing SSH from 0.0.0.0/0 is trivially exploitable. An overly permissive IAM policy requires an attacker to already have some access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exposure&lt;/strong&gt;: Is this resource publicly accessible? A misconfigured public S3 bucket is more urgent than a misconfigured internal S3 bucket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compliance Impact&lt;/strong&gt;: Will this fail an audit? If you have SOC 2 certification to maintain, compliance-related findings have business urgency beyond pure security risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Critical Items (Fix Immediately)
&lt;/h3&gt;

&lt;p&gt;These findings represent active security risks. Drop everything and fix these today.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Root account without MFA&lt;/strong&gt;: One password away from complete account compromise&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security groups with 0.0.0.0/0 for SSH (22) or RDP (3389)&lt;/strong&gt;: Brute force attacks begin within minutes of exposure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publicly accessible S3 buckets with sensitive data&lt;/strong&gt;: Data breaches happen from exactly this misconfiguration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudTrail disabled or single-region only&lt;/strong&gt;: You can't investigate what you can't see&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM access keys for root user&lt;/strong&gt;: Should never exist&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  High Priority (Fix Within 30 Days)
&lt;/h3&gt;

&lt;p&gt;Significant exposure that increases attack surface or violates critical best practices.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unencrypted RDS databases or EBS volumes&lt;/strong&gt;: Data at rest without protection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM users without MFA&lt;/strong&gt;: Credential compromise risk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access keys not rotated in 90+ days&lt;/strong&gt;: Increased window of exposure if compromised&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GuardDuty not enabled in all regions&lt;/strong&gt;: Detection blind spots&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default security groups in use&lt;/strong&gt;: Overly permissive default rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unsupported Lambda runtimes&lt;/strong&gt;: No security patches available&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Medium and Low Priority Items
&lt;/h3&gt;

&lt;p&gt;These improve your security posture but don't represent immediate exploitable risk.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VPC endpoints not configured&lt;/strong&gt;: Defense-in-depth enhancement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security group rules without descriptions&lt;/strong&gt;: Documentation improvement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S3 versioning not enabled&lt;/strong&gt;: Data protection enhancement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shield Advanced not evaluated&lt;/strong&gt;: DDoS protection consideration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Resource Constraints Guidance
&lt;/h3&gt;

&lt;p&gt;If you're a small team with limited time, focus exclusively on Critical items first. A single engineer can address critical findings across one account in 2-4 hours.&lt;/p&gt;

&lt;p&gt;For larger teams, parallelize: one person on IAM, one on network, one on data protection. Use Security Hub findings to track progress and verify remediation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compliance-Specific Items
&lt;/h2&gt;

&lt;p&gt;If you're working toward specific compliance certifications, certain checklist items map directly to compliance requirements. This section helps you prioritize based on your compliance needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  SOC 2 Alignment
&lt;/h3&gt;

&lt;p&gt;SOC 2 Trust Service Criteria focus on security, availability, processing integrity, confidentiality, and privacy. Key checklist items for SOC 2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: IAM MFA, access key rotation, CloudTrail logging, encryption at rest and in transit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Availability&lt;/strong&gt;: Multi-AZ deployments, backup configurations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidentiality&lt;/strong&gt;: S3 Block Public Access, KMS encryption, security group restrictions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS Audit Manager provides pre-built frameworks for &lt;a href="https://towardsthecloud.com/blog/aws-soc-2-compliance" rel="noopener noreferrer"&gt;SOC 2 with 15 automated and 46 manual controls&lt;/a&gt;. For complete guidance on preparing for SOC 2 audits including evidence collection strategies and common failure patterns, see our AWS SOC 2 compliance guide. Access SOC reports via AWS Artifact to verify AWS's compliance with their portion of shared responsibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  HIPAA Considerations
&lt;/h3&gt;

&lt;p&gt;If handling Protected Health Information (PHI), additional requirements apply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Business Associate Agreement (BAA)&lt;/strong&gt;: Must be in place with AWS before processing PHI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HIPAA-eligible services only&lt;/strong&gt;: Not all AWS services are covered. Use only services listed in AWS HIPAA eligible services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encryption requirements&lt;/strong&gt;: PHI must be encrypted at rest and in transit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access logging&lt;/strong&gt;: Comprehensive audit trails for all PHI access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS Audit Manager includes HIPAA frameworks with automated evidence collection.&lt;/p&gt;

&lt;h3&gt;
  
  
  PCI DSS Requirements
&lt;/h3&gt;

&lt;p&gt;For payment card data processing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Network segmentation&lt;/strong&gt;: Cardholder data environment must be isolated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encryption&lt;/strong&gt;: TLS 1.2+ for transmission, encryption at rest for stored card data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging&lt;/strong&gt;: Comprehensive audit trails with tamper protection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access control&lt;/strong&gt;: Strict least privilege for cardholder data access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS maintains PCI DSS Level 1 Service Provider certification. Access the Attestation of Compliance (AOC) via AWS Artifact.&lt;/p&gt;

&lt;h3&gt;
  
  
  CIS AWS Foundations Benchmark
&lt;/h3&gt;

&lt;p&gt;The CIS Benchmark provides specific, actionable security recommendations. Security Hub includes the CIS AWS Foundations Benchmark standard with automated checks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Level 1&lt;/strong&gt;: Basic security hygiene applicable to all organizations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 2&lt;/strong&gt;: Additional controls for sensitive environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enable the CIS standard in Security Hub for automated compliance checking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws securityhub batch-enable-standards &lt;span class="nt"&gt;--standards-subscription-requests&lt;/span&gt; &lt;span class="s1"&gt;'{"StandardsArn":"arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.4.0"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When DIY Isn't Enough
&lt;/h2&gt;

&lt;p&gt;I've given you the complete checklist I use for security reviews. You can absolutely run through this yourself and improve your security posture significantly. But let me be honest about when DIY approaches hit their limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Signs You Need Professional Help
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Complex multi-account environments (10+ accounts)&lt;/strong&gt;: The checklist scales, but the effort multiplies. Aggregating findings, understanding cross-account dependencies, and coordinating remediation across teams requires experience and tooling beyond what most internal teams have.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compliance audit preparation with tight timelines&lt;/strong&gt;: If you need &lt;a href="https://towardsthecloud.com/blog/aws-soc-2-compliance" rel="noopener noreferrer"&gt;SOC 2 certification in 90 days&lt;/a&gt;, learning compliance requirements while implementing them is risky. Experienced practitioners know the shortcuts and pitfalls. If you're facing compliance requirements or want an expert assessment of your AWS security posture, consider a &lt;a href="https://towardsthecloud.com/blog/aws-security-review-process" rel="noopener noreferrer"&gt;professional AWS security audit&lt;/a&gt; to understand your options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Previous security incident requiring forensic analysis&lt;/strong&gt;: Post-incident analysis requires skills most teams don't maintain. Preserving evidence, building timelines, identifying root cause, and validating remediation completeness benefit from external expertise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Findings you don't know how to remediate&lt;/strong&gt;: The checklist tells you what's wrong, but some remediations require architectural changes. Migrating from IAM users to IAM Identity Center, redesigning VPCs for proper segmentation, or implementing least privilege at scale are projects, not tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lack of internal security expertise&lt;/strong&gt;: If your team is excellent at development and operations but doesn't have security specialists, external review catches what internal teams miss. Security requires different thinking patterns than building features.&lt;/p&gt;

&lt;p&gt;When evaluating AWS security partners, use our &lt;a href="https://towardsthecloud.com/blog/aws-security-partner" rel="noopener noreferrer"&gt;partner selection framework&lt;/a&gt; with a 10-point checklist, discovery call questions, and guidance on choosing between Big 4, boutique specialists, and AWS Professional Services.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Professional Reviews Include Beyond This Checklist
&lt;/h3&gt;

&lt;p&gt;This checklist covers configuration-level security. Professional reviews go deeper:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom threat modeling for your architecture&lt;/strong&gt;: Understanding how your specific application architecture creates attack surfaces that generic checklists miss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture review and recommendations&lt;/strong&gt;: Not just "is this misconfigured" but "is this the right architecture." Sometimes the right fix is redesign, not reconfiguration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compliance gap analysis with remediation roadmap&lt;/strong&gt;: Mapping your current state to compliance requirements and creating prioritized plans that account for dependencies and effort.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Penetration testing and vulnerability assessment&lt;/strong&gt;: Actively attempting to exploit vulnerabilities to validate controls work under attack. The checklist finds misconfigurations, pen tests find exploitable vulnerabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ongoing monitoring and response setup&lt;/strong&gt;: Moving from point-in-time assessment to continuous security operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next Steps
&lt;/h3&gt;

&lt;p&gt;If you've worked through this checklist and found issues you're confident remediating, that's excellent. Most organizations can handle the foundational items internally.&lt;/p&gt;

&lt;p&gt;If you've found findings that concern you, have compliance timelines to meet, or want validation that you haven't missed something, consider a &lt;a href="https://towardsthecloud.com/blog/aws-security-audit" rel="noopener noreferrer"&gt;professional AWS security audit&lt;/a&gt; to understand your options.&lt;/p&gt;

&lt;p&gt;For organizations that want expert assessment of their AWS security posture, I conduct comprehensive security reviews that identify misconfigurations, compliance gaps, and architectural weaknesses this checklist can't catch.&lt;/p&gt;

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

&lt;p&gt;You now have the complete checklist I use for professional security reviews. Let me summarize what matters most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with the critical items.&lt;/strong&gt; Root MFA, no 0.0.0.0/0 for SSH/RDP, S3 Block Public Access at account level, CloudTrail in all regions. These prevent the misconfigurations that cause actual breaches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enable the detection foundation.&lt;/strong&gt; Security Hub, GuardDuty, Config, and CloudTrail form your security visibility layer. Without them, you're flying blind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Document findings and create a remediation roadmap.&lt;/strong&gt; Track what you found, prioritize by risk, and schedule fixes. A finding without a remediation plan is just awareness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Schedule regular reviews.&lt;/strong&gt; Quarterly for stable environments. After significant infrastructure changes. Before compliance audits. After security incidents. Security posture degrades over time as new resources are created and configurations drift.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Know when to get help.&lt;/strong&gt; DIY works for many organizations, especially for foundational security. But compliance requirements, complex environments, and post-incident analysis often benefit from experienced practitioners.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your immediate action&lt;/strong&gt;: Run through the critical items in the IAM and Network sections today. It takes less than an hour and addresses your highest risks. Then schedule time for the full checklist.&lt;/p&gt;

&lt;p&gt;Have questions about specific findings or want to discuss what you discovered? Drop a comment below.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>awssecurity</category>
      <category>securitychecklist</category>
      <category>iamsecurity</category>
      <category>cloudtrail</category>
    </item>
    <item>
      <title>AWS Security Review Process: What Happens Step by Step</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 17:28:24 +0000</pubDate>
      <link>https://forem.com/dannysteenman/aws-security-review-process-what-happens-step-by-step-1e8b</link>
      <guid>https://forem.com/dannysteenman/aws-security-review-process-what-happens-step-by-step-1e8b</guid>
      <description>&lt;p&gt;You've decided your AWS environment needs a professional security review. Maybe you've already booked a call, or maybe you're comparing providers and want to understand the AWS security review process before committing. Either way, here's exactly what happens, step by step, day by day, so there are no surprises.&lt;/p&gt;

&lt;p&gt;Whether you call it a security review, a &lt;a href="https://towardsthecloud.com/blog/aws-security-audit" rel="noopener noreferrer"&gt;security audit or assessment&lt;/a&gt;, the goal is the same: identify what's misconfigured, what's missing, and what needs to change. Having reviewed 200+ AWS accounts, I can tell you that &lt;a href="https://towardsthecloud.com/blog/aws-security-misconfigurations" rel="noopener noreferrer"&gt;the same misconfigurations appear in 90% of environments&lt;/a&gt;. The difference between a good review and a great one is how findings are prioritized and presented so you can actually act on them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;By the end of this guide, you'll know exactly what to prepare, what happens during each phase, what you'll receive, and what your options are afterward.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Before the Review: How to Prepare
&lt;/h2&gt;

&lt;p&gt;Security review preparation on your end is minimal. Most clients spend less than an hour total across the entire engagement. Here's what helps the review go smoothly.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Need from You (Access and Documentation)
&lt;/h3&gt;

&lt;p&gt;The most common preparation mistake is granting full admin access. I don't need it and don't want it. Here's what's actually required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read-only IAM role&lt;/strong&gt;: A role with the &lt;code&gt;SecurityAudit&lt;/code&gt; AWS managed policy attached. This provides &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html" rel="noopener noreferrer"&gt;read-only access&lt;/a&gt; to security configurations without any ability to modify your environment. I provide a CloudFormation template to set this up in minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architecture documentation&lt;/strong&gt; (if available): Diagrams, service maps, or even a rough sketch of how your environment is structured. Helpful but not required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance requirements&lt;/strong&gt;: If you need to align with specific frameworks (SOC 2, HIPAA, PCI-DSS, CIS), let me know upfront so the review covers those controls. For SOC 2 specifically, see how &lt;a href="https://towardsthecloud.com/blog/aws-soc-2-compliance" rel="noopener noreferrer"&gt;AWS SOC 2 compliance requirements&lt;/a&gt; map to your controls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Known concerns&lt;/strong&gt;: Anything keeping you up at night. Recent incidents, areas you suspect are misconfigured, or services you've outgrown.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Who Should Be Involved
&lt;/h3&gt;

&lt;p&gt;You don't need to assemble a large team. Three people typically cover it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AWS account owner or administrator&lt;/strong&gt; - to provision the read-only IAM role&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical lead or CTO&lt;/strong&gt; - for 30 minutes of architecture context during the discovery call&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance or security lead&lt;/strong&gt; (if applicable) - to confirm framework alignment requirements&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Total time commitment from your team: roughly 30-60 minutes across the entire engagement.&lt;/strong&gt; The rest happens on my side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 1: Discovery Call and Access Setup
&lt;/h2&gt;

&lt;p&gt;Once you've set up the read-only role, the engagement kicks off with a discovery call. This is where I learn what matters most to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  What We Cover in the Discovery Call
&lt;/h3&gt;

&lt;p&gt;The discovery call runs 30-45 minutes and covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your environment&lt;/strong&gt;: How many accounts, which regions, what services you're running, and how your architecture is structured&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business context&lt;/strong&gt;: What workloads are business-critical, what compliance obligations you have, and what triggered the review&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope alignment&lt;/strong&gt;: Confirming which accounts and regions to assess, and which compliance frameworks to evaluate against&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Known risk areas&lt;/strong&gt;: Any services or configurations you're already concerned about&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This conversation is important because it determines focus. A startup with a single account running a SaaS application gets a different emphasis than a company with 20 accounts preparing for a SOC 2 audit. The &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/shared-responsibility.html" rel="noopener noreferrer"&gt;AWS shared responsibility model&lt;/a&gt; defines what falls under your responsibility, and the discovery call ensures I'm reviewing the parts that matter most to your business.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up Secure Read-Only Access
&lt;/h3&gt;

&lt;p&gt;If you haven't provisioned the IAM role beforehand, we handle it during this step. The role uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimal permissions&lt;/strong&gt;: The &lt;code&gt;SecurityAudit&lt;/code&gt; managed policy, nothing more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No write access&lt;/strong&gt;: I cannot create, modify, or delete any resources in your environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trust relationship scoped&lt;/strong&gt;: The role is only assumable from a specific external account ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Access setup takes about 10 minutes using the CloudFormation template I provide. Once confirmed, the analysis begins, typically on the same day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Days 1-2: The Security Analysis Process
&lt;/h2&gt;

&lt;p&gt;This is the core of the engagement. The assessment combines automated scanning with manual expert review, aligned with the &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/welcome.html" rel="noopener noreferrer"&gt;AWS Well-Architected Security Pillar&lt;/a&gt; and its seven best practice areas. For the detailed checklist behind this process, see &lt;a href="https://towardsthecloud.com/blog/aws-security-review-checklist" rel="noopener noreferrer"&gt;our complete AWS security review checklist&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Review (The Seven Security Domains)
&lt;/h3&gt;

&lt;p&gt;Every review covers these seven domains systematically:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Security Domain&lt;/th&gt;
&lt;th&gt;What Gets Checked&lt;/th&gt;
&lt;th&gt;Key Tools Used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Identity and Access Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Root account security, MFA enforcement, unused credentials, overly permissive policies, access key rotation&lt;/td&gt;
&lt;td&gt;IAM Access Analyzer, Security Hub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Network Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;VPC configuration, security groups (0.0.0.0/0 checks), NACLs, public exposure, VPC endpoints&lt;/td&gt;
&lt;td&gt;VPC Flow Logs, Config Rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Protection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Encryption at rest (SSE-S3, SSE-KMS), encryption in transit (TLS 1.2+), S3 public access blocks, KMS key management&lt;/td&gt;
&lt;td&gt;Security Hub, S3 policies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Logging and Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CloudTrail in all regions, VPC Flow Logs, CloudWatch alarms, DNS query logging&lt;/td&gt;
&lt;td&gt;CloudTrail, CloudWatch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Infrastructure Protection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;EC2 patching, container security, Lambda function configurations, security group segmentation&lt;/td&gt;
&lt;td&gt;Inspector, Config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Detection and Threat Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GuardDuty status, Security Hub findings, Inspector vulnerability scans, alert routing&lt;/td&gt;
&lt;td&gt;GuardDuty, Inspector, Security Hub&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compliance Alignment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;FSBP controls, CIS Benchmark checks, framework-specific requirements&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://aws.amazon.com/security-hub/features/" rel="noopener noreferrer"&gt;Security Hub&lt;/a&gt;, Audit Manager&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Tools and Methodology
&lt;/h3&gt;

&lt;p&gt;I use a combination of native AWS security services and open-source tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS Security Hub&lt;/strong&gt; - Centralized security scoring with automated checks against FSBP and CIS benchmarks. Security Hub aggregates findings from multiple sources and provides exposure findings with attack path analysis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Inspector&lt;/strong&gt; - Automated vulnerability scanning of EC2 instances, container images, and Lambda functions, including both package vulnerability and code vulnerability detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM Access Analyzer&lt;/strong&gt; - Identifies external access to your resources, unused permissions, and validates policies using automated reasoning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Config&lt;/strong&gt; - Evaluates resource compliance against managed rules and conformance packs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon GuardDuty&lt;/strong&gt; - Reviews threat detection status across CloudTrail, VPC Flow Logs, and DNS, including Extended Threat Detection for multi-stage attack identification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prowler&lt;/strong&gt; - Open-source CIS benchmark assessment that complements native AWS tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual expert review&lt;/strong&gt; - Architecture analysis, policy review, and business-context evaluation that automated tools cannot perform&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The automated tools identify what's misconfigured. The manual review determines what actually matters for your environment and what the tools miss. That combination is the difference between running &lt;a href="https://aws.amazon.com/security-hub/features/" rel="noopener noreferrer"&gt;AWS Security Hub&lt;/a&gt; yourself and hiring someone who knows how to interpret the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Deliverable: Your Security Report Walkthrough
&lt;/h2&gt;

&lt;p&gt;Once the analysis is complete, everything gets compiled into a prioritized security posture assessment and report. Here's what that report contains, because "you'll receive a detailed report" tells you nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Findings Are Classified
&lt;/h3&gt;

&lt;p&gt;Every finding is classified by severity, following the same model used by AWS Security Hub and Inspector:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Critical&lt;/strong&gt;: Immediate risk to data or operations. Active exposure, public access to sensitive resources, or exploitable vulnerabilities. Fix within days.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High&lt;/strong&gt;: Significant risk requiring prompt action. Missing MFA on privileged accounts, overly permissive IAM policies, or disabled logging. Fix within 2 weeks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medium&lt;/strong&gt;: Moderate risk to address in normal development cycles. Non-optimal encryption settings, missing tags, or security group refinements. Fix within 1-3 months.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low&lt;/strong&gt;: Best practice improvements that strengthen your overall posture. Documentation gaps, minor configuration optimizations. Address during regular maintenance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each finding includes: &lt;strong&gt;what was found&lt;/strong&gt;, &lt;strong&gt;why it matters&lt;/strong&gt; (business impact, not just technical risk), &lt;strong&gt;how to fix it&lt;/strong&gt; (specific remediation steps), and &lt;strong&gt;estimated effort&lt;/strong&gt; so you can plan resources. On average, a review identifies 15-30 findings per account, with 2-5 classified as critical or high.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the Remediation Roadmap Looks Like
&lt;/h3&gt;

&lt;p&gt;The report doesn't just list problems. It organizes them into a prioritized roadmap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quick wins (0-30 days)&lt;/strong&gt;: Enabling MFA, removing overly permissive security group rules, enabling CloudTrail across all regions, rotating old access keys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Short-term (1-3 months)&lt;/strong&gt;: Implementing least-privilege IAM policies, deploying GuardDuty, configuring CloudWatch alarms, establishing automated backups&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long-term (3-6 months)&lt;/strong&gt;: Centralizing logging to a dedicated account, implementing automated remediation, completing compliance framework alignment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the report is ready, I walk you through every finding on a call. You can ask questions, challenge priorities, and discuss remediation approaches. This isn't a document dump. It's a conversation about what to fix and in what order.&lt;/p&gt;

&lt;h2&gt;
  
  
  After the Review: Your Options
&lt;/h2&gt;

&lt;p&gt;The report walkthrough call is included in every engagement. After that, you have three options. No pressure, no upsell. The report stands on its own regardless of what you choose.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remediation Support
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Self-remediation.&lt;/strong&gt; You take the report and fix findings using the step-by-step guidance included with each finding. Many teams handle quick wins and short-term items internally. The remediation roadmap tells you exactly what to do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Guided remediation.&lt;/strong&gt; I help you implement the fixes, especially for complex changes like IAM policy refactoring, network segmentation, or multi-account security architecture. This is common for teams that want to move fast without risk of breaking production workloads.&lt;/p&gt;

&lt;p&gt;For a broader understanding of what good security looks like, &lt;a href="https://towardsthecloud.com/blog/aws-security-best-practices" rel="noopener noreferrer"&gt;AWS security best practices&lt;/a&gt; covers the foundational patterns behind these remediations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ongoing Security Monitoring
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Option 3: Continuous security partnership.&lt;/strong&gt; Security isn't a one-time activity. For organizations that want ongoing monitoring, this includes periodic reviews (quarterly is the most common cadence), drift detection, and new-finding triage. AWS recommends a continuous monitoring approach with daily Security Hub reviews, weekly Inspector findings analysis, and quarterly &lt;a href="https://towardsthecloud.com/blog/aws-well-architected-review-checklist" rel="noopener noreferrer"&gt;Well-Architected reassessments&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The right option depends on your team's capacity and expertise. Most clients start with guided remediation for critical and high findings, then handle the rest internally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample Timeline: From Booking to Deliverables
&lt;/h2&gt;

&lt;p&gt;The most common question I get is "how long does this take?" Here's the typical timeline for a standard AWS security review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Total: approximately 1 week from kickoff to deliverables&lt;/strong&gt; for a standard single-account or small multi-account environment.&lt;/p&gt;

&lt;p&gt;Larger environments with 10+ accounts, multiple regions, or complex architectures may take longer. Timelines vary based on organization size and scope, which is exactly why the discovery call happens first. I'll give you a specific estimate after understanding your environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Questions About the AWS Security Review Process
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Ready to Start Your AWS Security Review?
&lt;/h2&gt;

&lt;p&gt;Now you know exactly what the AWS security review process involves: minimal preparation on your end, a focused analysis across seven security domains, a prioritized report with clear remediation steps, and a walkthrough call to discuss every finding.&lt;/p&gt;

&lt;p&gt;The entire process takes approximately one week. Your team's time commitment is roughly an hour total. You receive actionable findings, not vague recommendations, and you choose what happens next.&lt;/p&gt;

&lt;p&gt;The first step is a discovery call to understand your environment and confirm scope. If you want to self-assess before booking, start with &lt;a href="https://towardsthecloud.com/blog/aws-security-review-checklist" rel="noopener noreferrer"&gt;our complete AWS security review checklist&lt;/a&gt;. If you're still evaluating providers, here's &lt;a href="https://towardsthecloud.com/blog/aws-security-partner" rel="noopener noreferrer"&gt;how to choose an AWS security partner&lt;/a&gt; using a structured framework.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>awssecurity</category>
      <category>securityreview</category>
      <category>awswellarchitected</category>
      <category>securityhub</category>
    </item>
    <item>
      <title>AWS Cost Optimization Checklist: The Maturity-Based Framework [2026]</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 15:21:39 +0000</pubDate>
      <link>https://forem.com/dannysteenman/aws-cost-optimization-checklist-the-maturity-based-framework-2026-1opo</link>
      <guid>https://forem.com/dannysteenman/aws-cost-optimization-checklist-the-maturity-based-framework-2026-1opo</guid>
      <description>&lt;p&gt;You've seen the lists. "30 Ways to Reduce Your AWS Bill." "The Ultimate AWS Cost Optimization Checklist." They dump 40+ items on you and call it a day. But knowing what to optimize and knowing where to start are entirely different problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real challenge is prioritization.&lt;/strong&gt; When you're staring at a checklist with rightsizing, Savings Plans, Graviton migration, and storage class optimization all competing for attention, how do you know which delivers the biggest impact for your current situation?&lt;/p&gt;

&lt;p&gt;This AWS cost optimization checklist takes a different approach. Instead of overwhelming you with a flat list, I've organized optimizations into four maturity levels. You identify where you are today, then work through the checklist items appropriate for your stage. Level 1 quick wins can deliver 10-20% savings in 30 days. Level 2 strategic optimizations add 20-35% with proper planning. By Level 4, you're running automated cost governance that sustains savings without constant manual effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding AWS Cost Optimization
&lt;/h2&gt;

&lt;p&gt;Before diving into specific checklist items, let's establish the framework that guides prioritization. The &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/cost-optimization-pillar/welcome.html" rel="noopener noreferrer"&gt;AWS Well-Architected Cost Optimization pillar&lt;/a&gt; defines five practice areas that form the foundation of any cost optimization program.&lt;/p&gt;

&lt;p&gt;Understanding these areas helps you see how individual checklist items connect to broader capabilities. It also ensures your optimization efforts align with AWS's proven practices rather than random tactical improvements.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Well-Architected Framework Approach
&lt;/h3&gt;

&lt;p&gt;For the complete set of Cost Optimization questions (COST 1-11) as they appear in the AWS Well-Architected Tool, see the &lt;a href="https://towardsthecloud.com/blog/aws-well-architected-review-checklist" rel="noopener noreferrer"&gt;Well-Architected Review checklist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Cost Optimization pillar organizes practices into five interconnected areas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Financial Management&lt;/strong&gt;: Implementing tools and processes for clear understanding of costs, including allocation, budgeting, and forecasting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expenditure and Usage Awareness&lt;/strong&gt;: Monitoring and analyzing usage patterns to identify cost-saving opportunities through detailed visibility&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost-Effective Resources&lt;/strong&gt;: Using the right type and size of AWS resources, considering total cost of ownership including operational overhead&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managing Demand and Supply Resources&lt;/strong&gt;: Scaling dynamically based on actual demand rather than maintaining fixed capacity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimizing Over Time&lt;/strong&gt;: Continuously evaluating opportunities as AWS releases new services and features&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These aren't sequential checkboxes. They're ongoing practices that mature together as your organization grows. A Level 1 team focuses heavily on the first two areas while building capability in the others. A Level 4 team operates effectively across all five.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost Optimization Maturity Assessment
&lt;/h3&gt;

&lt;p&gt;The maturity model translates these broad practice areas into concrete organizational capabilities. Here's how the four levels map to real-world states:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where are you today?&lt;/strong&gt; Ask yourself these questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Level 1 indicators&lt;/strong&gt;: Can you identify your top 5 spending services in 30 seconds? Do you have budget alerts configured? Have you cleaned up idle resources in the last 90 days?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 2 indicators&lt;/strong&gt;: Do you have Savings Plans or Reserved Instances covering steady-state workloads? Are non-production instances scheduled to stop during off-hours? Have you acted on rightsizing recommendations?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 3 indicators&lt;/strong&gt;: Have you evaluated Graviton migration? Do you understand your data transfer costs? Are your Lambda functions memory-optimized?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 4 indicators&lt;/strong&gt;: Do you have &lt;a href="https://towardsthecloud.com/blog/aws-scp-service-control-policies" rel="noopener noreferrer"&gt;Service Control Policies&lt;/a&gt; enforcing cost guardrails? Is cost allocation tagging enforced organization-wide? Do developers consider cost impact during design?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you answered "no" to any Level 1 question, start there. Don't jump to Graviton migration when you haven't cleaned up your idle resources first.&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS Cost Management Tools Foundation
&lt;/h2&gt;

&lt;p&gt;Before implementing optimizations, you need visibility into your costs. These five tools form the foundation of AWS cost management. Set them up before tackling the optimization levels since you'll reference their recommendations throughout.&lt;/p&gt;

&lt;p&gt;The good news: most of these tools are free or included with your existing support tier. The effort to set them up is minimal compared to the value they provide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost Optimization Hub
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/aws-cost-management/cost-optimization-hub/" rel="noopener noreferrer"&gt;Cost Optimization Hub&lt;/a&gt; is your central dashboard for optimization opportunities across accounts and regions. It consolidates over 15 types of recommendations including EC2 rightsizing, Graviton migration, idle resource detection, Savings Plans opportunities, and EBS volume optimization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key capabilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quantifies and aggregates estimated savings accounting for existing discounts (RIs, Savings Plans)&lt;/li&gt;
&lt;li&gt;Automatically groups related recommendations and deduplicates resource optimization strategies&lt;/li&gt;
&lt;li&gt;Prioritizes recommendations by highest savings&lt;/li&gt;
&lt;li&gt;Free to use with no additional cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enable Cost Optimization Hub in your management account to see organization-wide recommendations in a single view.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost Explorer
&lt;/h3&gt;

&lt;p&gt;Cost Explorer provides visualization and analysis for AWS costs and usage over time. It's your primary tool for understanding spending patterns before taking optimization action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom reports with charts and tabular data at various levels (service, account, tag)&lt;/li&gt;
&lt;li&gt;Cost forecasting for up to 12 months based on usage patterns&lt;/li&gt;
&lt;li&gt;13 months of historical data for trend analysis&lt;/li&gt;
&lt;li&gt;Rightsizing recommendations for EC2 instances&lt;/li&gt;
&lt;li&gt;Reserved Instance and Savings Plans recommendations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Data refreshes at least once every 24 hours. Make checking Cost Explorer part of your morning routine to catch anomalies quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compute Optimizer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/compute-optimizer/latest/ug/supported-resources.html" rel="noopener noreferrer"&gt;AWS Compute Optimizer&lt;/a&gt; uses machine learning to recommend optimal AWS resources based on actual usage data. It analyzes 14-32 days of utilization history (varies by resource type) and provides estimated monthly savings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supported resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon EC2 instances and Auto Scaling groups&lt;/li&gt;
&lt;li&gt;EBS volumes (gp2, gp3, io1, io2, io2 Block Express, st1, sc1)&lt;/li&gt;
&lt;li&gt;Lambda functions (memory configuration)&lt;/li&gt;
&lt;li&gt;RDS databases (MySQL, PostgreSQL, Aurora MySQL, Aurora PostgreSQL)&lt;/li&gt;
&lt;li&gt;ECS on Fargate services&lt;/li&gt;
&lt;li&gt;Idle resource detection for EC2, ASG, EBS, ECS, RDS, and NAT Gateways&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Compute Optimizer requires opt-in activation. Enable it now if you haven't already. You can customize rightsizing preferences including CPU/memory utilization thresholds and preferred instance types.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trusted Advisor
&lt;/h3&gt;

&lt;p&gt;Trusted Advisor offers real-time guidance across five categories: cost optimization, performance, security, fault tolerance, and service limits. For cost optimization specifically, it checks for over-provisioned resources, idle resources, unattached Elastic IPs, and S3 buckets without lifecycle policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access levels:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Basic Support&lt;/strong&gt;: 7 checks available&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business/Enterprise Support&lt;/strong&gt;: All 50+ checks with weekly refresh&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're on Business or Enterprise Support, leverage the full Trusted Advisor check library. The additional checks surface optimization opportunities that basic checks miss.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Budgets and Cost Anomaly Detection
&lt;/h3&gt;

&lt;p&gt;AWS Budgets lets you set custom budgets for costs, usage, and commitment discounts with alert notifications when exceeding or forecasted to exceed thresholds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key capabilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monthly budgets at aggregate or granular level with daily granularity for near-real-time tracking&lt;/li&gt;
&lt;li&gt;Alert notifications via email, SNS, Slack, or Teams&lt;/li&gt;
&lt;li&gt;Budget actions for automated responses (apply IAM policies, SCPs, stop instances)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cost Anomaly Detection complements Budgets by using machine learning to identify unusual spending patterns. It runs approximately 3 times per day and provides up to 10 potential root causes with approximate dollar impact per anomaly. Unlike threshold-based Budgets, Anomaly Detection catches unexpected spending patterns you might not have anticipated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 1: Reactive Cost Management (Quick Wins)
&lt;/h2&gt;

&lt;p&gt;Level 1 focuses on eliminating obvious waste and establishing visibility. These optimizations require minimal planning, can be implemented in 0-30 days, and typically deliver 10-20% savings with low effort.&lt;/p&gt;

&lt;p&gt;If you haven't done these items yet, don't skip to Level 2. The savings from Level 1 often fund the time investment for more strategic optimizations, and the visibility you establish here guides your Level 2 priorities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delete Unused and Idle Resources
&lt;/h3&gt;

&lt;p&gt;Idle resources cost money without delivering value. When &lt;a href="https://towardsthecloud.com/blog/aws-costs-keep-increasing" rel="noopener noreferrer"&gt;your AWS bill keeps growing&lt;/a&gt; due to forgotten resources, these deletions provide immediate relief. AWS Compute Optimizer provides &lt;a href="https://docs.aws.amazon.com/compute-optimizer/latest/ug/view-idle-recommendations.html" rel="noopener noreferrer"&gt;specific criteria for identifying idle resources&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EC2 Instances&lt;/strong&gt; (14-day lookback):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Peak CPU utilization 5% or less AND network I/O less than 5MB/day&lt;/li&gt;
&lt;li&gt;Recommendation: Delete instance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;EBS Volumes&lt;/strong&gt; (32-day lookback):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less than 1 read/write operation per day for non-root volumes OR unattached&lt;/li&gt;
&lt;li&gt;Recommendation: Create snapshot, then delete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;RDS Databases&lt;/strong&gt; (14-day lookback):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No database connections, low CPU usage, low read/write activity&lt;/li&gt;
&lt;li&gt;Recommendation: Stop (7-day max before auto-restart), snapshot and delete, or convert Aurora to Serverless v2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;NAT Gateways&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Available state, not in route tables, no active connections&lt;/li&gt;
&lt;li&gt;Recommendation: Verify network architecture role, then delete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Always create snapshots or backups before deleting.&lt;/strong&gt; The cost of retaining a snapshot is far less than recreating a resource you deleted by mistake. For automation scripts to &lt;a href="https://towardsthecloud.com/blog/amazon-ec2-delete-unused-elastic-ip-addresses" rel="noopener noreferrer"&gt;clean up unused Elastic IPs across all regions&lt;/a&gt;, see our dedicated guide.&lt;/p&gt;

&lt;h3&gt;
  
  
  EBS Volume Cleanup and Migration
&lt;/h3&gt;

&lt;p&gt;EBS volumes continue charging whether attached or not. Unattached volumes are pure waste.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick wins:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Delete unattached volumes (same cost as attached, zero value)&lt;/li&gt;
&lt;li&gt;Delete old snapshots beyond your retention requirements&lt;/li&gt;
&lt;li&gt;Migrate gp2 volumes to gp3 for immediate 20% savings&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The gp2 to gp3 migration is particularly compelling. &lt;strong&gt;gp3 costs $0.08/GiB-month compared to gp2's $0.10/GiB-month&lt;/strong&gt;, and gp3 includes a baseline of 3,000 IOPS and 125 MiB/s throughput at no extra cost. Most workloads see better performance at lower cost with no downtime during migration.&lt;/p&gt;

&lt;p&gt;Compute Optimizer generates recommendations for EBS volume optimization. Check the console or use AWS CLI to identify migration candidates across your accounts.&lt;/p&gt;

&lt;p&gt;To compare costs across all EBS volume types and find the most cost-effective configuration, use our &lt;a href="https://cloudburn.io/tools/amazon-ebs-pricing-calculator" rel="noopener noreferrer"&gt;EBS Pricing Calculator&lt;/a&gt; with IOPS/throughput modeling.&lt;/p&gt;

&lt;h3&gt;
  
  
  CloudWatch Logs Retention
&lt;/h3&gt;

&lt;p&gt;Here's a cost driver that most teams overlook: CloudWatch Logs default retention is indefinite. Every log ever written stays forever unless you configure retention policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Action items:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review all log groups and set appropriate retention periods (1 day to 10 years based on compliance requirements)&lt;/li&gt;
&lt;li&gt;Export old logs to S3 for cost-effective long-term storage if needed&lt;/li&gt;
&lt;li&gt;Use S3 Lifecycle policies to transition exported logs to Glacier classes&lt;/li&gt;
&lt;li&gt;Review logging levels and avoid DEBUG in production unless actively troubleshooting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Logs take up to 72 hours to delete after the retention period expires, so don't expect immediate savings. But preventing indefinite accumulation stops costs from growing unbounded.&lt;/p&gt;

&lt;p&gt;For automation, see our guide on how to &lt;a href="https://towardsthecloud.com/blog/amazon-cloudwatch-set-logs-retention-policy" rel="noopener noreferrer"&gt;automate CloudWatch Logs retention with Python&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Up Budget Alerts
&lt;/h3&gt;

&lt;p&gt;Budget alerts prevent cost surprises before they become disasters. Configure budgets for both actual spend and forecasted spend since forecast alerts give you earlier warning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended budget structure:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Account-level budget&lt;/strong&gt;: Set at 110% of expected monthly spend. Alert at 50%, 80%, 100%, and 120% thresholds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service-specific budgets&lt;/strong&gt;: For your top 3 services by spend, set individual budgets to catch service-specific anomalies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily spend budget&lt;/strong&gt;: Enable daily granularity for faster anomaly detection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AWS Budgets also supports automated actions when thresholds are exceeded. You can automatically apply IAM policies that restrict launching new resources, giving you a safety net against runaway costs.&lt;/p&gt;

&lt;p&gt;Enable Cost Anomaly Detection alongside Budgets. While Budgets trigger on thresholds you define, Anomaly Detection uses ML to identify unusual patterns you might not anticipate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Activate Cost Allocation Tags
&lt;/h3&gt;

&lt;p&gt;Tags are the foundation of cost allocation. Without them, you can see total spending but can't attribute costs to teams, projects, or environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implement these essential tags:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Environment&lt;/strong&gt;: production, staging, development&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Project&lt;/strong&gt;: website-redesign, mobile-app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Owner&lt;/strong&gt;: platform-team, data-engineering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CostCenter&lt;/strong&gt;: CC-1234, engineering-ops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Critical steps after creating tags:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Activate tags in the Billing Console for cost allocation reports (tags don't appear automatically)&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://towardsthecloud.com/blog/aws-organizations-best-practices" rel="noopener noreferrer"&gt;AWS Organizations tag policies&lt;/a&gt; to standardize tags across accounts&lt;/li&gt;
&lt;li&gt;Set up Cost Categories to group costs by business logic beyond simple tags&lt;/li&gt;
&lt;li&gt;Document tagging conventions and communicate to all teams&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Tags are case-sensitive and aren't retroactive. Establish naming conventions before rolling out, and know that costs from before tag creation won't be categorized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 2: Proactive Cost Optimization (Strategic)
&lt;/h2&gt;

&lt;p&gt;With visibility established and waste eliminated, Level 2 focuses on strategic optimizations that require more planning but deliver greater savings. These items take 30-90 days to implement properly and can add 20-35% savings on top of Level 1 gains.&lt;/p&gt;

&lt;p&gt;The key difference from Level 1: these optimizations require understanding your workload patterns before committing. Don't purchase Savings Plans until you've cleaned up idle resources and understand your baseline usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proactive Cost Estimation
&lt;/h3&gt;

&lt;p&gt;Here's a principle most cost optimization guides miss: &lt;strong&gt;preventing underutilized resources is always better than reactively optimizing or cleaning them up&lt;/strong&gt;. If you can estimate costs before deployment, you make informed decisions while developing rather than discovering cost problems months later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;CloudBurn&lt;/a&gt; is a Cost Optimization CLI we developed that runs deterministic cost rules against Terraform and CloudFormation in CI, then runs those same rules against live AWS infrastrucute using it's discovery tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How proactive cost estimation helps:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers see cost implications before merging, enabling informed architecture decisions&lt;/li&gt;
&lt;li&gt;Large cost increases trigger discussion during PR review, not after deployment&lt;/li&gt;
&lt;li&gt;Teams build cost awareness into their development workflow naturally&lt;/li&gt;
&lt;li&gt;Prevents the accumulation of underutilized resources that require reactive cleanup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This shift-left approach to cost management reduces the time and effort spent on optimization since you're preventing waste rather than chasing it. When every infrastructure change includes cost visibility, teams make better decisions by default.&lt;/p&gt;

&lt;h3&gt;
  
  
  EC2 Rightsizing Strategy
&lt;/h3&gt;

&lt;p&gt;Rightsizing ensures instances are appropriately sized for workloads. AWS Compute Optimizer analyzes 14 days of utilization data and classifies instances into three categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Over-provisioned&lt;/strong&gt;: Specifications can be reduced while meeting performance requirements (typically 25% cost reduction opportunity)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Under-provisioned&lt;/strong&gt;: At least one specification doesn't meet requirements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimized&lt;/strong&gt;: Current configuration appropriately matches workload needs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each recommendation includes a Performance Risk Rating from very low to very high. Start with "very low" risk recommendations to build confidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rightsizing process:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Review Compute Optimizer recommendations for your accounts&lt;/li&gt;
&lt;li&gt;Validate by checking CloudWatch metrics for CPU, memory, and network utilization&lt;/li&gt;
&lt;li&gt;For stateless workloads, resize during a maintenance window&lt;/li&gt;
&lt;li&gt;For stateful workloads, create a new instance, migrate data, and decommission the old instance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Pro tip&lt;/strong&gt;: Compute Optimizer accounts for existing Reserved Instances and Savings Plans discounts in its calculations. Recommendations reflect your actual cost impact, not theoretical On-Demand savings.&lt;/p&gt;

&lt;p&gt;To compare pricing across instance types and find cost-effective alternatives, use our &lt;a href="https://cloudburn.io/tools/amazon-ec2-pricing-calculator" rel="noopener noreferrer"&gt;EC2 Pricing Calculator&lt;/a&gt; which includes smart instance recommendations based on your vCPU and memory requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Savings Plans and Reserved Instances
&lt;/h3&gt;

&lt;p&gt;Commitment-based pricing offers the largest discounts but requires understanding your workload patterns first. Here's how to choose:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://cloudburn.io/blog/amazon-ec2-pricing#savings-plans-up-to-72-off-with-commitment" rel="noopener noreferrer"&gt;Savings Plans&lt;/a&gt; offer up to 72% savings&lt;/strong&gt; through 1 or 3-year commitments:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan Type&lt;/th&gt;
&lt;th&gt;Max Discount&lt;/th&gt;
&lt;th&gt;Flexibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compute Savings Plans&lt;/td&gt;
&lt;td&gt;Up to 66%&lt;/td&gt;
&lt;td&gt;Any instance family, size, Region, OS, or tenancy (EC2, Fargate, Lambda)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EC2 Instance Savings Plans&lt;/td&gt;
&lt;td&gt;Up to 72%&lt;/td&gt;
&lt;td&gt;Specific instance family in a Region, any size/OS/tenancy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database Savings Plans&lt;/td&gt;
&lt;td&gt;Up to 35%&lt;/td&gt;
&lt;td&gt;RDS and Aurora across engine, instance family, size&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;My recommendation&lt;/strong&gt;: Start with Compute Savings Plans covering 60-70% of your steady-state On-Demand usage. This leaves room for optimization while capturing significant savings. Increase coverage as you gain confidence in your usage patterns.&lt;/p&gt;

&lt;p&gt;Perform pricing model analysis at the management account level using Cost Explorer recommendations to identify opportunities across all linked accounts. Savings Plans apply to usage based on highest discount percentage across accounts when purchased at the management account level.&lt;/p&gt;

&lt;h3&gt;
  
  
  S3 Storage Class Optimization
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/s3/storage-classes/intelligent-tiering/" rel="noopener noreferrer"&gt;S3 Intelligent-Tiering&lt;/a&gt; automatically optimizes storage costs for data with unknown or changing access patterns. It moves objects between access tiers based on actual access patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frequent Access tier&lt;/strong&gt;: Default, standard pricing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrequent Access tier&lt;/strong&gt; (not accessed 30 days): 40% savings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Archive Instant Access tier&lt;/strong&gt; (not accessed 90 days): 68% savings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional Archive Access and Deep Archive tiers&lt;/strong&gt;: Up to 95% savings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key advantage&lt;/strong&gt;: No retrieval charges for Intelligent-Tiering (except optional archive tiers). A small monthly monitoring fee ($0.0025 per 1,000 objects) is the only additional cost.&lt;/p&gt;

&lt;p&gt;For data you know will be accessed infrequently, use explicit storage classes with lifecycle policies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transition to Standard-IA after 30 days (minimum required)&lt;/li&gt;
&lt;li&gt;Transition to Glacier Instant Retrieval after 90 days&lt;/li&gt;
&lt;li&gt;Delete after 365 days if no longer needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use S3 Storage Class Analysis to identify access patterns before creating lifecycle policies. It generates reports showing object age and access frequency to guide data-driven decisions.&lt;/p&gt;

&lt;p&gt;To estimate costs across different storage classes and see free tier tracking, use our &lt;a href="https://cloudburn.io/tools/amazon-s3-pricing-calculator" rel="noopener noreferrer"&gt;S3 Pricing Calculator&lt;/a&gt; with cost optimization recommendations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lambda Function Optimization
&lt;/h3&gt;

&lt;p&gt;Lambda charges based on memory allocation and execution time. The key insight: Lambda allocates CPU proportionally to memory. A function with 128 MB gets minimal CPU, while 1,769 MB gets one full vCPU. Sometimes increasing memory actually reduces costs because faster execution offsets higher memory charges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimization strategies:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;a href="https://docs.aws.amazon.com/lambda/latest/operatorguide/profile-functions.html" rel="noopener noreferrer"&gt;AWS Lambda Power Tuning&lt;/a&gt; to find optimal memory configuration&lt;/li&gt;
&lt;li&gt;Enable ARM64/Graviton2 architecture for up to 34% better price-performance&lt;/li&gt;
&lt;li&gt;Enable SnapStart for Java functions to reduce cold starts&lt;/li&gt;
&lt;li&gt;Right-size timeout settings (don't set 15 minutes when 30 seconds is sufficient)&lt;/li&gt;
&lt;li&gt;Review logging levels and avoid excessive DEBUG logs in production&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Compute Optimizer provides Lambda memory recommendations based on historical performance metrics. Check recommendations before manually tuning.&lt;/p&gt;

&lt;p&gt;For detailed cost modeling including Compute Savings Plans and Provisioned Concurrency scenarios, use our &lt;a href="https://cloudburn.io/tools/aws-lambda-pricing-calculator" rel="noopener noreferrer"&gt;Lambda Pricing Calculator&lt;/a&gt; to estimate serverless costs across different configurations.&lt;/p&gt;

&lt;h3&gt;
  
  
  RDS and Aurora Database Optimization
&lt;/h3&gt;

&lt;p&gt;Database costs add up quickly. AWS Compute Optimizer now provides rightsizing recommendations for RDS MySQL, PostgreSQL, and Aurora (both MySQL and PostgreSQL compatible editions).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Idle database criteria&lt;/strong&gt; (14-day lookback):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No database connections&lt;/li&gt;
&lt;li&gt;Low CPU usage&lt;/li&gt;
&lt;li&gt;Low read/write activity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Options for idle databases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop database for up to 7 days (automatically restarts after 7 days)&lt;/li&gt;
&lt;li&gt;Create snapshot and delete instance&lt;/li&gt;
&lt;li&gt;Convert Aurora to Aurora Serverless v2 for automatic scaling to zero&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Storage optimization:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable storage autoscaling to prevent over-provisioning (scales when free space falls below 10%)&lt;/li&gt;
&lt;li&gt;Migrate gp2 to gp3 storage for cost savings&lt;/li&gt;
&lt;li&gt;Consider Database Savings Plans for predictable workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To compare database instance costs, storage types, and Reserved Instance savings, use our &lt;a href="https://cloudburn.io/tools/amazon-rds-pricing-calculator" rel="noopener noreferrer"&gt;RDS Pricing Calculator&lt;/a&gt; for MySQL, PostgreSQL, MariaDB, Oracle, and SQL Server or our &lt;a href="https://cloudburn.io/tools/amazon-aurora-pricing-calculator" rel="noopener noreferrer"&gt;Aurora Pricing Calculator&lt;/a&gt; for Aurora MySQL and PostgreSQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Transfer Cost Reduction
&lt;/h3&gt;

&lt;p&gt;Data transfer costs often surprise teams, especially when they're 15-30% of the monthly bill. The biggest lever: &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost_data_transfer_optimized_components.html" rel="noopener noreferrer"&gt;VPC Endpoints&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VPC Endpoints eliminate NAT Gateway charges for AWS service traffic:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gateway Endpoints (S3 and DynamoDB) are free&lt;/li&gt;
&lt;li&gt;Interface Endpoints cost $0.01/GB processed (still cheaper than NAT Gateway at $0.045/GB)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Additional strategies:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review and delete idle NAT Gateways (available state, not in route tables, no active connections)&lt;/li&gt;
&lt;li&gt;Use CloudFront CDN to cache content at edge locations, reducing origin data transfer&lt;/li&gt;
&lt;li&gt;Keep data transfer within the same Availability Zone when possible (free within AZ)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-best-practices" rel="noopener noreferrer"&gt;multi-account architectures&lt;/a&gt;, centralize VPC Endpoints in a shared services account and share them via PrivateLink to maximize efficiency across accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 3: Predictive Cost Engineering (Advanced)
&lt;/h2&gt;

&lt;p&gt;Level 2 optimizations work within your existing architecture. Level 3 goes deeper with architectural changes that deliver 35-50% additional savings but require more effort and testing. These typically take 90+ days to implement properly.&lt;/p&gt;

&lt;p&gt;Organizations enter Level 3 after capturing Level 1 and Level 2 wins. If you haven't optimized the basics, architectural changes won't deliver their full potential since you're optimizing on top of waste.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Graviton Migration
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/optimize-costs-microsoft-workloads/net-graviton.html" rel="noopener noreferrer"&gt;AWS Graviton processors&lt;/a&gt; deliver up to 40% better price-performance compared to x86-based instances. Graviton4 offers 30% better performance than Graviton3, which itself is 60% more energy efficient than comparable EC2 instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customer results are compelling&lt;/strong&gt;: 20-45% reduction in infrastructure costs across various workloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migration paths by workload type:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Containerized workloads&lt;/strong&gt;: Build multi-architecture images and deploy to Graviton-based Fargate or EKS. Most containers work without modification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda functions&lt;/strong&gt;: Change the architecture setting from x86_64 to arm64. Most functions work immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2 instances&lt;/strong&gt;: Test applications on Graviton instances in staging. Modern frameworks (Python, Node.js, Java, Go, .NET Core) typically run without changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Databases&lt;/strong&gt;: RDS and Aurora offer Graviton-based instance types. Start with read replicas and non-production databases for low-risk migration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Start with non-critical workloads&lt;/strong&gt;, validate performance, then expand to production. Cost Optimization Hub includes Graviton migration recommendations to help identify candidates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Spot Instance Strategy
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-best-practices.html" rel="noopener noreferrer"&gt;Spot Instances&lt;/a&gt; offer up to 90% savings compared to On-Demand prices by utilizing spare EC2 capacity. The tradeoff: Spot Instances can be interrupted with 2-minute warning when AWS needs capacity back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best practices for Spot success:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Be flexible&lt;/strong&gt;: Use multiple instance types and Availability Zones to increase capacity allocation probability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use attribute-based instance type selection&lt;/strong&gt;: Automatically identify instances matching specified attributes rather than hard-coding types&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement interruption handling&lt;/strong&gt;: Design applications to handle the 2-minute warning gracefully&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use EC2 Rebalance Recommendations&lt;/strong&gt;: Proactively replace at-risk Spot Instances before interruption&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leverage price-capacity-optimized allocation&lt;/strong&gt;: Automatically provision from most-available Spot pools with lowest price&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Spot Instance interruption frequency varies by pool: less than 5% to over 20% depending on instance type and Availability Zone. Check Spot Instance Advisor for interruption frequency data before selecting instance types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ideal Spot workloads&lt;/strong&gt;: Batch processing, CI/CD pipelines, data analysis, containerized microservices designed for horizontal scaling, and any fault-tolerant application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Account Consolidated Billing
&lt;/h3&gt;

&lt;p&gt;AWS Organizations &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-cost-savings" rel="noopener noreferrer"&gt;consolidated billing aggregates usage across accounts for volume discounts&lt;/a&gt; and shared reservations. For organizations with multiple accounts, this delivers significant savings without additional optimization effort.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Combined usage qualifies for volume discounts (S3, EC2, data transfer)&lt;/li&gt;
&lt;li&gt;Shared Savings Plans and Reserved Instance benefits across accounts&lt;/li&gt;
&lt;li&gt;No additional cost for consolidated billing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Discount sharing options:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Organization-wide sharing&lt;/strong&gt; (default): Management account benefits first, then shares with all member accounts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prioritized group sharing&lt;/strong&gt;: Benefits account owner first, then defined groups, then other accounts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restricted group sharing&lt;/strong&gt;: Exclusive sharing within defined groups only&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Purchase Savings Plans and Reserved Instances at the management account level for maximum flexibility across the organization. For detailed guidance on &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-best-practices" rel="noopener noreferrer"&gt;multi-account best practices&lt;/a&gt; including cost governance, see our dedicated guide.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced Monitoring and Forecasting
&lt;/h3&gt;

&lt;p&gt;Level 3 organizations move beyond reactive monitoring to predictive cost management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advanced capabilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Cost Explorer forecasting for 12-month projections to guide budget planning&lt;/li&gt;
&lt;li&gt;Set up custom CloudWatch dashboards combining cost metrics with operational metrics&lt;/li&gt;
&lt;li&gt;Implement cost-per-feature or cost-per-customer tracking&lt;/li&gt;
&lt;li&gt;Analyze Cost and Usage Reports for granular data&lt;/li&gt;
&lt;li&gt;Integrate cost data with business metrics to understand unit economics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cost Explorer retains 13 months of historical data, giving you enough baseline to identify seasonal patterns and forecast accurately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 4: Automated Cost Governance
&lt;/h2&gt;

&lt;p&gt;Individual optimizations don't scale. Level 4 implements governance frameworks that enforce cost controls automatically across your organization, preventing waste before it occurs. This typically takes 6-12 months to mature and delivers 50%+ sustained savings.&lt;/p&gt;

&lt;p&gt;This stage is essential for organizations with multiple teams, multiple accounts, or compliance requirements around cost management. Without automation, optimization becomes an endless manual task that teams eventually deprioritize.&lt;/p&gt;

&lt;h3&gt;
  
  
  IaC Cost Controls
&lt;/h3&gt;

&lt;p&gt;Infrastructure as Code provides the foundation for automated cost governance. When infrastructure is defined in code, you can implement cost controls before resources exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation strategies:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Terraform modules or CDK constructs with cost-optimized defaults (right-sized instance types, appropriate storage classes)&lt;/li&gt;
&lt;li&gt;Implement pre-deployment cost estimation with &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;CloudBurn&lt;/a&gt; to get automatic cost estimates in pull requests for Terraform and AWS CDK&lt;/li&gt;
&lt;li&gt;Enforce tagging requirements in IaC templates (resources without required tags fail deployment)&lt;/li&gt;
&lt;li&gt;Version control cost decisions alongside infrastructure&lt;/li&gt;
&lt;li&gt;Implement CI/CD gates that require approval for changes exceeding cost thresholds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://cloudburn.io/blog/aws-finops-shift-left" rel="noopener noreferrer"&gt;shift-left philosophy&lt;/a&gt; applies to costs just like security: catch problems early when they're cheap to fix, not in production when they're expensive to remediate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated Rightsizing
&lt;/h3&gt;

&lt;p&gt;Manual rightsizing reviews don't scale. Level 4 organizations automate the optimization recommendations from Compute Optimizer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automation opportunities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EBS volume type migrations (gp2 to gp3) via Compute Optimizer automation&lt;/li&gt;
&lt;li&gt;Lambda memory optimization recommendations applied automatically&lt;/li&gt;
&lt;li&gt;Scheduled scaling for predictable workloads (development environments that don't need 24/7)&lt;/li&gt;
&lt;li&gt;Tag-based automation rules (instances tagged "environment:development" automatically stop at 8 PM)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compute Optimizer refreshes recommendations daily. Set up automation to review new recommendations and apply low-risk changes automatically while escalating higher-risk changes for human review.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service Control Policies for Cost
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://towardsthecloud.com/blog/aws-scp-service-control-policies" rel="noopener noreferrer"&gt;Service Control Policies&lt;/a&gt; provide organization-wide guardrails that even account administrators can't bypass. For &lt;a href="https://towardsthecloud.com/blog/aws-organizations-best-practices" rel="noopener noreferrer"&gt;AWS Organizations configuration best practices&lt;/a&gt; including detailed SCP guidance, see our dedicated guide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common cost-focused SCPs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Region restrictions&lt;/strong&gt;: Deny launching resources in regions you don't use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instance type restrictions&lt;/strong&gt;: Limit non-production accounts to cost-effective instance families&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service restrictions&lt;/strong&gt;: Block expensive services in sandbox accounts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tagging enforcement&lt;/strong&gt;: Deny resource creation without required cost allocation tags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important limitation&lt;/strong&gt;: SCPs don't apply to the management account. Implement additional controls there via IAM policies or keep the management account limited to billing and organization management only.&lt;/p&gt;

&lt;p&gt;AWS Budgets automated actions provide another layer. When spending exceeds thresholds, Budgets can automatically apply IAM policies that restrict specific actions like launching new EC2 instances.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Pitfalls and What NOT to Optimize
&lt;/h2&gt;

&lt;p&gt;Most cost optimization content tells you what to do. This section covers what not to do, which matters equally. Over-optimization creates technical debt and organizational friction that costs more than the savings you capture.&lt;/p&gt;

&lt;p&gt;Understanding these trade-offs prevents the failure modes I've seen repeatedly across organizations that pursued savings too aggressively.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Cost vs Developer Experience Balance
&lt;/h3&gt;

&lt;p&gt;Not all infrastructure costs should be minimized. Some "waste" is actually investment in developer productivity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protect these areas from aggressive optimization:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Development environments&lt;/strong&gt;: Prioritize speed over cost. A developer waiting 10 minutes for an undersized instance to build costs more than the instance savings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD pipelines&lt;/strong&gt;: Pipeline availability matters more than instance cost. Failed builds block entire teams.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability tools&lt;/strong&gt;: Don't cut monitoring that prevents incidents. The cost of an outage exceeds years of CloudWatch spending.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Establish "safe optimization zones"&lt;/strong&gt; for your organization. Production infrastructure? Optimize carefully. Shared development tools? Leave headroom for productivity.&lt;/p&gt;

&lt;p&gt;Calculate cost per developer alongside infrastructure cost. If cutting $500/month in development environment costs adds 2 hours of friction per developer per week across 10 developers, you've lost money.&lt;/p&gt;

&lt;h3&gt;
  
  
  Over-Optimization Failure Modes
&lt;/h3&gt;

&lt;p&gt;I've seen these patterns repeatedly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spot interruptions causing production outages&lt;/strong&gt;: Teams deploy Spot for stateful services without proper interruption handling. The 90% discount becomes irrelevant when an outage costs $100K.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reserved Instance commitments for changing workloads&lt;/strong&gt;: Organizations commit to 3-year Reserved Instances right before a major architecture change. Now they're paying for capacity they can't use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggressive rightsizing causing performance degradation&lt;/strong&gt;: Rightsizing to the 95th percentile of utilization leaves no headroom for traffic spikes. Users experience latency during peak periods.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto-scaling configured too aggressively&lt;/strong&gt;: Scale-in policies that terminate instances too quickly cause oscillation. The constant scaling costs more than maintaining slightly higher baseline capacity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Removing redundancy for cost savings&lt;/strong&gt;: Single-AZ deployments save money until the AZ has an incident. Multi-AZ costs more but provides the resilience production workloads require.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Prioritize Speed Over Savings
&lt;/h3&gt;

&lt;p&gt;Cost optimization isn't always the right priority:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Startups in growth phase&lt;/strong&gt;: Time-to-market often matters more than infrastructure efficiency. Optimize once you've found product-market fit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production incidents&lt;/strong&gt;: Don't optimize during outages. Throw resources at the problem now, optimize later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New feature launches&lt;/strong&gt;: Stability before cost reduction. Launch, validate, then optimize.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When developer time costs more than savings&lt;/strong&gt;: If a week of engineering time saves $200/month, that's a 2-year payback period. Find better uses for engineering time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporary workloads&lt;/strong&gt;: Don't over-engineer short-term needs. A 3-month project doesn't need Savings Plans.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Measuring Success and ROI
&lt;/h2&gt;

&lt;p&gt;Tracking the right metrics ensures your optimization efforts deliver value. Total AWS spend isn't the right metric for growing organizations since costs should grow with the business. Focus instead on efficiency metrics that reveal whether costs grow slower than business outcomes.&lt;/p&gt;

&lt;p&gt;The metrics you track drive behavior. Choose metrics that encourage sustainable optimization rather than aggressive cost-cutting that creates technical debt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Metrics Beyond Dollar Savings
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Unit economics metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cost per transaction/request&lt;/li&gt;
&lt;li&gt;Cost per customer&lt;/li&gt;
&lt;li&gt;Cost per developer&lt;/li&gt;
&lt;li&gt;Cost per deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These metrics normalize for business growth. If costs grow 20% while transactions grow 40%, you're optimizing effectively even though absolute spend increased.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Efficiency metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Savings Plans/RI coverage percentage (target 70-80%)&lt;/li&gt;
&lt;li&gt;Savings Plans/RI utilization percentage (target 95%+)&lt;/li&gt;
&lt;li&gt;Waste ratio (idle and over-provisioned resources as percentage of total spend)&lt;/li&gt;
&lt;li&gt;Time to remediation (how quickly teams act on optimization recommendations)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Operational metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Number of idle resources over time (should trend downward)&lt;/li&gt;
&lt;li&gt;Tagging compliance percentage&lt;/li&gt;
&lt;li&gt;Budget alert frequency (fewer alerts = better forecasting)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quarterly Review Cadence
&lt;/h3&gt;

&lt;p&gt;Establish regular review cycles to maintain optimization momentum:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monthly:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review Cost Optimization Hub recommendations&lt;/li&gt;
&lt;li&gt;Check budget status and anomaly alerts&lt;/li&gt;
&lt;li&gt;Track unit economics trending&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Quarterly:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analyze Savings Plans and RI utilization&lt;/li&gt;
&lt;li&gt;Review commitment purchase recommendations&lt;/li&gt;
&lt;li&gt;Assess architecture optimization pipeline (Graviton, Spot candidates)&lt;/li&gt;
&lt;li&gt;Update forecasts based on business plans&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Annually:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review Savings Plans/RI terms approaching renewal&lt;/li&gt;
&lt;li&gt;Evaluate multi-year commitment strategies&lt;/li&gt;
&lt;li&gt;Align cost optimization priorities with business priorities&lt;/li&gt;
&lt;li&gt;Assess team ownership and accountability structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Integrate cost reviews into existing ceremonies (sprint planning, architecture reviews) rather than creating separate meetings. Cost optimization sustains when it's part of how teams already work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion and Next Steps
&lt;/h2&gt;

&lt;p&gt;Cost optimization is a journey organized around maturity levels, not a checklist you complete once. The framework I've presented gives you a roadmap: establish visibility (Level 1), eliminate waste and make strategic commitments (Level 2), implement architectural optimizations (Level 3), and automate governance (Level 4).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with your current maturity level. Don't jump to Graviton migration when you haven't cleaned up idle resources.&lt;/li&gt;
&lt;li&gt;Level 1 quick wins can deliver 10-20% savings in 30 days with minimal effort.&lt;/li&gt;
&lt;li&gt;Level 2 strategic optimizations add 20-35% but require understanding your workload patterns first.&lt;/li&gt;
&lt;li&gt;Balance cost reduction with developer experience and system reliability. Over-optimization creates technical debt.&lt;/li&gt;
&lt;li&gt;Automated governance (Level 4) is how you sustain savings without constant manual effort.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Your next action based on current stage:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Level 1&lt;/strong&gt;: Enable Cost Optimization Hub today. Set up your first budget alert. Delete one idle resource.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 2&lt;/strong&gt;: Review Compute Optimizer rightsizing recommendations. Calculate your Savings Plans coverage gap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 3&lt;/strong&gt;: Identify one workload to test on Graviton. Evaluate VPC Endpoints for your highest-volume AWS service calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 4&lt;/strong&gt;: Implement one cost-focused SCP. Add cost estimation to your CI/CD pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For organizations wanting deeper coverage of cost optimization principles and the full maturity model framework, see our comprehensive guide to &lt;a href="https://towardsthecloud.com/blog/aws-cost-optimization-best-practices" rel="noopener noreferrer"&gt;AWS cost optimization best practices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What's your current maturity level, and what's the biggest blocker to reaching the next stage? I'd like to hear about your cost optimization journey in the comments.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>aws</category>
      <category>costoptimization</category>
      <category>finops</category>
      <category>savingsplans</category>
    </item>
    <item>
      <title>The AWS Cost Spiral: Why Your Bill Keeps Growing (+ Fix)</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 15:21:36 +0000</pubDate>
      <link>https://forem.com/dannysteenman/the-aws-cost-spiral-why-your-bill-keeps-growing-fix-nb9</link>
      <guid>https://forem.com/dannysteenman/the-aws-cost-spiral-why-your-bill-keeps-growing-fix-nb9</guid>
      <description>&lt;p&gt;You open your AWS billing dashboard expecting a modest increase. Instead, you see a number that makes your stomach drop. Last month was $12,000. This month: $19,000. You have no idea why.&lt;/p&gt;

&lt;p&gt;If your AWS costs keep increasing, you're in the right place. Small inefficiencies compound as teams scale, and without visibility, costs climb silently until the bill arrives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This guide covers exactly why your AWS bill keeps growing, how to diagnose the causes in your account, a prioritized action plan to reduce spending, and how to prevent it from happening again.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As an AWS Partner who has helped organizations &lt;a href="https://towardsthecloud.com/blog/aws-cost-optimization-assessment" rel="noopener noreferrer"&gt;cut their cloud spend by 30-60%&lt;/a&gt;, I've seen every version of this story. Here's what actually works.&lt;/p&gt;

&lt;h2&gt;
  
  
  You Are Not Alone: The Reality of AWS Cost Shock
&lt;/h2&gt;

&lt;p&gt;Before diving into technical fixes, let's acknowledge something: discovering a spiraling AWS bill is stressful. If your AWS bill is too high and you don't understand why, you're not alone. It creates organizational tension, triggers blame dynamics, and forces reactive decisions. Understanding why this happens to even experienced teams helps you approach the problem with clarity instead of panic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why AWS Bills Surprise Even Experienced Teams
&lt;/h3&gt;

&lt;p&gt;"Why is my AWS bill so high?" is one of the most common questions teams ask. AWS's pay-as-you-go model means costs are inherently variable. A misconfigured Auto Scaling group, a forgotten long-running test environment, or an unexpected spike in data transfer can &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost_cloud_financial_management_cost_awareness.html" rel="noopener noreferrer"&gt;generate thousands of dollars in charges overnight&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The cloud's ease of provisioning also creates a "better safe than sorry" mentality. Traditional on-premises thinking, where capacity must be purchased upfront, &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/public-sector-cloud-transformation/budgeting-and-cost-optimization.html" rel="noopener noreferrer"&gt;carries directly into the cloud&lt;/a&gt;. Teams select oversized instances "just in case," and AWS's pay-per-use model makes every hour of that excess capacity a direct line item on the bill.&lt;/p&gt;

&lt;p&gt;External factors add pressure too. AWS periodically adjusts pricing across services, and these changes compound on top of internal inefficiencies. When your architecture isn't optimized, even a modest price adjustment amplifies the impact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Your Cost Increase Normal or an Emergency?
&lt;/h3&gt;

&lt;p&gt;Not every cost increase is a crisis. Here's a simple framework to assess your situation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;10-20% month-over-month increase&lt;/strong&gt; with corresponding business growth = normal scaling. Your costs are growing because your business is growing. Focus on optimizing efficiency, not panicking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;20-50% increase&lt;/strong&gt; without proportional business growth = investigate within the week. Something changed in your infrastructure, and you need to find it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;50%+ sudden increase&lt;/strong&gt; = drop everything and diagnose immediately. This likely indicates a misconfiguration, forgotten resource, or security event.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The critical question is: &lt;strong&gt;did your usage grow, or did your efficiency drop?&lt;/strong&gt; A growing startup doubling revenue should expect cost increases. A stable product with flat traffic should not. This distinction determines whether you need to optimize your existing setup or simply scale smarter.&lt;/p&gt;

&lt;p&gt;Now that you have a sense of the severity, let's examine the specific reasons AWS costs spiral, so you can identify which ones apply to your situation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Your AWS Bill Keeps Growing
&lt;/h2&gt;

&lt;p&gt;Most AWS cost increases trace back to six root causes. Understanding each one helps you diagnose your specific situation and prioritize fixes that deliver the biggest impact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Over-Provisioned Resources Burning Money
&lt;/h3&gt;

&lt;p&gt;This is the most common cost driver I see. Teams select larger EC2 instance types than needed, run instances 24/7 when workloads only require compute during business hours, and keep EBS volumes attached to stopped instances long after they're needed.&lt;/p&gt;

&lt;p&gt;The root cause is a disconnect between infrastructure teams and actual business requirements. That m5.2xlarge running your staging API at 8% CPU utilization? It doesn't need 8 vCPUs and 32 GB of memory. A t3.medium would handle the workload at a fraction of the cost.&lt;/p&gt;

&lt;p&gt;RDS databases are another common culprit. Production-grade instances running continuously even when applications see minimal off-peak traffic generate significant waste.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zombie Resources You Forgot About
&lt;/h3&gt;

&lt;p&gt;Zombie resources are assets provisioned for testing, proof-of-concepts, or temporary projects that were never decommissioned. The most common types include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unattached EBS volumes&lt;/strong&gt; that remain after EC2 instance termination (they cost the same as attached volumes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stopped EC2 instances&lt;/strong&gt; still incurring EBS storage charges&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unassociated Elastic IPs&lt;/strong&gt; charged hourly when not attached to running instances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idle RDS databases&lt;/strong&gt; with no connections and minimal CPU activity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NAT Gateways&lt;/strong&gt; sitting in available state with no active connections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Balancers&lt;/strong&gt; with no registered targets or active connections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/compute-optimizer/latest/ug/view-idle-recommendations.html" rel="noopener noreferrer"&gt;AWS Compute Optimizer identifies idle resources&lt;/a&gt; using specific thresholds: EC2 instances with peak CPU below 5% and network I/O less than 5MB/day over a 14-day period, EBS volumes with less than 1 read/write operation per day or unattached over a 32-day period. These aren't arbitrary numbers; they represent resources doing effectively nothing.&lt;/p&gt;

&lt;p&gt;The scale can be staggering. One organization discovered 2,800 zombie assets out of 130,000 total resources. That's a significant amount of wasted spend hiding in plain sight.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paying Full Price Without Commitment Discounts
&lt;/h3&gt;

&lt;p&gt;If you've been running steady-state workloads on On-Demand pricing for more than a few months, you're leaving serious money on the table:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compute Savings Plans&lt;/strong&gt;: Up to 66% savings, the most flexible option. Applies to EC2, Fargate, and Lambda across any instance family, size, OS, or region.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EC2 Instance Savings Plans&lt;/strong&gt;: Up to 72% savings, locked to a specific instance family in a chosen region.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reserved Instances&lt;/strong&gt;: Up to 72% for EC2 and up to 69% for RDS with 1 or 3-year terms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spot Instances&lt;/strong&gt;: Up to 90% discount for fault-tolerant, stateless workloads that can handle interruptions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/savingsplans/latest/userguide/sp-ris.html" rel="noopener noreferrer"&gt;Savings Plans are now the recommended approach over Reserved Instances&lt;/a&gt; due to their superior flexibility. They automatically apply to usage across regions and instance types without manual configuration.&lt;/p&gt;

&lt;p&gt;Many organizations avoid commitments because they fear lock-in or lack visibility into usage patterns. The result: paying full retail for resources they'll clearly need for the next 12 months.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hidden Data Transfer Charges
&lt;/h3&gt;

&lt;p&gt;Data transfer is often the source of AWS unexpected charges. While data coming into AWS is free, nearly everything else costs money. Here's the breakdown:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Transfer Type&lt;/th&gt;
&lt;th&gt;Cost per GB&lt;/th&gt;
&lt;th&gt;Common Scenario&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cross-AZ&lt;/td&gt;
&lt;td&gt;$0.01 (both directions)&lt;/td&gt;
&lt;td&gt;Multi-AZ deployments, load balancers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inter-Region&lt;/td&gt;
&lt;td&gt;$0.02&lt;/td&gt;
&lt;td&gt;Cross-region replication, disaster recovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internet Egress&lt;/td&gt;
&lt;td&gt;$0.05-$0.09&lt;/td&gt;
&lt;td&gt;API responses, file downloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NAT Gateway Processing&lt;/td&gt;
&lt;td&gt;$0.045 + hourly fee&lt;/td&gt;
&lt;td&gt;Private subnet internet access&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Common architectural patterns that drive unexpected data transfer costs include placing resources in different Availability Zones than their data sources, using NAT Gateways when &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost_data_transfer_optimized_components.html" rel="noopener noreferrer"&gt;VPC endpoints would eliminate the data processing charge entirely&lt;/a&gt;, and replicating large datasets across regions without lifecycle policies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storage That Grows Silently
&lt;/h3&gt;

&lt;p&gt;Storage costs creep up because data accumulates without anyone actively managing it. Three areas are particularly problematic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EBS snapshots&lt;/strong&gt; are incremental, but the first snapshot captures nearly the full volume. Organizations often retain snapshots indefinitely without retention policies, or maintain daily snapshots when weekly would suffice. Meanwhile, unattached EBS volumes orphaned after instance termination continue incurring charges identical to attached volumes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;S3 objects&lt;/strong&gt; in the Standard storage class cost more than they should when data is infrequently accessed. Without &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html" rel="noopener noreferrer"&gt;lifecycle policies&lt;/a&gt;, logs, archives, and old data remain in expensive tiers indefinitely. S3 Intelligent-Tiering can automatically move objects to cheaper tiers based on access patterns with no retrieval fees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RDS backup retention&lt;/strong&gt; defaults matter too. Setting retention to the maximum 35 days without considering actual recovery requirements doubles backup storage costs in multi-AZ deployments.&lt;/p&gt;

&lt;p&gt;The fix is straightforward: Amazon Data Lifecycle Manager automates EBS snapshot retention, S3 Lifecycle policies transition objects to cheaper tiers (Standard-IA after 30 days, Glacier after 90), and reviewing RDS backup settings ensures you're not retaining more than you need.&lt;/p&gt;

&lt;h3&gt;
  
  
  No Cost Visibility or Accountability
&lt;/h3&gt;

&lt;p&gt;This is often the root cause underneath every other issue. When you can't attribute spending to specific teams, projects, or applications, cost optimization becomes everyone's responsibility but nobody's priority.&lt;/p&gt;

&lt;p&gt;Common visibility gaps include untagged resources that prevent cost allocation, missing cost anomaly detection to catch unexpected spikes, and the absence of regular cost reviews.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Teams that can't see their costs can't manage them.&lt;/strong&gt; Visibility is the foundation that makes every other optimization possible.&lt;/p&gt;

&lt;p&gt;Now that you understand what drives costs up, let's walk through how to diagnose which of these issues are affecting your specific AWS account.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Diagnose Your AWS Cost Increase
&lt;/h2&gt;

&lt;p&gt;Knowing the common causes is step one. Identifying which ones apply to your account requires a structured diagnostic process. Here's the three-step approach I use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Check AWS Cost Explorer for Trends
&lt;/h3&gt;

&lt;p&gt;Open &lt;a href="https://docs.aws.amazon.com/cost-management/latest/userguide/ce-what-is.html" rel="noopener noreferrer"&gt;AWS Cost Explorer&lt;/a&gt; and view the last 3-6 months at monthly granularity. This immediately reveals when costs started increasing and whether the trend is gradual or sudden. For longer trend analysis, enable multi-year data access for up to 38 months of historical cost data.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.aws.amazon.com/cost-management/latest/userguide/ce-cost-comparison.html" rel="noopener noreferrer"&gt;Cost Comparison feature&lt;/a&gt; (released in 2025) is particularly useful here. It automatically detects significant cost variations between two months and identifies the underlying drivers, highlighting specific services, accounts, or regions where changes occurred.&lt;/p&gt;

&lt;p&gt;Then switch to daily granularity for the most recent month to pinpoint specific spike dates. A single-day spike often points to a misconfiguration. A gradual daily climb suggests accumulating resources or growing usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Identify the Top Cost Drivers
&lt;/h3&gt;

&lt;p&gt;Now group your costs by Service to find which services are driving the increase. EC2, RDS, S3, and data transfer are the usual suspects, but the specifics vary by account.&lt;/p&gt;

&lt;p&gt;If you're using AWS Organizations, group by Linked Account to identify which team or project is responsible. Then filter by Usage Type to distinguish between compute hours, storage gigabytes, data transfer, and API requests. Compare the current month to the previous month using the same filters to isolate exactly where the delta is.&lt;/p&gt;

&lt;p&gt;This step transforms a vague "costs went up" into a specific "EC2 compute hours in the staging account increased 40% because three new m5.xlarge instances were launched and never terminated."&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Run AWS Compute Optimizer and Trusted Advisor
&lt;/h3&gt;

&lt;p&gt;With the top cost drivers identified, run the tools that provide specific recommendations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Compute Optimizer&lt;/strong&gt; analyzes EC2, EBS, Lambda, ECS on Fargate, RDS, Aurora, and NAT Gateways. It uses 14 days of CloudWatch metrics to recommend up to 3 alternative configurations with projected savings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Trusted Advisor&lt;/strong&gt; scans for specific waste: low-utilization EC2 instances, underutilized EBS volumes, &lt;a href="https://docs.aws.amazon.com/awssupport/latest/user/cost-optimization-checks.html" rel="noopener noreferrer"&gt;idle RDS instances&lt;/a&gt;, idle load balancers, and unassociated Elastic IPs. In 2025, it integrated 16 new checks from Cost Optimization Hub for improved accuracy. Note: full Trusted Advisor access requires Business Support or higher.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Cost Optimization Hub&lt;/strong&gt; consolidates recommendations into a single dashboard. Its &lt;a href="https://aws.amazon.com/about-aws/whats-new/2025/11/aws-cost-optimization-hub-cost-efficiency-metric-measure-track/" rel="noopener noreferrer"&gt;Cost Efficiency metric&lt;/a&gt; calculates the percentage of your spend that can be optimized, refreshed daily, at no additional cost.&lt;/p&gt;

&lt;p&gt;Now you know what's driving your costs. Let's start fixing it, beginning with the quick wins you can implement today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Wins to Reduce Your AWS Bill Today
&lt;/h2&gt;

&lt;p&gt;These optimizations deliver immediate results. Most can be implemented within a day and start saving money right away.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kill Zombie Resources Immediately
&lt;/h3&gt;

&lt;p&gt;Start with the easiest savings: delete resources that serve no purpose.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Delete unattached EBS volumes.&lt;/strong&gt; They cost the same as attached volumes for zero value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release unassociated Elastic IPs.&lt;/strong&gt; Every unattached Elastic IP incurs an hourly charge. (We published a &lt;a href="https://towardsthecloud.com/blog/amazon-ec2-delete-unused-elastic-ip-addresses" rel="noopener noreferrer"&gt;script to find and delete unused Elastic IPs across all regions&lt;/a&gt; that automates this.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminate or snapshot-and-delete idle EC2 instances.&lt;/strong&gt; If peak CPU is below 5% and network I/O is less than 5MB/day, it's not doing useful work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stop or delete idle RDS instances&lt;/strong&gt; with no active connections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remove unused NAT Gateways and Load Balancers&lt;/strong&gt; with no active connections or registered targets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use &lt;a href="https://docs.aws.amazon.com/compute-optimizer/latest/ug/view-idle-recommendations.html" rel="noopener noreferrer"&gt;AWS Compute Optimizer's idle resource recommendations&lt;/a&gt; to find all of these systematically. The automation rules feature (introduced in 2024) can run daily, weekly, or monthly cleanup with the ability to track events and reverse actions if needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schedule Non-Production Environments
&lt;/h3&gt;

&lt;p&gt;Development, staging, and test environments running 24/7 waste roughly 65% of their cost. Your team works 8-10 hours a day, 5 days a week. Those environments sit idle the rest of the time.&lt;/p&gt;

&lt;p&gt;AWS Instance Scheduler can automatically stop and start EC2 and RDS instances based on defined schedules. Configure your non-production environments to run 8am-6pm on weekdays, and you'll cut non-production compute costs by 65-75%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Switch to Savings Plans or Reserved Instances
&lt;/h3&gt;

&lt;p&gt;If you've been running steady-state workloads on On-Demand for 3+ months, this is your highest-impact commitment.&lt;/p&gt;

&lt;p&gt;Start with &lt;strong&gt;Compute Savings Plans&lt;/strong&gt; for maximum flexibility. They &lt;a href="https://docs.aws.amazon.com/savingsplans/latest/userguide/sp-ris.html" rel="noopener noreferrer"&gt;apply across EC2, Fargate, and Lambda&lt;/a&gt;, any instance family, any region. Payment options matter: All Upfront gets the highest discount, while No Upfront requires no capital but offers a lower discount. Check Cost Explorer's Savings Plans recommendations, which analyze your historical usage and suggest optimal commitment amounts.&lt;/p&gt;

&lt;p&gt;For databases, &lt;strong&gt;RDS Reserved Instances&lt;/strong&gt; save up to 69% and support instance size flexibility within the same family.&lt;/p&gt;

&lt;p&gt;Here's my recommendation: &lt;strong&gt;commit to covering 70-80% of your baseline usage.&lt;/strong&gt; This captures the majority of savings while keeping 20-30% On-Demand for flexibility.&lt;/p&gt;

&lt;p&gt;Quick wins stop the immediate bleeding. But for lasting savings, you need to systematically optimize how your infrastructure runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Systematic Optimization for Long-Term Savings
&lt;/h2&gt;

&lt;p&gt;These strategies require more planning but deliver sustained cost reductions that compound over time. If you're looking for a comprehensive implementation plan, our &lt;a href="https://towardsthecloud.com/blog/aws-cost-optimization-checklist" rel="noopener noreferrer"&gt;AWS cost optimization checklist&lt;/a&gt; provides a structured, maturity-based approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Right-Size Your Compute Resources
&lt;/h3&gt;

&lt;p&gt;Right-sizing isn't a one-time activity. It's an ongoing process you should perform at least monthly as workloads evolve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EC2 instances&lt;/strong&gt;: Analyze CPU, memory, network, and disk I/O over 14-30 days. Compute Optimizer recommends up to 3 alternatives with projected savings. Consider &lt;a href="https://aws.amazon.com/ec2/cost-and-capacity/" rel="noopener noreferrer"&gt;Graviton instances&lt;/a&gt; (ARM-based) for up to 40% better price-performance on compatible workloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RDS and Aurora databases&lt;/strong&gt;: &lt;a href="https://aws.amazon.com/blogs/database/how-to-optimize-amazon-rds-and-amazon-aurora-database-costs-performance-with-aws-compute-optimizer/" rel="noopener noreferrer"&gt;Compute Optimizer now provides database recommendations&lt;/a&gt; (expanded in 2024), including idle detection and Graviton migration suggestions. For variable workloads, Aurora Serverless v2 auto-scales per Aurora Capacity Unit hour instead of fixed instance pricing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lambda functions&lt;/strong&gt;: &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/configuration-memory.html" rel="noopener noreferrer"&gt;Memory allocation determines cost&lt;/a&gt; (memory x execution time). CPU scales proportionally with memory, so increasing memory can actually reduce cost for CPU-intensive functions by cutting execution time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement Storage Lifecycle Policies
&lt;/h3&gt;

&lt;p&gt;Storage costs compound month over month. Lifecycle policies automate the optimization so you don't have to think about it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;S3 Lifecycle policies&lt;/strong&gt; automatically &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-transition-general-considerations.html" rel="noopener noreferrer"&gt;transition objects to cheaper tiers&lt;/a&gt;: Standard to Standard-IA after 30 days, to Glacier Flexible Retrieval after 90 days, to Glacier Deep Archive for long-term retention. Transition costs are minimal at $0.01 per 1,000 requests. Alternatively, &lt;strong&gt;S3 Intelligent-Tiering&lt;/strong&gt; automatically moves objects between access tiers based on usage patterns with no retrieval fees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon Data Lifecycle Manager&lt;/strong&gt; automates creation, retention, and deletion of EBS snapshots and AMIs. Set a retention policy that matches your actual recovery requirements. Similarly, review &lt;strong&gt;RDS backup retention&lt;/strong&gt; settings: if they're set to the maximum 35 days but you only need 7 days of point-in-time recovery, you're paying for unnecessary backup storage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimize Data Transfer Architecture
&lt;/h3&gt;

&lt;p&gt;Data transfer optimizations require architectural thinking, but the payoff is ongoing.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Co-locate resources in the same Availability Zone&lt;/strong&gt; when possible to avoid the $0.01/GB cross-AZ charge. This matters most for high-throughput connections between compute and data services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replace NAT Gateways with VPC Gateway Endpoints&lt;/strong&gt; for S3 and DynamoDB access. Gateway Endpoints are &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost_data_transfer_modeling.html" rel="noopener noreferrer"&gt;free and eliminate the $0.045/GB processing charge&lt;/a&gt;. For other AWS services, Interface Endpoints cost less than NAT Gateway data processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Amazon CloudFront&lt;/strong&gt; for frequently accessed content to reduce internet egress costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review cross-region data replication&lt;/strong&gt; and ensure lifecycle policies exist on replicated data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use VPC Flow Logs and CloudWatch&lt;/strong&gt; to identify the largest data transfer sources before optimizing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Optimization gets your costs under control. But the real question is: how do you make sure costs don't spiral again?&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Prevent Future AWS Cost Spirals
&lt;/h2&gt;

&lt;p&gt;Moving from reactive firefighting to proactive cost governance is the difference between a one-time cleanup and sustainable cost management. &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-cost-savings" rel="noopener noreferrer"&gt;Multi-account architecture delivers 20-40% cost savings&lt;/a&gt; through consolidated billing, centralized Savings Plans, and automated governance. For a deeper dive into building a complete cost governance program, see our &lt;a href="https://towardsthecloud.com/blog/aws-cost-optimization-best-practices" rel="noopener noreferrer"&gt;AWS cost optimization best practices&lt;/a&gt; guide.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftowardsthecloud.com%2Fimages%2Fblog%2Faws-costs-keep-increasing%2Fcost-governance-architecture.excalidraw" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftowardsthecloud.com%2Fimages%2Fblog%2Faws-costs-keep-increasing%2Fcost-governance-architecture.excalidraw" alt="AWS cost governance architecture with Budgets, Cost Anomaly Detection, SNS alerts, and automated Budget Actions enforcement" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Up AWS Budgets and Cost Anomaly Detection
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost_govern_usage_controls.html" rel="noopener noreferrer"&gt;AWS Budgets&lt;/a&gt; is your first line of defense. Set multiple alert thresholds at 80%, 90%, and 100% of your monthly budget with notifications via Amazon SNS, email, or Slack through AWS Chatbot.&lt;/p&gt;

&lt;p&gt;But alerts alone aren't enough. &lt;strong&gt;Budget Actions&lt;/strong&gt; automatically execute responses when thresholds are exceeded, like applying IAM policies to restrict new resource creation. This is your automated safety net that catches cost overruns even when nobody's watching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Cost Anomaly Detection&lt;/strong&gt; uses machine learning to establish spending baselines and flags unusual patterns with confidence scores and root cause identification. Configure monitors for individual services, specific accounts, and cost allocation tags.&lt;/p&gt;

&lt;p&gt;Together, Budgets catches threshold breaches with automated enforcement, while Anomaly Detection catches unexpected spending patterns that represent unusual behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement Tagging for Cost Accountability
&lt;/h3&gt;

&lt;p&gt;Without tags, you can't attribute costs to teams, projects, or environments. And what can't be measured can't be managed.&lt;/p&gt;

&lt;p&gt;Start with these minimum recommended tags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Environment&lt;/strong&gt;: prod, dev, staging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CostCenter&lt;/strong&gt;: Engineering, Marketing, Finance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Project&lt;/strong&gt;: The project or product name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Owner&lt;/strong&gt;: Team email or identifier&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application&lt;/strong&gt;: The application or service name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Activate cost allocation tags in the &lt;a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html" rel="noopener noreferrer"&gt;AWS Billing and Cost Management console&lt;/a&gt; (management account only). Tags take up to 24 hours to appear in cost reports and only track costs from activation forward, not retroactively.&lt;/p&gt;

&lt;p&gt;Enforce tagging through &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/building-a-cost-allocation-strategy.html" rel="noopener noreferrer"&gt;AWS Organizations Tag Policies&lt;/a&gt; or Service Control Policies to prevent untagged resource creation. Tags are case-sensitive (&lt;code&gt;Environment&lt;/code&gt; and &lt;code&gt;environment&lt;/code&gt; are different tags), so define a consistent schema and enforce it with AWS Config Rules.&lt;/p&gt;

&lt;p&gt;For multi-account strategies, combining account-based cost allocation with resource-level tags provides both high-level visibility and granular attribution. Our &lt;a href="https://towardsthecloud.com/blog/aws-cloud-foundation" rel="noopener noreferrer"&gt;AWS cloud foundation guide&lt;/a&gt; covers how to design this with built-in cost governance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build a Cost-Aware Engineering Culture
&lt;/h3&gt;

&lt;p&gt;Tools and policies only work if people use them. The &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost-01.html" rel="noopener noreferrer"&gt;AWS Well-Architected Framework&lt;/a&gt; recommends establishing a dedicated cost optimization function and creating a partnership between finance and technology teams.&lt;/p&gt;

&lt;p&gt;Here's what that looks like in practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Establish regular cost reviews&lt;/strong&gt;: Weekly quick checks on anomalies, monthly deep dives into trends, quarterly strategic reviews of commitment coverage and architectural efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrate cost into architectural decisions&lt;/strong&gt;: Teams should understand cost implications before provisioning, not after the bill arrives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay current with AWS releases&lt;/strong&gt;: Newer instance generations and services often provide better price-performance. Graviton instances, for example, deliver up to 40% better price-performance for many workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Celebrate optimization wins&lt;/strong&gt;: Quantify savings in business terms, freed budget for innovation, improved margins, faster product delivery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track progress with the Cost Optimization Hub &lt;a href="https://aws.amazon.com/about-aws/whats-new/2025/11/aws-cost-optimization-hub-cost-efficiency-metric-measure-track/" rel="noopener noreferrer"&gt;Cost Efficiency metric&lt;/a&gt;&lt;/strong&gt;: This calculates the percentage of your cloud spend that can be optimized, refreshed daily, so you can measure whether the organization is getting more or less efficient over time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cost optimization is everyone's responsibility. For practical guidance on embedding this into your &lt;a href="https://towardsthecloud.com/blog/aws-account-best-practices" rel="noopener noreferrer"&gt;AWS account best practices including cost management fundamentals&lt;/a&gt;, start with foundational account hygiene and build from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take Control of Your AWS Costs
&lt;/h2&gt;

&lt;p&gt;AWS cost increases come from two sources: external price changes and internal inefficiencies. The path forward is clear:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with quick wins&lt;/strong&gt;: Delete idle resources, schedule non-production environments, and commit to Savings Plans for steady-state workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build for the long term&lt;/strong&gt;: Right-size continuously, implement lifecycle policies, and optimize data transfer architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prevent recurrence&lt;/strong&gt;: Set up Budgets with automated actions, enable Cost Anomaly Detection, enforce tagging, and build a cost-aware engineering culture.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Your next step&lt;/strong&gt;: Open AWS Cost Explorer right now and run a month-over-month comparison using the Cost Comparison feature. In 5 minutes, you'll know exactly where your money is going.&lt;/p&gt;

&lt;p&gt;You're not alone in dealing with AWS cost shock. With the right approach, it's a solvable problem, and the savings are often much larger than expected.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>aws</category>
      <category>costoptimization</category>
      <category>finops</category>
      <category>savingsplans</category>
    </item>
    <item>
      <title>Outgrowing Your Single AWS Account? The Migration Roadmap</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 15:21:09 +0000</pubDate>
      <link>https://forem.com/dannysteenman/outgrowing-your-single-aws-account-the-migration-roadmap-2n82</link>
      <guid>https://forem.com/dannysteenman/outgrowing-your-single-aws-account-the-migration-roadmap-2n82</guid>
      <description>&lt;p&gt;Your single AWS account started simple. One team, a few workloads, everything manageable. But now you have production and development colliding, IAM policies that look like spaghetti, and a nagging feeling that one misconfiguration could take everything down.&lt;/p&gt;

&lt;p&gt;If that sounds familiar, you're not alone. The AWS single account to multi-account migration is the most common architectural shift I see organizations make once they outgrow their initial setup. AWS itself identifies account-level workload separation as a &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_multi_accounts.html" rel="noopener noreferrer"&gt;foundational security best practice (SEC01-BP01)&lt;/a&gt;, and for good reason.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This guide will help you determine if you've outgrown your single account, understand what multi-account architecture looks like, follow a phased migration roadmap, and avoid the most common pitfalls that derail transitions.&lt;/strong&gt; Unlike AWS documentation that assumes you've already decided to migrate, I'll start at the beginning: do you actually need to make this move?&lt;/p&gt;

&lt;h2&gt;
  
  
  Signs You Have Outgrown Your Single AWS Account
&lt;/h2&gt;

&lt;p&gt;Before committing to a migration, you need an honest assessment. Not every organization needs multi-account architecture today, but most will eventually. Here's how to tell if you've reached that point.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 5 Warning Signs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Security incidents have no containment boundaries.&lt;/strong&gt; In a single-account environment, there are no hard security boundaries between workloads. A misconfiguration or breach in one application can impact everything else in the account. If your production database shares an account with your development sandbox, a compromised dev credential can potentially reach production data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Cost allocation is guesswork.&lt;/strong&gt; You can't tell your CEO which team, project, or environment is responsible for that cost spike last month. Tracking costs within a single account requires disciplined resource-level tagging across every resource, and few organizations maintain that consistently. Account-level cost separation is far simpler.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Compliance requirements are creating audit scope creep.&lt;/strong&gt; Regulated data (PCI-DSS, HIPAA, SOC 2) sharing an account with general workloads means your entire account falls within audit scope. &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/organizing-your-aws-environment/benefits-of-using-multiple-aws-accounts.html" rel="noopener noreferrer"&gt;Sensitive data security requires limiting access to dedicated accounts&lt;/a&gt;, reducing the number of people and processes that can interact with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Service quotas are causing cross-workload contention.&lt;/strong&gt; Your dev team's load test consumed the API rate limit your production application depends on. AWS Service Quotas and API rate limits apply at the account level. When unrelated workloads share the same account, they compete for the same quota pool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. IAM complexity has become unmanageable.&lt;/strong&gt; Trying to separate teams within a single account leads to increasingly complex IAM policies that are hard to audit and easy to misconfigure. You end up with contractors and vendors who have broader access than necessary because everything lives in one boundary.&lt;/p&gt;

&lt;p&gt;Here's a quick self-assessment. Do you recognize any of these?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accidental production data deletion due to shared environments&lt;/li&gt;
&lt;li&gt;Development activities impacting production workloads&lt;/li&gt;
&lt;li&gt;Inability to differentiate costs between production and development&lt;/li&gt;
&lt;li&gt;Contractors or vendors with broader access than necessary&lt;/li&gt;
&lt;li&gt;Complex IAM policies attempting to separate teams within a single boundary&lt;/li&gt;
&lt;li&gt;Service quota exhaustion affecting unrelated workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If you checked three or more, it's time to plan your migration.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  When Multi-Account Might Not Be Necessary Yet
&lt;/h3&gt;

&lt;p&gt;I want to be honest here: multi-account isn't always the answer right now. If you're a very small team (1-3 engineers), running a single workload, have no compliance requirements, and your monthly AWS spend is modest, a single account with good tagging discipline and strong IAM practices can work fine.&lt;/p&gt;

&lt;p&gt;The key word is "yet." Most organizations hit the warning signs above within 12-18 months of serious AWS usage. So even if you're not ready today, bookmark this guide. You'll need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Multi-Account Architecture Matters
&lt;/h2&gt;

&lt;p&gt;Understanding the benefits isn't just academic. You'll need these to justify the migration effort to stakeholders and to stay motivated when the work gets complex. Every benefit here directly addresses the pain points from the previous section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security and Blast Radius Containment
&lt;/h3&gt;

&lt;p&gt;AWS accounts act as hard boundaries for identity and access management. Access between accounts must be explicitly granted, unlike IAM policies within a single account where misconfiguration can inadvertently expose resources.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_multi_accounts.html" rel="noopener noreferrer"&gt;AWS Well-Architected Security Pillar (SEC01-BP01)&lt;/a&gt; rates account-level workload separation as a &lt;strong&gt;high-risk item if not implemented&lt;/strong&gt;. Isolation of workloads in separate accounts limits the scope of impact from adverse events, preventing problems from spreading across your entire infrastructure.&lt;/p&gt;

&lt;p&gt;In practical terms: if a production database is compromised in a multi-account setup, only that account's resources are exposed. Your other environments, logging infrastructure, and security tooling remain untouched.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost Visibility and Accountability
&lt;/h3&gt;

&lt;p&gt;Costs are naturally tracked at the account level through consolidated billing. You get a single bill covering all member accounts at no additional cost, while maintaining individual account visibility.&lt;/p&gt;

&lt;p&gt;Here's a detail that makes cost management significantly easier: &lt;a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/account-tags-cost-allocation.html" rel="noopener noreferrer"&gt;account tags applied at the account level in AWS Organizations&lt;/a&gt; automatically apply to all metered usage within tagged accounts. This eliminates the need for resource-level tagging for organizational cost allocation. Combined usage also counts toward volume discounts and Savings Plans across all accounts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compliance and Regulatory Boundaries
&lt;/h3&gt;

&lt;p&gt;Dedicated accounts for regulated data create clear audit scope, data sovereignty, and regulatory control boundaries. Instead of your entire account falling within PCI-DSS or HIPAA scope, only the specific accounts handling regulated data are in scope. That's a significant reduction in audit effort and exposure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Operational Independence and Innovation
&lt;/h3&gt;

&lt;p&gt;Service quotas and API rate limits distribute across accounts, eliminating the noisy-neighbor problems that plague single-account setups. Sandbox accounts can give developers wide-ranging access for experimentation without any risk to production. Different environments get security postures that match their needs: strict controls for production, permissive policies for development.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Single Account&lt;/th&gt;
&lt;th&gt;Multi-Account&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;Soft IAM boundaries, shared blast radius&lt;/td&gt;
&lt;td&gt;Hard account boundaries, isolated blast radius&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost tracking&lt;/td&gt;
&lt;td&gt;Requires resource-level tagging discipline&lt;/td&gt;
&lt;td&gt;Automatic account-level tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compliance&lt;/td&gt;
&lt;td&gt;Entire account in audit scope&lt;/td&gt;
&lt;td&gt;Only relevant accounts in scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service quotas&lt;/td&gt;
&lt;td&gt;Shared across all workloads&lt;/td&gt;
&lt;td&gt;Distributed per account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Innovation&lt;/td&gt;
&lt;td&gt;Risk of impacting production&lt;/td&gt;
&lt;td&gt;Isolated sandbox environments&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now that you understand why multi-account matters, let's look at what the target architecture actually involves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a Multi-Account Architecture Looks Like
&lt;/h2&gt;

&lt;p&gt;Before you can migrate, you need a clear picture of where you're headed. The target state involves three layers: the organizational hierarchy (AWS Organizations), the automated setup mechanism (&lt;a href="https://towardsthecloud.com/blog/aws-landing-zone" rel="noopener noreferrer"&gt;AWS Control Tower landing zone&lt;/a&gt;), and shared infrastructure services that connect everything together.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Organizations and Control Tower
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://towardsthecloud.com/blog/aws-organizations" rel="noopener noreferrer"&gt;AWS Organizations&lt;/a&gt; is the management layer that groups accounts into organizational units (OUs), applies policies centrally, and enables consolidated billing. The management account sits at the top. It pays all charges, manages the organization, and should never host workloads. &lt;strong&gt;Use a new dedicated account as your management account, not your existing workload account.&lt;/strong&gt; This is a critical decision I'll revisit in the pitfalls section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html" rel="noopener noreferrer"&gt;AWS Control Tower&lt;/a&gt; automates the landing zone setup in less than one hour. It creates a Security OU with Log Archive and Audit accounts, deploys baseline controls, and provisions Account Factory for standardized account creation. Controls come in three types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Preventive controls&lt;/strong&gt; (SCPs) block actions before they happen&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detective controls&lt;/strong&gt; (Config rules) identify non-compliant resources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proactive controls&lt;/strong&gt; (CloudFormation hooks) scan resources before deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For teams wanting more flexibility than Control Tower provides, &lt;a href="https://towardsthecloud.com/blog/aws-control-tower-alternatives" rel="noopener noreferrer"&gt;Control Tower alternatives&lt;/a&gt; like IaC-based landing zone options exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Organizational Unit (OU) Structure
&lt;/h3&gt;

&lt;p&gt;OU design follows a set of principles: organize by function (not org chart), apply controls to OUs (not individual accounts), keep the structure flat, and start small. Here's the recommended starting structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Root
├── Security OU
│   ├── Log Archive (account)
│   └── Audit (account)
├── Infrastructure OU
│   └── Networking (account) ─ Transit Gateway, DNS
├── Workloads OU
│   ├── Prod OU
│   │   ├── App1-Prod (account)
│   │   └── App2-Prod (account)
│   └── NonProd OU
│       ├── App1-Dev (account)
│       └── App2-Staging (account)
├── Sandbox OU
│   └── Developer sandboxes (accounts)
└── Transitional OU
    └── Migration staging (account)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;strong&gt;Transitional OU&lt;/strong&gt; specifically for migration staging. Accounts live here temporarily during migration before moving to their final OU. This lets you test &lt;a href="https://towardsthecloud.com/blog/aws-scp-service-control-policies" rel="noopener noreferrer"&gt;Service Control Policies&lt;/a&gt; against migrated workloads without affecting other accounts.&lt;/p&gt;

&lt;p&gt;OUs can nest up to 5 levels deep, but resist the urge to go deep. A flat structure is easier to understand, maintain, and troubleshoot. The default account limit is 10 (easily increased to thousands), with a maximum of 5 SCPs per OU and a 5,120-character limit per SCP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shared Services: Networking, Identity, and Logging
&lt;/h3&gt;

&lt;p&gt;Three shared service areas form the backbone of multi-account operations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Networking.&lt;/strong&gt; AWS Transit Gateway deployed in a centralized networking account acts as the hub for all cross-account connectivity. You share it with member accounts using AWS Resource Access Manager (RAM). Use AWS IPAM (IP Address Manager) to prevent CIDR overlaps across all VPCs from day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity.&lt;/strong&gt; AWS IAM Identity Center (formerly AWS SSO) provides single sign-on across all accounts. It integrates with your existing identity provider (Microsoft Entra ID, Okta, etc.) and replaces per-account IAM users with temporary, federated credentials. No more long-lived access keys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logging and Security.&lt;/strong&gt; CloudTrail organization trails log events for all accounts automatically and cannot be disabled by member accounts. Config aggregators collect compliance data organization-wide. GuardDuty and Security Hub, enabled from a delegated administrator account, provide centralized threat detection and security findings.&lt;/p&gt;

&lt;p&gt;For a deeper exploration of how these components fit together as a &lt;a href="https://towardsthecloud.com/blog/aws-cloud-foundation" rel="noopener noreferrer"&gt;cloud foundation&lt;/a&gt;, I've written a dedicated guide.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftowardsthecloud.com%2Fimages%2Fblog%2Faws-single-to-multi-account-migration%2Fmulti-account-architecture.excalidraw" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftowardsthecloud.com%2Fimages%2Fblog%2Faws-single-to-multi-account-migration%2Fmulti-account-architecture.excalidraw" alt="AWS multi-account architecture diagram showing OU structure with Security, Infrastructure, and Workloads organizational units connected via Transit Gateway" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where you're headed. Now let's walk through the phased roadmap to get there without disrupting your existing workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 5-Phase Migration Roadmap
&lt;/h2&gt;

&lt;p&gt;A phased approach is the single most important decision in this entire process. It minimizes risk, builds team confidence through early wins, and keeps your existing workloads running throughout. Here's the roadmap I recommend based on the &lt;a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/transitioning-to-multiple-aws-accounts/welcome.html" rel="noopener noreferrer"&gt;AWS Prescriptive Guidance for transitioning to multiple accounts&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Assess and Plan
&lt;/h3&gt;

&lt;p&gt;This phase is about building the map before starting the journey. Skip it and you'll break things during migration that you didn't know were connected.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inventory all resources&lt;/strong&gt;: Document every workload, application, and service in your account&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Map dependencies&lt;/strong&gt;: Identify data flows, integration points, and inter-service connections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Catalog IAM&lt;/strong&gt;: List all users, roles, policies, and permissions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define target architecture&lt;/strong&gt;: Design your OU structure and decide which workloads go in which accounts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan migration waves&lt;/strong&gt;: Group workloads by environment and dependency. Non-production goes first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assess risks&lt;/strong&gt;: Identify encrypted resources (KMS key sharing is complex), downtime tolerance, and critical dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 2: Establish the Foundation
&lt;/h3&gt;

&lt;p&gt;This is the most important phase. Get the foundation right and workload migration becomes straightforward. Get it wrong and you'll be rebuilding it later.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Set up AWS Organizations&lt;/strong&gt; with a new dedicated management account (not your existing workload account)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy Control Tower&lt;/strong&gt; landing zone in your home Region where the majority of workloads reside&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create the OU structure&lt;/strong&gt;: Security OU (auto-created), Infrastructure OU, Workloads OU (Prod/NonProd), Sandbox OU, Transitional OU&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Establish shared services&lt;/strong&gt;: Transit Gateway for networking, IAM Identity Center for identity, CloudTrail organization trails for logging, GuardDuty and Security Hub for security&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement baseline SCPs&lt;/strong&gt;: Region restriction, CloudTrail protection, Config protection, encryption enforcement&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test SCPs in a Policy Staging OU&lt;/strong&gt; before applying to production OUs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 3: Provision Target Accounts and Networks
&lt;/h3&gt;

&lt;p&gt;With the foundation in place, you create the accounts that will receive your workloads.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Account Factory&lt;/strong&gt; to provision accounts with organizational standards baked in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure VPCs&lt;/strong&gt; with non-overlapping CIDRs (use IPAM to prevent conflicts)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create Transit Gateway attachments&lt;/strong&gt; for cross-account connectivity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set up IAM Identity Center access&lt;/strong&gt; so teams can reach their new accounts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy account baselines&lt;/strong&gt; via CloudFormation StackSets (monitoring, patching, backup)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Phase 4: Migrate Workloads in Waves
&lt;/h3&gt;

&lt;p&gt;This is where the actual migration happens. The rehost ("lift and shift") strategy is most common for single-to-multi-account moves. Start with non-production workloads because they carry the lowest risk and the highest learning value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service-specific migration patterns:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;Migration Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EC2 instances&lt;/td&gt;
&lt;td&gt;Create AMI, share with destination account, launch in new account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 buckets&lt;/td&gt;
&lt;td&gt;S3 Replication (SRR/CRR) + Batch Replication for existing objects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RDS databases&lt;/td&gt;
&lt;td&gt;Create snapshot, share with destination, restore in new account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EBS volumes&lt;/td&gt;
&lt;td&gt;Create snapshot, share, copy to destination account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda functions&lt;/td&gt;
&lt;td&gt;Redeploy using IaC in destination account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Containers (ECS/EKS)&lt;/td&gt;
&lt;td&gt;Push images to new ECR, redeploy with updated task definitions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;For encrypted resources&lt;/strong&gt; (AMIs, snapshots, backups): share the customer-managed KMS key with the destination account and grant &lt;code&gt;kms:CreateGrant&lt;/code&gt;, &lt;code&gt;kms:Decrypt&lt;/code&gt;, and &lt;code&gt;kms:DescribeKey&lt;/code&gt; permissions. This is one of the most common stumbling blocks in migration, so test it with non-production resources first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep source account resources running&lt;/strong&gt; during a validation period. Update DNS records, redirect traffic, run functional and performance tests, then only decommission source resources after confirming everything works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 5: Optimize and Decommission
&lt;/h3&gt;

&lt;p&gt;Migration isn't done when the last workload moves. This phase turns a migrated environment into a well-operating one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Refine OU structure&lt;/strong&gt; based on operational experience&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy advanced controls&lt;/strong&gt; beyond the mandatory guardrails&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement Cost Categories&lt;/strong&gt; for chargeback and showback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Train teams&lt;/strong&gt; on multi-account operations, IAM Identity Center access, and account request processes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decommission the original single account&lt;/strong&gt;: move it to the Suspended OU or close it after verifying all workloads migrated successfully&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Following this phased approach minimizes risk and business disruption. But there are specific mistakes that can still derail your migration if you're not prepared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Pitfalls That Derail Multi-Account Migrations
&lt;/h2&gt;

&lt;p&gt;I've seen organizations make these mistakes repeatedly. Every pitfall here comes from real-world experience, and every one is avoidable with proper planning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Planning and Design Mistakes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Using your existing workload account as the management account.&lt;/strong&gt; The management account cannot have SCPs applied to it and should never host business workloads. Create a new, dedicated account as the management account and invite your existing account as a member. This is the single most impactful design decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mirroring your org chart in OUs.&lt;/strong&gt; OUs should represent security and operational boundaries, not reporting hierarchies. Organize by function (Security, Infrastructure, Workloads) and apply controls accordingly. Two teams with identical policy requirements belong in the same OU, even if they report to different VPs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overly complex OU structures.&lt;/strong&gt; You can nest OUs up to 5 levels deep, but that doesn't mean you should. Start with 2-3 levels and expand as needed. Deep hierarchies are difficult to troubleshoot when SCP evaluation produces unexpected results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Implementation Mistakes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overlapping CIDR blocks across VPCs.&lt;/strong&gt; You cannot route between VPCs with overlapping CIDRs, and fixing this after the fact requires re-creating VPCs. Use AWS IPAM for centralized CIDR allocation and plan non-overlapping address space from the start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not planning for encrypted resource migration.&lt;/strong&gt; Encrypted AMIs, snapshots, and backups require KMS key sharing between accounts. If you don't plan for this, your first production migration attempt will fail. Document all encrypted resources during Phase 1 and test cross-account KMS key sharing in non-production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attaching SCPs to production without testing.&lt;/strong&gt; SCPs can inadvertently block legitimate operations, causing production outages. Always test new or modified SCPs in a Policy Staging OU or against a small subset of accounts before broad deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Forgetting to share Transit Gateway via AWS RAM.&lt;/strong&gt; Member accounts cannot create Transit Gateway attachments if the Transit Gateway isn't shared. Share it immediately after creation to avoid blocking account provisioning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Operational and Governance Mistakes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;No rollback plan.&lt;/strong&gt; Keep source account resources running during the validation period. Maintain parallel operation until you're confident the migrated workloads function correctly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not training teams on multi-account operations.&lt;/strong&gt; Teams will struggle with cross-account access, get confused about which account to use, and default to workarounds that undermine your architecture. Document processes and provide hands-on training before completing migration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No SCP change management process.&lt;/strong&gt; Ad-hoc SCP changes cause unexpected permission denials that can look like service outages. Establish formal change management: test, review, approve, then deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hitting the default 10-account &lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_reference_limits.html" rel="noopener noreferrer"&gt;Organizations quota&lt;/a&gt;.&lt;/strong&gt; The default limit is 10 accounts (which includes deleted and closed accounts). Request a quota increase early in the migration process. It can be raised to thousands of accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Long Does Migration Take?
&lt;/h2&gt;

&lt;p&gt;This is the question every decision-maker asks, and no AWS documentation answers it. Here are realistic ranges based on the complexity of each phase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Timeline by Organization Size
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Organization Size&lt;/th&gt;
&lt;th&gt;Workloads&lt;/th&gt;
&lt;th&gt;Approximate Timeline&lt;/th&gt;
&lt;th&gt;Effort Estimate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small (1-3 teams)&lt;/td&gt;
&lt;td&gt;Fewer than 10&lt;/td&gt;
&lt;td&gt;4-8 weeks&lt;/td&gt;
&lt;td&gt;40-80 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium (3-10 teams)&lt;/td&gt;
&lt;td&gt;10-50&lt;/td&gt;
&lt;td&gt;8-16 weeks&lt;/td&gt;
&lt;td&gt;160-320 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large (10+ teams)&lt;/td&gt;
&lt;td&gt;50+&lt;/td&gt;
&lt;td&gt;3-6 months&lt;/td&gt;
&lt;td&gt;Dedicated migration team&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These estimates assume your team has some AWS experience and existing IaC maturity. Manual, ClickOps-managed infrastructure adds significant time because you'll need to recreate everything programmatically. Encrypted resources, complex network architectures, and multi-region deployments push timelines toward the higher end.&lt;/p&gt;

&lt;p&gt;The foundation (Phases 1-3) typically takes 40-60% of total effort. It's tempting to rush through it, but this is where shortcuts cost the most.&lt;/p&gt;

&lt;h3&gt;
  
  
  Team Roles Required
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud/Solutions architect&lt;/strong&gt;: OU design, SCP strategy, target architecture decisions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security engineer&lt;/strong&gt;: Controls, compliance requirements, identity management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DevOps/Platform engineer&lt;/strong&gt;: IaC, automation, Account Factory configuration, CI/CD pipelines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network engineer&lt;/strong&gt;: Transit Gateway, VPC design, CIDR planning, connectivity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In smaller organizations, one person often covers multiple roles. That's fine, but expect longer timelines accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps: Start Your Multi-Account Migration
&lt;/h2&gt;

&lt;p&gt;You've seen the warning signs, understood the benefits, mapped the target architecture, and learned the roadmap. Here's how to move forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  DIY Path
&lt;/h3&gt;

&lt;p&gt;Start with Phase 1: inventory your current workloads, dependencies, and IAM structure. This assessment is the prerequisite for every other step and costs nothing but time. Then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up AWS Organizations and deploy Control Tower&lt;/li&gt;
&lt;li&gt;Follow the &lt;a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/transitioning-to-multiple-aws-accounts/welcome.html" rel="noopener noreferrer"&gt;AWS Prescriptive Guidance for transitioning to multiple accounts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reference our &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-best-practices" rel="noopener noreferrer"&gt;multi-account best practices&lt;/a&gt; guide for operational guidance&lt;/li&gt;
&lt;li&gt;Review our &lt;a href="https://towardsthecloud.com/blog/aws-scp-service-control-policies" rel="noopener noreferrer"&gt;SCP implementation guide&lt;/a&gt; for governance details&lt;/li&gt;
&lt;li&gt;Explore &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-strategy" rel="noopener noreferrer"&gt;multi-account strategy patterns&lt;/a&gt; to find the right architecture for your growth stage&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Accelerated Path
&lt;/h3&gt;

&lt;p&gt;The foundation (Organizations, Control Tower, OU design, SCPs, networking, identity, logging, security baselines) is the hardest and most important part. It's also where mistakes are most expensive to fix later.&lt;/p&gt;

&lt;p&gt;If you want expert guidance on designing and implementing your multi-account architecture, our AWS Landing Zone service handles the entire foundation so your team can focus on what they do best: building and shipping product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Migrating from a single AWS account to a multi-account architecture is not optional for growing organizations. It's a foundational best practice that the &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/sec_securely_operate_multi_accounts.html" rel="noopener noreferrer"&gt;AWS Well-Architected Framework&lt;/a&gt; identifies as high-risk to skip. The AWS single account to multi-account migration doesn't have to be overwhelming if you approach it in phases.&lt;/p&gt;

&lt;p&gt;Here's what to remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recognize the warning signs&lt;/strong&gt;: security gaps, cost allocation struggles, service quota contention, and IAM complexity are your signals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-account is foundational&lt;/strong&gt;: it's SEC01-BP01, not an optional optimization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Follow the 5-phase roadmap&lt;/strong&gt;: assess, foundation, accounts, migrate, optimize. Each phase builds on the previous&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan for common pitfalls&lt;/strong&gt;: CIDR overlaps, encrypted resources, SCP testing, and team training&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The foundation is everything&lt;/strong&gt;: get Organizations, Control Tower, networking, and identity right, and workload migration becomes the straightforward part&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with an inventory of your current workloads, dependencies, and IAM structure. That assessment is Phase 1, and it's the prerequisite for everything that follows.&lt;/p&gt;

&lt;p&gt;Have questions about planning your migration? Drop them in the comments below, I'm happy to help.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>multiaccount</category>
      <category>awsorganizations</category>
      <category>awscontroltower</category>
      <category>landingzone</category>
    </item>
    <item>
      <title>AWS SOC 2 Compliance: What Auditors Actually Look For</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 15:21:06 +0000</pubDate>
      <link>https://forem.com/dannysteenman/aws-soc-2-compliance-what-auditors-actually-look-for-ghh</link>
      <guid>https://forem.com/dannysteenman/aws-soc-2-compliance-what-auditors-actually-look-for-ghh</guid>
      <description>&lt;p&gt;SOC 2 auditors will ask about your AWS controls. Most teams scramble because they don't know what auditors actually test, or what evidence satisfies their requirements.&lt;/p&gt;

&lt;p&gt;Here's the uncomfortable truth about AWS SOC 2 compliance: using AWS does NOT automatically make you compliant. AWS being SOC 2 compliant means their infrastructure is compliant, not your applications running on it. Your auditor will want to see YOUR controls, using AWS SOC reports only as evidence of infrastructure compliance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This guide shows you exactly what to prepare.&lt;/strong&gt; By the end, you'll know which controls are your responsibility versus AWS's, what evidence auditors expect for each Trust Service Criteria, common failure patterns to avoid, and a 90-day plan to get audit-ready.&lt;/p&gt;

&lt;p&gt;With 185 AWS services now in scope for SOC 2 (as of the Fall 2025 reports), the toolkit is comprehensive. The challenge isn't capability. It's knowing where to focus. Let's start with what auditors actually care about.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SOC 2 Auditors Expect from Your AWS Environment
&lt;/h2&gt;

&lt;p&gt;SOC 2 auditors evaluate controls across five Trust Service Criteria, with Security being mandatory for all engagements. They want evidence, not promises. Documentation and logs that prove compliance matter far more than verbal assurances about your security posture.&lt;/p&gt;

&lt;p&gt;AWS publishes their own SOC 2 reports quarterly, covering 185 services as of the &lt;a href="https://aws.amazon.com/blogs/security/fall-2025-soc-1-2-and-3-reports-are-now-available-with-185-services-in-scope/" rel="noopener noreferrer"&gt;Fall 2025 report&lt;/a&gt;. Your job is implementing Complementary User Entity Controls (CUECs) that AWS doesn't cover. These are the specific controls you must implement to complement AWS's infrastructure controls.&lt;/p&gt;

&lt;p&gt;Understanding this division is the first step. Let's clarify the most common misconception before diving into the details.&lt;/p&gt;

&lt;h3&gt;
  
  
  The #1 Misconception: AWS Compliance vs. Your Compliance
&lt;/h3&gt;

&lt;p&gt;The shared responsibility model determines everything. AWS secures "of" the cloud (physical infrastructure, hypervisor, networking). You secure "in" the cloud (IAM, data encryption, application configuration, firewall rules).&lt;/p&gt;

&lt;p&gt;When your auditor asks about data encryption, they're asking about YOUR KMS key policies, YOUR S3 bucket configurations, YOUR encryption choices. AWS's infrastructure encryption is documented in their SOC reports, but that's a foundation you build on, not a substitute for your own controls.&lt;/p&gt;

&lt;p&gt;This distinction matters because many teams assume "we're on AWS, so we're compliant." That assumption leads to audit failures.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Access AWS SOC Reports via AWS Artifact
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/artifact/latest/ug/what-is-aws-artifact.html" rel="noopener noreferrer"&gt;AWS Artifact&lt;/a&gt; is the self-service portal for accessing compliance reports at no cost. Your auditor will expect you to have reviewed these reports to understand which controls AWS handles.&lt;/p&gt;

&lt;p&gt;To access AWS SOC reports:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to AWS Artifact in the console (available in US East N. Virginia and GovCloud US-West)&lt;/li&gt;
&lt;li&gt;Accept the NDA if you haven't already&lt;/li&gt;
&lt;li&gt;Download the relevant SOC 2 report for your audit period&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Required IAM permissions:&lt;/strong&gt; Your IAM user or role needs &lt;code&gt;artifact:ListReportVersions&lt;/code&gt; permission. The &lt;code&gt;AWSArtifactReportsReadOnlyAccess&lt;/code&gt; managed policy includes this.&lt;/p&gt;

&lt;p&gt;As of December 2025, AWS Artifact now provides access to previous versions of compliance reports, helpful when auditors need historical evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Shared Responsibility Model for SOC 2
&lt;/h2&gt;

&lt;p&gt;Understanding which SOC 2 controls are AWS's responsibility versus yours is critical. Misunderstanding this split leads to gaps that auditors will find.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://aws.amazon.com/blogs/security/new-whitepaper-available-aicpa-soc-2-compliance-guide-on-aws/" rel="noopener noreferrer"&gt;AICPA SOC 2 Compliance Guide on AWS whitepaper&lt;/a&gt; (released July 2025) provides official guidance on this mapping. I recommend downloading it as a reference alongside this guide.&lt;/p&gt;

&lt;h3&gt;
  
  
  What AWS Handles (Security of the Cloud)
&lt;/h3&gt;

&lt;p&gt;AWS manages and secures the infrastructure from the host operating system and virtualization layer down to physical security. This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Physical and environmental controls&lt;/strong&gt; of data centers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardware, software, networking, and facilities&lt;/strong&gt; that run AWS services&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute, storage, database, and networking&lt;/strong&gt; infrastructure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS-managed security controls&lt;/strong&gt; documented in their SOC reports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your auditor will reference AWS SOC reports as evidence for these controls. You don't need to demonstrate these, just show you're aware of and relying on them appropriately.&lt;/p&gt;

&lt;h3&gt;
  
  
  What You Must Implement (Security in the Cloud)
&lt;/h3&gt;

&lt;p&gt;You're responsible for everything built on top of AWS infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Guest operating system&lt;/strong&gt; (including updates and security patches)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application software and utilities&lt;/strong&gt; you install&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration of AWS-provided security groups&lt;/strong&gt; (firewall rules)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IAM policies and access controls&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data encryption&lt;/strong&gt; (at rest and in transit choices)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network traffic protection&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are where auditors focus their attention. Every control discussed in this guide falls into your responsibility domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complementary User Entity Controls (CUECs)
&lt;/h3&gt;

&lt;p&gt;CUECs are the specific controls you implement to complement AWS's controls. The AICPA whitepaper provides detailed CUEC guidance mapped to each Trust Service Criteria.&lt;/p&gt;

&lt;p&gt;Your auditor will specifically evaluate CUEC implementation. They're looking for evidence that you understood which controls AWS provides and consciously designed your controls to complement them, not duplicate or miss gaps.&lt;/p&gt;

&lt;h2&gt;
  
  
  SOC 2 Trust Service Criteria and AWS Mapping
&lt;/h2&gt;

&lt;p&gt;The SOC 2 framework consists of five Trust Service Categories. Security (Common Criteria CC 1-9) is mandatory for all engagements. The other four categories are optional based on your business needs and customer commitments.&lt;/p&gt;

&lt;p&gt;Understanding how each category maps to AWS services helps you plan both implementation and evidence collection.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trust Service Criteria&lt;/th&gt;
&lt;th&gt;AWS Services&lt;/th&gt;
&lt;th&gt;Evidence Types&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Security&lt;/strong&gt; (Required)&lt;/td&gt;
&lt;td&gt;IAM, CloudTrail, Config, Security Hub, GuardDuty&lt;/td&gt;
&lt;td&gt;Access policies, audit logs, compliance reports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Availability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-AZ, Auto Scaling, Route 53, CloudWatch&lt;/td&gt;
&lt;td&gt;Uptime reports, incident logs, backup verification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Processing Integrity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Step Functions, EventBridge, CloudWatch Logs&lt;/td&gt;
&lt;td&gt;Transaction logs, reconciliation reports, validation evidence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Confidentiality&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;KMS, S3 encryption, RDS encryption, Secrets Manager&lt;/td&gt;
&lt;td&gt;Key policies, encryption configs, access logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Privacy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Macie, S3 lifecycle, Data classification&lt;/td&gt;
&lt;td&gt;Data inventory, retention policies, consent records&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Security (Common Criteria)
&lt;/h3&gt;

&lt;p&gt;Security is mandatory for all SOC 2 engagements. It covers access control, system operations, change management, and risk mitigation. These are the controls auditors spend the most time examining.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IAM policies demonstrating least privilege&lt;/li&gt;
&lt;li&gt;CloudTrail logs showing all API activity&lt;/li&gt;
&lt;li&gt;Evidence of regular access reviews&lt;/li&gt;
&lt;li&gt;MFA enforcement for privileged accounts&lt;/li&gt;
&lt;li&gt;Change management procedures with approval workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Availability
&lt;/h3&gt;

&lt;p&gt;If you've committed to uptime SLAs with customers, you'll include Availability criteria. This covers system accessibility for operation and use as committed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-AZ deployment evidence&lt;/li&gt;
&lt;li&gt;Auto Scaling configurations&lt;/li&gt;
&lt;li&gt;CloudWatch monitoring and alerting&lt;/li&gt;
&lt;li&gt;Incident response documentation&lt;/li&gt;
&lt;li&gt;Backup and recovery test results&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Processing Integrity (The Gap AWS Doesn't Cover)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This is critical:&lt;/strong&gt; AWS explicitly does NOT include Processing Integrity in their SOC 2 scope. You are fully responsible for proving that system processing is complete, valid, accurate, and timely.&lt;/p&gt;

&lt;p&gt;No AWS service automatically provides Processing Integrity compliance. You must design and document:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input validation procedures&lt;/li&gt;
&lt;li&gt;Transaction logging and audit trails&lt;/li&gt;
&lt;li&gt;Data reconciliation processes&lt;/li&gt;
&lt;li&gt;Error handling and correction procedures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS services that help (even without explicit coverage): Step Functions for workflow orchestration, EventBridge for event tracking, CloudWatch Logs for processing evidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Confidentiality
&lt;/h3&gt;

&lt;p&gt;Confidentiality protects information designated as confidential. If you handle customer data with confidentiality requirements, you'll include this category.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KMS key policies with least privilege&lt;/li&gt;
&lt;li&gt;S3 bucket encryption configurations&lt;/li&gt;
&lt;li&gt;RDS encryption enabled&lt;/li&gt;
&lt;li&gt;Secrets Manager for credential storage&lt;/li&gt;
&lt;li&gt;Evidence of data classification&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;p&gt;Privacy addresses personal information handling per your privacy notice. This often overlaps with GDPR or CCPA requirements. If you collect personal data from end users, you likely need this category.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data inventory and classification&lt;/li&gt;
&lt;li&gt;Retention policies and enforcement&lt;/li&gt;
&lt;li&gt;Consent mechanisms&lt;/li&gt;
&lt;li&gt;Data access logs&lt;/li&gt;
&lt;li&gt;Deletion procedures&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Required AWS Security Controls
&lt;/h2&gt;

&lt;p&gt;Now let's get specific about what you need to implement. Each control section includes what auditors expect to see and the evidence you should collect.&lt;/p&gt;

&lt;p&gt;For implementation details on these controls, see our &lt;a href="https://towardsthecloud.com/blog/aws-security-best-practices" rel="noopener noreferrer"&gt;AWS security best practices&lt;/a&gt; guide which covers the configurations in depth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identity and Access Management (IAM)
&lt;/h3&gt;

&lt;p&gt;IAM misconfigurations cause more audit findings than any other category. Auditors scrutinize access controls closely because they're fundamental to every other Trust Service Criteria.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required controls:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Least privilege&lt;/strong&gt; - Grant minimum permissions needed. Use &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html" rel="noopener noreferrer"&gt;IAM Access Analyzer&lt;/a&gt; to generate policies based on actual CloudTrail activity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No root user operations&lt;/strong&gt; - Eliminate day-to-day root usage. Enable hardware MFA. Never create access keys for root.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MFA enforcement&lt;/strong&gt; - Required for all privileged accounts and console access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Temporary credentials&lt;/strong&gt; - Use IAM roles instead of long-term access keys wherever possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Regular access reviews&lt;/strong&gt; - Remove unused permissions, users, and roles. Document review cadence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Conditions in policies&lt;/strong&gt; - Use conditions like &lt;code&gt;PrincipalOrgID&lt;/code&gt; and &lt;code&gt;CalledVia&lt;/code&gt; to scope access appropriately.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt; IAM Credential Reports showing MFA enabled, CloudTrail logs demonstrating no root activity, sample IAM policies showing least privilege implementation, documentation of access review procedures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Logging and Monitoring
&lt;/h3&gt;

&lt;p&gt;Without comprehensive logging, you can't prove what happened or didn't happen in your environment. Auditors will verify logging is enabled, protected, and retained appropriately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required controls:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CloudTrail multi-region trail&lt;/strong&gt; - Create a trail that captures events in ALL regions. Single-region trails leave blind spots. Follow &lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/best-practices-security.html" rel="noopener noreferrer"&gt;CloudTrail security best practices&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Log file validation enabled&lt;/strong&gt; - This provides integrity checking. Without it, you can't prove logs weren't tampered with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Log encryption with KMS&lt;/strong&gt; - Encrypt CloudTrail logs using AWS KMS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Protected S3 bucket&lt;/strong&gt; - Enable MFA delete, object lock, and strict access controls on your log bucket.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CloudWatch integration&lt;/strong&gt; - Integrate CloudTrail with CloudWatch Logs for real-time alerting on security events.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Appropriate retention&lt;/strong&gt; - Minimum 1 year recommended. Note that CloudTrail console history only shows 90 days.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt; Trail configuration showing multi-region enabled, validation status, encryption key ARN, S3 bucket policy restricting access, sample CloudWatch alarms for security events.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Protection and Encryption
&lt;/h3&gt;

&lt;p&gt;Encryption at rest and in transit protects data even if other controls fail. Auditors want to see encryption enabled by default with proper key management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required controls:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Encryption at rest&lt;/strong&gt; - Enable default encryption for EBS, S3, RDS using AWS KMS. KMS keys are protected by &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/sec_protect_data_rest_encrypt.html" rel="noopener noreferrer"&gt;FIPS 140-3 Level 3 validated HSMs&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Encryption in transit&lt;/strong&gt; - TLS 1.2+ for all connections. Use AWS Certificate Manager for certificate management.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customer-managed KMS keys&lt;/strong&gt; - For fine-grained control and audit trails. Enable automatic key rotation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Least privilege key policies&lt;/strong&gt; - Keys should only be accessible by services and users that need them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Separate keys for different data&lt;/strong&gt; - Use different keys for different data classifications.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt; KMS key policies demonstrating least privilege, encryption configuration screenshots for S3/EBS/RDS, TLS certificate evidence, CloudTrail events showing key usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Threat Detection and Response
&lt;/h3&gt;

&lt;p&gt;Detection capabilities demonstrate security maturity. Auditors want to see that you can identify and respond to threats, not just prevent them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required controls:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GuardDuty enabled&lt;/strong&gt; - Enable in all regions. GuardDuty continuously monitors for malicious activity using machine learning and threat intelligence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-internal-providers.html" rel="noopener noreferrer"&gt;Security Hub&lt;/a&gt; aggregation&lt;/strong&gt; - Aggregates findings from GuardDuty, Inspector, Macie, and Config. Provides security posture dashboard.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Amazon Inspector&lt;/strong&gt; - Vulnerability scanning for EC2, Lambda, and container images. Continuous scanning without standalone agents.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documented incident response plan&lt;/strong&gt; - IR plan with AWS-specific runbooks, tested regularly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automated response&lt;/strong&gt; - EventBridge rules to trigger containment actions for critical findings.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt; GuardDuty enabled confirmation across accounts/regions, Security Hub dashboard showing compliance scores, IR plan documentation, evidence of IR testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Network Security
&lt;/h3&gt;

&lt;p&gt;Network controls determine what can communicate with what. Misconfigured security groups are a leading cause of breaches and audit findings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required controls:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;VPC isolation&lt;/strong&gt; - Workloads in dedicated VPCs with proper subnet segmentation (public, private, isolated).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security group best practices&lt;/strong&gt; - Stateful firewall rules. Avoid 0.0.0.0/0 on sensitive ports. Create purpose-specific groups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network ACLs&lt;/strong&gt; - Stateless subnet-level protection as additional defense layer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;VPC Flow Logs enabled&lt;/strong&gt; - Required for network traffic monitoring and forensic capability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;WAF protection&lt;/strong&gt; - Protect web applications from common exploits using managed rule sets.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt; Security group configurations showing restricted access, VPC architecture diagrams, Flow Log configuration evidence, WAF rules documentation.&lt;/p&gt;

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

&lt;p&gt;For organizations using multiple AWS accounts (recommended), governance controls ensure consistent security across the environment. See &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-best-practices" rel="noopener noreferrer"&gt;AWS multi-account best practices&lt;/a&gt; for detailed implementation guidance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required controls:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS Organizations&lt;/strong&gt; - Centralized management with OU hierarchy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service Control Policies (SCPs)&lt;/strong&gt; - Define maximum available permissions at organization, OU, or account level. See &lt;a href="https://towardsthecloud.com/blog/aws-organizations-best-practices" rel="noopener noreferrer"&gt;AWS Organizations best practices&lt;/a&gt; for SCP patterns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Control Tower&lt;/strong&gt; - Automated landing zone with preventive and detective guardrails.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centralized logging&lt;/strong&gt; - Aggregate CloudTrail, Config, and Security Hub findings across all accounts to a dedicated log archive account.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What auditors look for:&lt;/strong&gt; Organizational structure documentation, SCP examples showing guardrails, centralized logging architecture, Control Tower dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence Collection Strategy
&lt;/h2&gt;

&lt;p&gt;Knowing what controls you need is step one. Proving them to auditors requires systematic evidence collection. This is where many organizations struggle because they implement controls but don't collect evidence proving they work.&lt;/p&gt;

&lt;p&gt;AWS Audit Manager automates much of this process. The prebuilt SOC 2 framework includes 15 automated controls and 46 manual controls across 20 control sets. Understanding what evidence you need helps you configure Audit Manager effectively.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Control Category&lt;/th&gt;
&lt;th&gt;Evidence Type&lt;/th&gt;
&lt;th&gt;Collection Method&lt;/th&gt;
&lt;th&gt;Frequency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;IAM&lt;/td&gt;
&lt;td&gt;Credential reports, policy documents&lt;/td&gt;
&lt;td&gt;API calls, manual upload&lt;/td&gt;
&lt;td&gt;Weekly/Monthly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logging&lt;/td&gt;
&lt;td&gt;Trail configs, sample logs&lt;/td&gt;
&lt;td&gt;CloudTrail, API calls&lt;/td&gt;
&lt;td&gt;Continuous&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;Key policies, encryption configs&lt;/td&gt;
&lt;td&gt;Config rules, API calls&lt;/td&gt;
&lt;td&gt;Event-driven&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;Security group rules, Flow Logs&lt;/td&gt;
&lt;td&gt;Config rules, API calls&lt;/td&gt;
&lt;td&gt;Event-driven&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Threat Detection&lt;/td&gt;
&lt;td&gt;GuardDuty findings, Security Hub scores&lt;/td&gt;
&lt;td&gt;Security Hub integration&lt;/td&gt;
&lt;td&gt;Scheduled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incident Response&lt;/td&gt;
&lt;td&gt;IR plans, test results&lt;/td&gt;
&lt;td&gt;Manual upload&lt;/td&gt;
&lt;td&gt;Quarterly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  AWS Audit Manager for SOC 2
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/audit-manager/latest/userguide/SOC2.html" rel="noopener noreferrer"&gt;AWS Audit Manager&lt;/a&gt; provides a prebuilt SSAE-18 SOC 2 framework. The framework includes 20 control sets aligned to SOC 2 requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting up Audit Manager for SOC 2:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enable Security Hub with all standards enabled (prerequisite)&lt;/li&gt;
&lt;li&gt;Enable necessary AWS Config rules&lt;/li&gt;
&lt;li&gt;Create assessment using the SOC 2 framework&lt;/li&gt;
&lt;li&gt;Configure evidence sources for automated collection&lt;/li&gt;
&lt;li&gt;Set up manual evidence upload procedures for non-AWS controls&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Important clarification:&lt;/strong&gt; Audit Manager controls don't verify compliance or guarantee you'll pass an audit. They organize evidence collection. You still need to ensure your controls are properly implemented and operating effectively.&lt;/p&gt;

&lt;p&gt;Evidence collection should begin 3-6 months before your audit to demonstrate controls operating over time. SOC 2 Type 2 audits examine operating effectiveness over a period (typically 6-12 months), not just point-in-time design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evidence Types and Data Sources
&lt;/h3&gt;

&lt;p&gt;AWS Audit Manager collects evidence from four &lt;a href="https://docs.aws.amazon.com/audit-manager/latest/userguide/control-data-sources.html" rel="noopener noreferrer"&gt;data source types&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User activity (CloudTrail)&lt;/strong&gt; - Continuous API call tracking. Select specific event names for targeted evidence.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compliance checks (AWS Config)&lt;/strong&gt; - Event-driven based on Config rule triggers. Shows resource compliance status.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security findings (Security Hub)&lt;/strong&gt; - Scheduled per Security Hub check schedule. Aggregated security posture.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuration data (API calls)&lt;/strong&gt; - Snapshots at daily, weekly, or monthly frequency. Point-in-time resource state.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Manual evidence&lt;/strong&gt; is still required for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Physical security documentation (if applicable)&lt;/li&gt;
&lt;li&gt;Vendor risk assessments&lt;/li&gt;
&lt;li&gt;Policy documents and procedures&lt;/li&gt;
&lt;li&gt;Training records&lt;/li&gt;
&lt;li&gt;Evidence from non-AWS systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can import manual evidence from S3, upload from browser, or enter as text directly in Audit Manager.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automating Evidence Collection with AWS Config
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/config/latest/developerguide/conformance-packs.html" rel="noopener noreferrer"&gt;AWS Config conformance packs&lt;/a&gt; bundle multiple Config rules for deployment. AWS provides an "Operational Best Practices for SOC 2" conformance pack template. For a broader look at how conformance packs fit into &lt;a href="https://towardsthecloud.com/blog/aws-operational-best-practices" rel="noopener noreferrer"&gt;AWS operational best practices&lt;/a&gt;, see our operations guide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits of conformance packs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy standard rule sets across accounts and regions&lt;/li&gt;
&lt;li&gt;Compliance score showing percentage of compliant rule-resource combinations&lt;/li&gt;
&lt;li&gt;Automated remediation with Systems Manager Automation&lt;/li&gt;
&lt;li&gt;Configuration aggregators for multi-account visibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deploy the SOC 2 conformance pack in all accounts within your audit scope. Configure automated remediation where appropriate, but test remediation actions in non-production first.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 Common SOC 2 Failures on AWS (And How to Avoid Them)
&lt;/h2&gt;

&lt;p&gt;Learning from others' failures is cheaper than learning from your own. These patterns cause consistent audit findings. Most stem from basic misconfigurations that automated tools can detect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Failure #1: Root User Misuse and Access Key Sprawl
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;TSC Mapping:&lt;/strong&gt; Security (CC6.1 - Logical Access)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The failure:&lt;/strong&gt; Using root user for daily operations. Root account without MFA. Sharing root credentials. Long-term access keys not rotated. Unused access keys accumulating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why auditors care:&lt;/strong&gt; Root access is unlimited. No IAM policy or SCP can restrict it. Poor root controls indicate poor security culture overall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eliminate root user for all operations (use IAM users/roles)&lt;/li&gt;
&lt;li&gt;Enable hardware MFA on root account immediately&lt;/li&gt;
&lt;li&gt;Replace long-term access keys with temporary credentials via IAM roles&lt;/li&gt;
&lt;li&gt;Regular access key rotation (90 days maximum) and cleanup of unused keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Evidence to collect:&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/security-audit-guide.html" rel="noopener noreferrer"&gt;IAM Credential Report&lt;/a&gt;, CloudTrail logs showing no root activity over audit period, MFA device configuration for root.&lt;/p&gt;

&lt;h3&gt;
  
  
  Failure #2: CloudTrail Gaps and Missing Log Validation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;TSC Mapping:&lt;/strong&gt; Security (CC7.2 - System Monitoring)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The failure:&lt;/strong&gt; CloudTrail not multi-region. Log validation disabled. Logs not encrypted. S3 bucket publicly accessible or with weak policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why auditors care:&lt;/strong&gt; Without integrity-validated logs, you can't prove what happened. Gaps in logging mean gaps in accountability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create multi-region trail capturing events in ALL regions&lt;/li&gt;
&lt;li&gt;Enable log file validation (integrity checking)&lt;/li&gt;
&lt;li&gt;Encrypt logs with KMS&lt;/li&gt;
&lt;li&gt;Protect S3 bucket with MFA delete and object lock&lt;/li&gt;
&lt;li&gt;Integrate with CloudWatch for real-time alerting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Evidence to collect:&lt;/strong&gt; Trail configuration showing multi-region enabled, validation status, encryption key ARN, bucket policy with access restrictions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Failure #3: Unencrypted Data and Weak Key Management
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;TSC Mapping:&lt;/strong&gt; Confidentiality (C1.1 - Confidential Information Protection)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The failure:&lt;/strong&gt; Data stored unencrypted. Same encryption key for all data. Overly permissive key policies. No key rotation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why auditors care:&lt;/strong&gt; Encryption without proper key management provides false security. Anyone with key access has data access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/sec_protect_data_rest_encrypt.html" rel="noopener noreferrer"&gt;default encryption for EBS, S3, RDS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Use customer-managed KMS keys (not AWS-managed) for control&lt;/li&gt;
&lt;li&gt;Apply least privilege to key policies&lt;/li&gt;
&lt;li&gt;Separate keys for different data classifications&lt;/li&gt;
&lt;li&gt;Enable automatic key rotation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Evidence to collect:&lt;/strong&gt; Encryption configuration for all storage services, KMS key policies showing restricted access, CloudTrail key usage events.&lt;/p&gt;

&lt;h3&gt;
  
  
  Failure #4: Security Group Misconfigurations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;TSC Mapping:&lt;/strong&gt; Security (CC6.6 - Logical Access Security)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The failure:&lt;/strong&gt; Security groups allowing 0.0.0.0/0 on sensitive ports. Default security groups used without modification. Overly permissive rules for unused ports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why auditors care:&lt;/strong&gt; Overly permissive network access is a leading breach vector. It indicates lack of defense-in-depth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restrict inbound rules to specific CIDR ranges&lt;/li&gt;
&lt;li&gt;&lt;a href="https://repost.aws/knowledge-center/ec2-secure-instance" rel="noopener noreferrer"&gt;Remove rules for unused ports&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Never use default security groups without modification&lt;/li&gt;
&lt;li&gt;Enable VPC Flow Logs for network monitoring&lt;/li&gt;
&lt;li&gt;Regular security group audits (at least quarterly)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Evidence to collect:&lt;/strong&gt; Security group configurations showing restricted access, VPC Flow Log configuration, documentation of security group review process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Failure #5: Missing Incident Response Capabilities
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;TSC Mapping:&lt;/strong&gt; Security (CC7.3 - Security Incident Management)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The failure:&lt;/strong&gt; No documented IR plan. GuardDuty not enabled. No automated response capabilities. Team not trained on cloud IR procedures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why auditors care:&lt;/strong&gt; Incidents are inevitable. Response capability demonstrates security maturity and operational readiness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Document &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/aspects-of-aws-incident-response.html" rel="noopener noreferrer"&gt;incident response plan&lt;/a&gt; with AWS-specific runbooks&lt;/li&gt;
&lt;li&gt;Enable GuardDuty in all accounts and regions&lt;/li&gt;
&lt;li&gt;Configure automated containment actions via EventBridge&lt;/li&gt;
&lt;li&gt;Train team on cloud IR procedures&lt;/li&gt;
&lt;li&gt;Retain logs for forensic analysis (minimum 1 year)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Evidence to collect:&lt;/strong&gt; IR plan documentation, GuardDuty enabled confirmation, EventBridge automation rules, training records.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your 90-Day SOC 2 Readiness Plan
&lt;/h2&gt;

&lt;p&gt;Ninety days is aggressive but achievable for organizations with an existing AWS presence and some security maturity. For organizations starting from scratch, plan 6-12 months instead.&lt;/p&gt;

&lt;p&gt;Critical context: SOC 2 Type 2 audits examine controls operating over a period (typically 6-12 months). Even after implementing controls, you need evidence of them working consistently. Start evidence collection as early as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Days 1-30: Assessment and Foundation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Week 1:&lt;/strong&gt; Determine applicable Trust Service Categories. Review AWS SOC reports via Artifact to understand AWS's control coverage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 2:&lt;/strong&gt; Conduct gap analysis. Identify which CUECs need implementation. Use our &lt;a href="https://towardsthecloud.com/blog/aws-security-review-checklist" rel="noopener noreferrer"&gt;security review checklist&lt;/a&gt; as a starting point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 3:&lt;/strong&gt; Define scope (AWS services and accounts). Establish multi-account strategy using AWS Organizations if not already in place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 4:&lt;/strong&gt; Enable foundational logging: CloudTrail (multi-region), AWS Config (all regions), VPC Flow Logs everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliverables:&lt;/strong&gt; Scoping document, gap analysis report, multi-account architecture diagram.&lt;/p&gt;

&lt;h3&gt;
  
  
  Days 31-60: Control Implementation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Weeks 5-6:&lt;/strong&gt; IAM hardening. Eliminate root usage. Enforce MFA everywhere. Implement least privilege policies. Set up regular access reviews.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weeks 7-8:&lt;/strong&gt; Encryption implementation. Deploy KMS keys for each data classification. Enable default encryption for all storage services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weeks 9-10:&lt;/strong&gt; Threat detection deployment. Enable GuardDuty in all accounts and regions. Configure Security Hub with all relevant standards. Deploy Inspector for vulnerability scanning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weeks 11-12:&lt;/strong&gt; Deploy AWS Config conformance packs for SOC 2. Configure automated remediation where appropriate. Set up configuration aggregators for multi-account visibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliverables:&lt;/strong&gt; Implemented controls documentation, conformance pack deployment, Security Hub baseline scores.&lt;/p&gt;

&lt;h3&gt;
  
  
  Days 61-90: Evidence Collection and Pre-Audit
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Week 13:&lt;/strong&gt; Create AWS Audit Manager assessment using SOC 2 framework. Configure all evidence sources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weeks 14-15:&lt;/strong&gt; Verify automated evidence collection is working. Gather manual evidence: policies, procedures, training records, vendor assessments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 16:&lt;/strong&gt; Control testing. Validate controls are operating effectively, not just designed correctly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weeks 17-18:&lt;/strong&gt; Remediate any identified gaps. Finalize documentation. Prepare for auditor walkthrough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliverables:&lt;/strong&gt; Audit Manager assessment with collected evidence, complete documentation package, remediation log.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparing for the Audit
&lt;/h2&gt;

&lt;p&gt;With controls implemented and evidence collected, you're approaching audit readiness. Understanding what happens during the audit helps you prepare the right materials and people.&lt;/p&gt;

&lt;p&gt;SOC 2 audits come in two types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type 1&lt;/strong&gt; tests control design at a point in time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type 2&lt;/strong&gt; tests operating effectiveness over a period (typically 6-12 months)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most customers require Type 2 reports because they demonstrate controls actually work, not just that they exist on paper.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Auditors Will Test
&lt;/h3&gt;

&lt;p&gt;Auditors evaluate controls across three dimensions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Control design&lt;/strong&gt; - Is the control designed to meet the Trust Service Criteria requirements?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Control implementation&lt;/strong&gt; - Is the control actually in place and configured correctly?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operating effectiveness (Type 2 only)&lt;/strong&gt; - Has the control been working consistently throughout the audit period?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;They'll sample transactions and configurations across the audit period. Prepare walkthroughs for key controls and have subject matter experts available for questions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Audit Questions by TSC
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Security questions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Show me your access review process. Walk me through how an employee gets access and how it's revoked."&lt;/li&gt;
&lt;li&gt;"Demonstrate how you enforce least privilege. Show me a sample policy."&lt;/li&gt;
&lt;li&gt;"How do you detect unauthorized access attempts?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Availability questions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"What's your uptime over the audit period? Show me incident tickets."&lt;/li&gt;
&lt;li&gt;"Walk me through your backup and recovery procedures. When did you last test recovery?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Confidentiality questions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"How is confidential data classified and encrypted? Who has access to encryption keys?"&lt;/li&gt;
&lt;li&gt;"Show me your key management procedures."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Privacy questions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Show me your data retention policies. How do you handle deletion requests?"&lt;/li&gt;
&lt;li&gt;"Where is personal data stored and who has access?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Processing Integrity questions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"How do you validate data accuracy? Show me reconciliation reports."&lt;/li&gt;
&lt;li&gt;"What happens when processing errors occur? Walk me through an example."&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When to Get Professional Help
&lt;/h3&gt;

&lt;p&gt;Consider external assistance if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First SOC 2 audit&lt;/strong&gt; - A readiness assessment from a qualified firm identifies gaps before the real audit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited internal expertise&lt;/strong&gt; - Your team excels at development and operations but security compliance isn't their specialty&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tight timelines&lt;/strong&gt; - Less than 90 days to audit with significant gaps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex environments&lt;/strong&gt; - Multi-account architectures with sophisticated compliance requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS Security Assurance Services provides compliance advisory. When selecting AWS security partners for compliance work, use our &lt;a href="https://towardsthecloud.com/blog/aws-security-partner" rel="noopener noreferrer"&gt;partner evaluation framework&lt;/a&gt; to verify their SOC 2 experience and AWS competencies. To understand what a security review engagement entails, see our &lt;a href="https://towardsthecloud.com/blog/aws-security-review-process" rel="noopener noreferrer"&gt;AWS security review process&lt;/a&gt; guide. Third-party GRC platforms (Vanta, Drata, Secureframe) can accelerate evidence collection. Independent consultancies like ours provide hands-on implementation alongside guidance. See how we helped &lt;a href="https://towardsthecloud.com/blog/case-study-accolade" rel="noopener noreferrer"&gt;Accolade achieve SOC 2 compliance&lt;/a&gt; with a properly governed AWS foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Your SOC 2 Readiness Checklist
&lt;/h2&gt;

&lt;p&gt;AWS SOC 2 compliance requires understanding two things: which controls AWS provides versus which you must implement, and what evidence proves your controls work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shared responsibility is critical&lt;/strong&gt; - AWS handles infrastructure security. You handle everything built on it. Auditors evaluate YOUR controls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Processing Integrity is entirely your responsibility&lt;/strong&gt; - AWS explicitly excludes this TSC. Plan accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evidence collection takes time&lt;/strong&gt; - Start AWS Audit Manager 3-6 months before audit to demonstrate controls operating over time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Common failures are preventable&lt;/strong&gt; - Root user controls, CloudTrail validation, encryption, security groups, IR capabilities. Address these first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;90 days is achievable&lt;/strong&gt; - With focused effort, proper tooling, and clear priorities.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Your immediate next step:&lt;/strong&gt; Access AWS Artifact today to download AWS's SOC reports. Understand their control coverage. Identify gaps in your environment using Security Hub. That baseline tells you exactly where to focus.&lt;/p&gt;

&lt;p&gt;For organizations wanting expert guidance, a security review identifies gaps quickly and provides a prioritized remediation roadmap. We've helped teams get audit-ready in weeks instead of months.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>awssecurity</category>
      <category>soc2</category>
      <category>compliance</category>
      <category>awsauditmanager</category>
    </item>
    <item>
      <title>AWS Landing Zone Benefits: The ROI That Justifies Your Investment</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 15:17:51 +0000</pubDate>
      <link>https://forem.com/aws-builders/aws-landing-zone-benefits-the-roi-that-justifies-your-investment-510</link>
      <guid>https://forem.com/aws-builders/aws-landing-zone-benefits-the-roi-that-justifies-your-investment-510</guid>
      <description>&lt;p&gt;You already know an AWS Landing Zone is best practice. Every AWS whitepaper, every Solutions Architect, every conference talk says the same thing: build a landing zone. But "it's best practice" doesn't get budget approved.&lt;/p&gt;

&lt;p&gt;What gets budget approved is concrete evidence. Numbers your CFO can put in a spreadsheet. Risk reduction your CISO can quantify. Time savings your engineering leads can validate. And that's exactly what's missing from every landing zone article out there. They all list the same generic benefits without a single metric to back them up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's what the AWS Landing Zone benefits actually look like in measurable terms: account provisioning drops from days to under 1 hour (95%+ reduction), operational overhead shrinks by 60-80%, compliance shifts from quarterly fire drills to continuous monitoring, and your developers stop waiting days for accounts they can provision themselves in minutes.&lt;/strong&gt; These aren't aspirational goals. They're the documented outcomes from &lt;a href="https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html" rel="noopener noreferrer"&gt;AWS Control Tower's&lt;/a&gt; automated multi-account architecture.&lt;/p&gt;

&lt;p&gt;I've implemented landing zones for organizations ranging from Series B startups to regulated enterprises. In this guide, I break down every benefit into the five ROI pillars that matter for your business case: security, compliance, cost optimization, operational efficiency, and developer velocity. Whether you're building a board deck or convincing your CTO, this is the ammunition you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is an AWS Landing Zone (Brief Refresher)
&lt;/h2&gt;

&lt;p&gt;If you're searching for "AWS Landing Zone benefits," you likely have a baseline understanding of the concept. So I'll keep this brief.&lt;/p&gt;

&lt;p&gt;An AWS Landing Zone is a well-architected, multi-account AWS environment with built-in governance, security, and compliance controls. Think of it as the enterprise-wide foundation that holds all your organizational units (OUs), accounts, users, and workloads under a single, centrally managed umbrella.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html" rel="noopener noreferrer"&gt;AWS Control Tower&lt;/a&gt; is the managed service that automates landing zone setup in under one hour. It orchestrates AWS Organizations, AWS Service Catalog, and AWS IAM Identity Center to provision everything you need: identity management, policy enforcement, data security, network design, and centralized logging. Control Tower extends AWS Organizations by layering on automated guardrails that prevent drift from best practices.&lt;/p&gt;

&lt;p&gt;For a deeper dive into &lt;a href="https://towardsthecloud.com/blog/aws-landing-zone" rel="noopener noreferrer"&gt;what an AWS Landing Zone is and how multi-account architecture works&lt;/a&gt;, I've written a comprehensive guide. What matters for this conversation is understanding that the architecture's structure, account isolation, centralized governance, and automated controls, is what creates the business value we're about to quantify.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftowardsthecloud.com%2Fimages%2Fblog%2Faws-landing-zone-benefits%2Fmulti-account-architecture.excalidraw" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftowardsthecloud.com%2Fimages%2Fblog%2Faws-landing-zone-benefits%2Fmulti-account-architecture.excalidraw" alt="AWS Landing Zone multi-account architecture with management account, security OU, infrastructure OU, workload OUs, and sandbox OU showing policy inheritance and centralized logging flows" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that the architectural foundation is clear, let's look at the concrete business outcomes this architecture delivers, starting with the most critical: security and risk reduction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security and Risk Reduction Benefits
&lt;/h2&gt;

&lt;p&gt;Security is the benefit every competitor article mentions, but none of them quantify what "better security" actually means in operational terms. Here's what it looks like when you move from ad-hoc account management to a landing zone with automated controls.&lt;/p&gt;

&lt;h3&gt;
  
  
  130+ Automated Security Controls
&lt;/h3&gt;

&lt;p&gt;AWS Control Tower provides three types of controls that work together to create a layered security model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Preventive controls&lt;/strong&gt; use Service Control Policies (SCPs) to block violations before they happen. These are organization-wide permission boundaries that prevent actions like creating root access keys, enabling public S3 bucket access, or deleting CloudTrail logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detective controls&lt;/strong&gt; use AWS Config rules to continuously monitor deployed resources for non-conformance. They catch issues like unrestricted TCP traffic, unencrypted data stores, and unattached EBS volumes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proactive controls&lt;/strong&gt; use CloudFormation hooks to evaluate resources before deployment, shifting security left in the development lifecycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With &lt;a href="https://docs.aws.amazon.com/controltower/latest/controlreference/compliance.html" rel="noopener noreferrer"&gt;130+ proactive controls&lt;/a&gt; available out of the box (as of Control Tower v3.0+), you get comprehensive security coverage from a central location. Compare that to manually configuring security policies account by account, and the risk reduction becomes obvious.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blast Radius Containment Through Account Isolation
&lt;/h3&gt;

&lt;p&gt;Each AWS account acts as a hard isolation boundary. A compromise in one account does not automatically provide access to resources in other accounts. This is the &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/sec_securely_operate_multi_accounts.html" rel="noopener noreferrer"&gt;Well-Architected Framework's SEC01-BP01 best practice&lt;/a&gt; in action.&lt;/p&gt;

&lt;p&gt;The practical impact of a multi-account strategy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security isolation&lt;/strong&gt;: credentials compromised in a development account cannot access production data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data isolation&lt;/strong&gt;: sensitive data lives in dedicated accounts with stricter access controls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quota isolation&lt;/strong&gt;: a runaway workload in one account cannot exhaust service limits in another&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workload separation&lt;/strong&gt;: different compliance levels (PCI-DSS production vs. development sandbox) get different security postures without complex policy management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Organizations using AWS Control Tower can scale to &lt;strong&gt;10,000 accounts&lt;/strong&gt; while maintaining consistent security controls through hierarchical policy application. That's not a theoretical limit. It's the documented ceiling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Centralized Security Visibility
&lt;/h3&gt;

&lt;p&gt;AWS Control Tower automatically creates a Security OU with two specialized accounts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Log Archive Account&lt;/strong&gt;: centralized, tamper-proof repository for CloudTrail, AWS Config, VPC Flow Logs, and S3 access logs across all accounts. Logs are encrypted using AWS KMS and stored in a separate account, so even if an attacker compromises a workload account, the audit trail remains intact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit Account&lt;/strong&gt;: provides cross-account read/write access for security teams, integrates with &lt;a href="https://aws.amazon.com/blogs/security/streamline-security-response-at-scale-with-aws-security-hub-automation/" rel="noopener noreferrer"&gt;Security Hub and GuardDuty&lt;/a&gt;, and serves as the central point for security monitoring and incident response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This architecture gives your security team a single pane of glass across the entire organization. No more logging into individual accounts. No more wondering if CloudTrail is actually enabled everywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated Threat Detection and Response
&lt;/h3&gt;

&lt;p&gt;The landing zone architecture enables rapid security response through integrated services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GuardDuty&lt;/strong&gt; monitors for malicious activity across all accounts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Hub&lt;/strong&gt; aggregates findings and provides compliance scoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EventBridge&lt;/strong&gt; triggers automated remediation workflows based on finding severity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Systems Manager Automation&lt;/strong&gt; executes runbooks to isolate compromised resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result: reduced mean-time-to-response (MTTR) for security incidents. Instead of hours spent identifying which account is affected and manually remediating, automated detection and response handles common scenarios in minutes.&lt;/p&gt;

&lt;p&gt;Security controls don't just protect your infrastructure. They also create the audit trail and evidence collection that transforms compliance from a quarterly fire drill into an always-on process.&lt;/p&gt;

&lt;h2&gt;
  
  
  How an AWS Landing Zone Accelerates Compliance
&lt;/h2&gt;

&lt;p&gt;Compliance is where the landing zone ROI often hits hardest, especially for organizations in regulated industries. The shift from periodic, manual compliance checks to continuous, automated monitoring fundamentally changes how audit preparation works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Continuous Compliance Monitoring
&lt;/h3&gt;

&lt;p&gt;Traditional compliance operates on a point-in-time model: auditors show up, you scramble to collect evidence, gaps are discovered, remediation takes weeks. A landing zone replaces this cycle with continuous monitoring.&lt;/p&gt;

&lt;p&gt;Detective controls implemented through AWS Config rules evaluate resource configurations continuously. &lt;a href="https://docs.aws.amazon.com/controltower/latest/controlreference/compliance.html" rel="noopener noreferrer"&gt;Compliance status is reported&lt;/a&gt; at the organization unit, account, and control levels. The dashboard provides real-time visibility into your compliance posture, so you know the moment something drifts out of compliance, not three months later during an audit.&lt;/p&gt;

&lt;p&gt;AWS Control Tower also runs automated drift detection to catch when resources or configurations deviate from your established baseline. Governance drift (changes to Control Tower-managed resources) and resource drift (modifications to deployed configurations) are both detected and surfaced automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audit-Ready Evidence on Demand
&lt;/h3&gt;

&lt;p&gt;CloudTrail automatically captures all API calls across all accounts. AWS Config continuously records every resource configuration and change. All of this flows into the centralized Log Archive account with encryption and retention policies aligned to compliance periods.&lt;/p&gt;

&lt;p&gt;This means audit preparation transforms from a months-long manual process to a continuous, automated activity. When auditors ask "show me all changes to your production databases in the last 90 days," you pull a report instead of starting an investigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Framework-Specific Benefits (SOC 2, HIPAA, PCI-DSS)
&lt;/h3&gt;

&lt;p&gt;AWS Control Tower supports compliance with specific regulatory frameworks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SOC 1/2/3&lt;/strong&gt;: automated evidence collection, continuous control monitoring, and centralized audit trails directly support SOC 2 Trust Services Criteria. See &lt;a href="https://towardsthecloud.com/blog/aws-soc-2-compliance" rel="noopener noreferrer"&gt;what SOC 2 auditors look for in your AWS controls&lt;/a&gt; for detailed mapping.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HIPAA&lt;/strong&gt;: data isolation through separate accounts, encryption enforcement via SCPs, and access logging satisfy key HIPAA technical safeguards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PCI-DSS&lt;/strong&gt;: network segmentation through account isolation, continuous monitoring of security configurations, and tamper-proof logging address multiple PCI-DSS requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GDPR and FedRAMP&lt;/strong&gt;: Region deny controls restrict where resources can be created, ensuring data residency requirements are met.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compliance reports are available through &lt;a href="https://docs.aws.amazon.com/controltower/latest/userguide/compliance-program-info.html" rel="noopener noreferrer"&gt;AWS Artifact&lt;/a&gt;, and AWS Config Conformance Packs provide pre-configured rules for specific frameworks. EventBridge integration enables automated workflows when compliance violations are detected.&lt;/p&gt;

&lt;p&gt;While security and compliance protect your organization, the financial benefits of a landing zone directly impact your bottom line, and they compound over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Optimization Benefits That Compound Over Time
&lt;/h2&gt;

&lt;p&gt;Despite "aws landing zone pricing" being a frequent related search, only 2 of the top 8 results even mention cost management. This is a massive gap, because the cost optimization benefits are significant and grow as your organization scales.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consolidated Billing and Volume Discounts
&lt;/h3&gt;

&lt;p&gt;AWS Organizations provides consolidated billing across all accounts in your organization. Your management account receives a single bill, and usage is aggregated across all accounts for volume pricing tiers.&lt;/p&gt;

&lt;p&gt;Here's why this matters financially:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Volume pricing&lt;/strong&gt;: higher combined usage across accounts leads to lower per-unit costs for services like S3, data transfer, and EC2. Even when usage is distributed across dozens of accounts, you get the aggregate discount.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared Savings Plans and Reserved Instances&lt;/strong&gt;: commitment-based pricing can be purchased centrally and shared across accounts. No more each team buying their own RIs independently and missing organizational optimization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified accounting&lt;/strong&gt;: one bill instead of dozens. Reduced administrative overhead for finance teams processing invoices and managing payments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cost Visibility and Allocation
&lt;/h3&gt;

&lt;p&gt;A landing zone gives you cost attribution tools that simply don't work well in a single-account environment.&lt;/p&gt;

&lt;p&gt;As of &lt;a href="https://aws.amazon.com/about-aws/whats-new/2025/12/cost-allocation-tags/" rel="noopener noreferrer"&gt;December 2025&lt;/a&gt;, AWS introduced account tags for cost allocation. Tags applied at the account level in AWS Organizations automatically apply to all usage within tagged accounts. This eliminates the need for manual cost groupings in Cost Explorer and Cost and Usage Reports. Changes propagate automatically across all cost management products.&lt;/p&gt;

&lt;p&gt;Combined with OU-based cost allocation and Cost Categories, you get a complete picture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Account-level tracking&lt;/strong&gt;: every account's spend attributed to the right business unit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource-level tags&lt;/strong&gt;: granular tracking at the application or workload level within accounts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated categorization&lt;/strong&gt;: costs grouped by OU structure, business unit, or environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chargeback and showback&lt;/strong&gt;: accurate cost allocation for internal billing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Waste Reduction Through Governance
&lt;/h3&gt;

&lt;p&gt;This is the cost benefit most organizations underestimate. Governance controls don't just enforce security. They prevent waste.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Preventive controls&lt;/strong&gt; restrict provisioning of expensive resources in non-production accounts (no p4d.24xlarge instances in sandbox, thank you)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detective controls&lt;/strong&gt; identify unattached EBS volumes, underutilized instances, and other idle resources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Region restrictions&lt;/strong&gt; prevent accidental resource creation in unintended (often more expensive) Regions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Budget controls&lt;/strong&gt;: AWS Budgets can be automatically applied to new accounts through Account Factory customization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instance Scheduler&lt;/strong&gt;: centrally managed solutions that stop non-production resources during non-business hours&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The combination of volume discounts (5-15% through aggregated usage), governance-driven waste reduction, and operational cost reduction (60-80% less time on account management) creates a cost optimization flywheel that compounds as your organization grows.&lt;/p&gt;

&lt;p&gt;Cost savings free up budget, but the operational efficiency gains free up something even more valuable: your team's time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operational Efficiency Gains
&lt;/h2&gt;

&lt;p&gt;The operational benefits are where the 60-80% reduction in time spent on account management comes from. Let me break down exactly where that time savings originates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated Account Provisioning
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/controltower/latest/userguide/account-factory.html" rel="noopener noreferrer"&gt;Account Factory&lt;/a&gt; transforms account creation from a manual, error-prone process into an automated workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Account creation completes in under 30 minutes&lt;/strong&gt; with full security baseline, network configuration, centralized logging, and IAM Identity Center access configured automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Up to 5 accounts can be provisioned concurrently&lt;/strong&gt; (adjustable quota up to 10), enabling batch provisioning for large organizational changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero manual configuration&lt;/strong&gt; required for CloudTrail, AWS Config, or centralized logging. It's all automatic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compare this to the alternative: days of manual setup per account, ticket queues, approval chains, and the inevitable "we forgot to enable CloudTrail in that new account" discovery three months later.&lt;/p&gt;

&lt;p&gt;Automation options scale with your maturity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Console-based provisioning&lt;/strong&gt; through Account Factory for occasional use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service Catalog APIs&lt;/strong&gt; for programmatic batch account creation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Account Factory for Terraform (AFT)&lt;/strong&gt; for GitOps-based account management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizations for AWS Control Tower (CfCT)&lt;/strong&gt; for version-controlled infrastructure definitions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Standardization and Drift Prevention
&lt;/h3&gt;

&lt;p&gt;Every account provisioned through Account Factory receives a consistent baseline. Controls applied at the OU level are automatically inherited by all child OUs and accounts. Changes propagate automatically.&lt;/p&gt;

&lt;p&gt;AWS Control Tower runs daily automated scans to verify controls are applied correctly. When configurations drift from baseline, the dashboard alerts your team immediately. No more discovering that someone disabled Config in a production account during an incident retrospective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduced Manual Overhead
&lt;/h3&gt;

&lt;p&gt;Here's where the &lt;strong&gt;60-80% reduction in operational time&lt;/strong&gt; breaks down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Centralized dashboard&lt;/strong&gt; for monitoring thousands of accounts, replacing account-by-account login&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated compliance checks&lt;/strong&gt; eliminating manual compliance reviews&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch operations&lt;/strong&gt; for large-scale changes across up to 300 accounts per OU&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized policy management&lt;/strong&gt; with changes propagating automatically, replacing account-by-account scripts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated drift detection&lt;/strong&gt; running continuously without manual intervention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When operations teams spend 60-80% less time on account management, the downstream effect is faster delivery for your development teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Velocity and Time-to-Market
&lt;/h2&gt;

&lt;p&gt;This is the benefit zero competitors mention, and it's the one that resonates most strongly with CTOs. A landing zone doesn't just make operations efficient. It makes your developers faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-Service Account Provisioning
&lt;/h3&gt;

&lt;p&gt;IAM Identity Center users in the AWSAccountFactory group can provision accounts without IT involvement. Fully configured accounts ready in under an hour. No waiting for manual setup, approval chains, or security reviews.&lt;/p&gt;

&lt;p&gt;Think about what that means: a team lead who needs a sandbox environment for a proof-of-concept doesn't file a ticket and wait three days. They provision an account, get a fully configured environment with security baselines baked in, and start building. Same day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guardrails That Enable Autonomy
&lt;/h3&gt;

&lt;p&gt;Here's a counterintuitive insight: &lt;strong&gt;guardrails don't slow developers down. They speed them up.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without guardrails, developers wait for security team approval on every account request. The security team becomes a bottleneck because they have to manually verify every configuration. Preventive and detective controls replace that bottleneck with automated policy enforcement. Teams innovate within defined boundaries without security team involvement for standard operations.&lt;/p&gt;

&lt;p&gt;The security team shifts from gatekeeper to enabler. They define the guardrails once, and developers operate freely within those boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Faster Path to Production
&lt;/h3&gt;

&lt;p&gt;The velocity improvement compounds across the development lifecycle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time to first deployment in new account: days reduced to under 2 hours.&lt;/strong&gt; New accounts come with security baselines pre-configured. No waiting for security reviews.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Waiting for security approvals: eliminated&lt;/strong&gt; for standard configurations. Preventive controls handle compliance automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment consistency issues: reduced through standardization.&lt;/strong&gt; Same security model across dev, staging, and production means fewer "it works in dev" surprises.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple teams work independently&lt;/strong&gt; in separate accounts. No resource contention, no naming conflicts, blast radius limited to individual accounts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've covered what you gain. Now let's look at what you risk losing by NOT implementing a landing zone.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost of NOT Having a Landing Zone
&lt;/h2&gt;

&lt;p&gt;No competitor article addresses this, and that's a mistake. Decision-makers need to understand both sides: the upside of investing AND the downside of not investing. The cost of inaction is not zero. It compounds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Risks and Compliance Failures
&lt;/h3&gt;

&lt;p&gt;Without a landing zone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security controls are applied inconsistently (or not at all) across accounts&lt;/li&gt;
&lt;li&gt;Manual configuration multiplies misconfiguration risk&lt;/li&gt;
&lt;li&gt;No centralized logging means security incidents go undetected longer&lt;/li&gt;
&lt;li&gt;Cross-account incident response requires logging into individual accounts&lt;/li&gt;
&lt;li&gt;Compliance evidence collection is manual and time-consuming, turning every audit into a fire drill&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Operational Bottlenecks and Cost Sprawl
&lt;/h3&gt;

&lt;p&gt;Without centralized governance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Central IT becomes the bottleneck for every new account request&lt;/li&gt;
&lt;li&gt;Development teams wait days for infrastructure they could provision in minutes&lt;/li&gt;
&lt;li&gt;Policy changes require manual updates in every account&lt;/li&gt;
&lt;li&gt;Scaling the account count requires proportional growth in the operations team&lt;/li&gt;
&lt;li&gt;Cost allocation is manual, error-prone, and incomplete, making chargeback nearly impossible&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  With vs Without: A Side-by-Side Comparison
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Without Landing Zone&lt;/th&gt;
&lt;th&gt;With Landing Zone&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Account provisioning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Days to weeks (manual)&lt;/td&gt;
&lt;td&gt;Under 1 hour (automated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security baseline deployment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual per account, inconsistent&lt;/td&gt;
&lt;td&gt;Automatic, consistent across all accounts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Policy deployment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hours per account, manual scripts&lt;/td&gt;
&lt;td&gt;Minutes for all accounts, automatic inheritance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compliance evidence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Weeks of manual collection&lt;/td&gt;
&lt;td&gt;On-demand, continuous&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security incident response&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hours (manual identification and access)&lt;/td&gt;
&lt;td&gt;Minutes (automated detection and remediation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Operational overhead&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Baseline (grows linearly with accounts)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;60-80% reduction&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost visibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual tagging, incomplete&lt;/td&gt;
&lt;td&gt;Automated allocation, comprehensive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Developer wait time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Days for new accounts&lt;/td&gt;
&lt;td&gt;Under 1 hour, self-service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Drift detection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual audits, periodic&lt;/td&gt;
&lt;td&gt;Automated, daily scans&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Requires proportional ops team growth&lt;/td&gt;
&lt;td&gt;Scales to 10,000 accounts with same tooling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The gap between these two columns widens with every account you add. At 5 accounts, the pain is manageable. At 50, it's significant. At 500, it's unsustainable.&lt;/p&gt;

&lt;p&gt;Whether you're managing 10 accounts or planning for 1,000, a landing zone scales with you without requiring architectural redesign.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built to Scale: From 10 to 10,000 Accounts
&lt;/h2&gt;

&lt;p&gt;A common concern I hear from decision-makers: "We're not enterprise-scale yet. Is a landing zone overkill?" The answer is no, because a landing zone's architecture is designed to grow with you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling Account Structure
&lt;/h3&gt;

&lt;p&gt;The numbers speak for themselves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Up to 10,000 accounts&lt;/strong&gt; in a single landing zone&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Up to 1,000 accounts per OU&lt;/strong&gt; for organizing workloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nested OUs up to 5 levels deep&lt;/strong&gt; for sophisticated organizational hierarchies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maximum 400 OUs&lt;/strong&gt; per organization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Up to 5 concurrent account operations&lt;/strong&gt; (adjustable to 10) for batch provisioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Up to 100 concurrent control operations&lt;/strong&gt; for large-scale governance changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulk updates for up to 300 accounts&lt;/strong&gt; per OU operation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You start with 10 accounts. You grow to 100. Then 1,000. The architecture doesn't change. The governance model scales. You don't need to redesign or migrate.&lt;/p&gt;

&lt;p&gt;For organizations planning their growth trajectory, I've written a guide on how to &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-strategy" rel="noopener noreferrer"&gt;design the right multi-account strategy for your growth stage&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flexible Governance Models
&lt;/h3&gt;

&lt;p&gt;As your cloud maturity evolves, so can your governance approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Centralized&lt;/strong&gt;: a single cloud platform team manages the landing zone and core policies. Best for organizations starting out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Federated&lt;/strong&gt;: business units manage their own OUs within the central framework. Delegated administrators handle service-specific governance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid&lt;/strong&gt;: mandatory central controls plus optional business unit controls. The most common model at scale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The landing zone supports all three models and lets you transition between them without downtime or migration. Multi-organization support also enables clean separation for acquisitions and divestitures.&lt;/p&gt;

&lt;p&gt;Now that you understand the full scope of AWS Landing Zone benefits, how do you know if your organization is ready to invest?&lt;/p&gt;

&lt;h2&gt;
  
  
  When Your Organization Needs a Landing Zone
&lt;/h2&gt;

&lt;p&gt;Not every organization needs a landing zone today. But most organizations that think they don't, actually do. Here's how to evaluate your situation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Signals That It Is Time to Invest
&lt;/h3&gt;

&lt;p&gt;You need a landing zone if you match &lt;strong&gt;three or more&lt;/strong&gt; of these signals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managing &lt;strong&gt;3+ AWS accounts&lt;/strong&gt; with manual governance processes&lt;/li&gt;
&lt;li&gt;Facing compliance requirements (SOC 2, HIPAA, PCI-DSS) with manual evidence collection&lt;/li&gt;
&lt;li&gt;Experiencing security incidents from misconfigured accounts&lt;/li&gt;
&lt;li&gt;Development teams waiting for account access or infrastructure setup&lt;/li&gt;
&lt;li&gt;Inability to accurately track and allocate AWS costs by team or project&lt;/li&gt;
&lt;li&gt;Operations team spending significant time on repetitive account management tasks&lt;/li&gt;
&lt;li&gt;Scaling plans that require more accounts in the next 12 months&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choosing Your Implementation Approach
&lt;/h3&gt;

&lt;p&gt;Three paths, each suited to different organizational profiles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AWS Control Tower (managed)&lt;/strong&gt;: fastest time-to-value, AWS-managed controls, landing zone setup in under 1 hour. Recommended for most organizations and the default starting point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure as Code (CDK, Terraform)&lt;/strong&gt;: maximum flexibility and customization, GitOps workflows, best for engineering-mature organizations with specific requirements. See &lt;a href="https://towardsthecloud.com/blog/aws-control-tower-alternatives" rel="noopener noreferrer"&gt;AWS Control Tower alternatives including IaC-based approaches&lt;/a&gt; for a detailed comparison.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Partner-led&lt;/strong&gt;: expert guidance, faster time-to-value for complex environments, recommended when internal cloud expertise is limited. Particularly valuable for regulated industries where compliance requirements add complexity.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you'd like expert guidance on your specific situation, understanding &lt;a href="https://towardsthecloud.com/blog/aws-control-tower-vs-aws-organizations" rel="noopener noreferrer"&gt;how AWS Control Tower builds on AWS Organizations&lt;/a&gt; is a solid next step for evaluating your options.&lt;/p&gt;

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

&lt;p&gt;The evidence is clear: an AWS Landing Zone is not a cost. It's an investment with measurable returns across five pillars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Landing Zone benefits in summary:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: 130+ automated controls, three-tier security model (preventive, detective, proactive), blast radius containment through account isolation, centralized visibility&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance&lt;/strong&gt;: continuous monitoring replaces periodic audits, on-demand audit evidence, framework-specific support for SOC 2, HIPAA, PCI-DSS, GDPR, and FedRAMP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost optimization&lt;/strong&gt;: consolidated billing with volume discounts, automated cost allocation (including the new 2025 account tags feature), governance-driven waste reduction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational efficiency&lt;/strong&gt;: 60-80% reduction in account management time, automated provisioning in under 30 minutes, daily drift detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer velocity&lt;/strong&gt;: self-service accounts in under 1 hour (not days), guardrails that enable autonomy instead of creating bottlenecks, faster path to production&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The cost of NOT investing compounds: manual overhead grows linearly with accounts, security risk increases, compliance gaps widen, and developers slow down.&lt;/p&gt;

&lt;p&gt;Start by evaluating your current setup against the signals in the "When Your Organization Needs a Landing Zone" section. If you match three or more, begin planning your implementation. AWS Control Tower can deliver initial value in under one hour.&lt;/p&gt;

&lt;p&gt;For a deeper look at the architecture, read my guide on &lt;a href="https://towardsthecloud.com/blog/aws-landing-zone" rel="noopener noreferrer"&gt;what an AWS Landing Zone is&lt;/a&gt;. For teams already evaluating implementation paths, check the &lt;a href="https://towardsthecloud.com/blog/case-study-accolade" rel="noopener noreferrer"&gt;Accolade case study&lt;/a&gt; for a practical example of landing zone deployment.&lt;/p&gt;

&lt;p&gt;What's your biggest hesitation about investing in a landing zone? I'd be curious to hear what's holding back your business case in the comments below.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>landingzone</category>
      <category>awscontroltower</category>
      <category>multiaccount</category>
      <category>governance</category>
    </item>
    <item>
      <title>How AWS Multi-Account Architecture Cuts Costs by 20-40%</title>
      <dc:creator>Danny Steenman</dc:creator>
      <pubDate>Thu, 02 Apr 2026 15:17:48 +0000</pubDate>
      <link>https://forem.com/aws-builders/how-aws-multi-account-architecture-cuts-costs-by-20-40-p3e</link>
      <guid>https://forem.com/aws-builders/how-aws-multi-account-architecture-cuts-costs-by-20-40-p3e</guid>
      <description>&lt;p&gt;Most organizations adopt multi-account architecture for security and governance. What they consistently discover is that it also reduces their AWS bill by &lt;strong&gt;20-40% through six distinct cost mechanisms&lt;/strong&gt; that compound on top of each other.&lt;/p&gt;

&lt;p&gt;I'm not talking about a vague "it might save you money" promise. I'm talking about quantifiable AWS multi-account cost savings you can calculate before committing: consolidated billing volume discounts, centralized Savings Plans, preventive cost controls, shared infrastructure, centralized monitoring, and automated cleanup. Beyond these direct savings mechanisms, &lt;a href="https://towardsthecloud.com/blog/aws-landing-zone-benefits#cost-optimization-benefits-that-compound-over-time" rel="noopener noreferrer"&gt;landing zones add governance-driven waste reduction and automated budget enforcement&lt;/a&gt; that prevent unnecessary spending before it happens.&lt;/p&gt;

&lt;p&gt;This guide breaks down each strategy with specific savings percentages and real cost calculations so you can build a business case with actual numbers. The strategies are grounded in the &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/cost-optimization-pillar/cost_govern_usage_account_structure.html" rel="noopener noreferrer"&gt;AWS Well-Architected Framework Cost Optimization Pillar&lt;/a&gt; and backed by current AWS pricing.&lt;/p&gt;

&lt;p&gt;Here is the summary of what each strategy delivers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Typical Savings Impact&lt;/th&gt;
&lt;th&gt;Effort Level&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Consolidated Billing and Volume Discounts&lt;/td&gt;
&lt;td&gt;5-20% through aggregated usage&lt;/td&gt;
&lt;td&gt;Low (automatic)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Centralized Savings Plans and RIs&lt;/td&gt;
&lt;td&gt;Up to 72% on compute&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Service Control Policies&lt;/td&gt;
&lt;td&gt;Preventive (avoids waste)&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shared Infrastructure&lt;/td&gt;
&lt;td&gt;30-50% on networking costs&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Centralized Monitoring and Budgeting&lt;/td&gt;
&lt;td&gt;Detective (catches overruns)&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automated Idle Resource Cleanup&lt;/td&gt;
&lt;td&gt;10-15% of total spend recovered&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are still &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-strategy" rel="noopener noreferrer"&gt;designing your AWS multi-account strategy&lt;/a&gt;, start there for the architectural foundation. This post focuses entirely on the cost savings you unlock once the structure is in place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Multi-Account Architecture Reduces AWS Costs
&lt;/h2&gt;

&lt;p&gt;The fundamental cost mechanism is simple: &lt;a href="https://towardsthecloud.com/blog/aws-organizations" rel="noopener noreferrer"&gt;AWS Organizations&lt;/a&gt; &lt;a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/consolidated-billing.html" rel="noopener noreferrer"&gt;consolidated billing&lt;/a&gt; aggregates usage from all member accounts under a single management account. Instead of each account operating as an isolated billing entity, your entire organization's usage counts toward volume discount tiers together.&lt;/p&gt;

&lt;p&gt;This matters because AWS services with tiered pricing, including Data Transfer, Amazon S3, and Amazon EC2, calculate discounts based on total organizational usage rather than individual account usage. Your organization reaches higher discount tiers faster, and the savings apply automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Consolidated Billing Unlocks Volume Discounts
&lt;/h3&gt;

&lt;p&gt;Tiered pricing works in your favor when usage is aggregated. As your combined usage increases, the per-unit cost decreases across the entire organization.&lt;/p&gt;

&lt;p&gt;Here is a practical example: if you have 10 accounts each storing 5 TB in S3, consolidated billing treats that as 50 TB of total storage. That 50 TB hits a higher discount tier than any single 5 TB account would reach on its own. The &lt;a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/con-bill-blended-rates.html" rel="noopener noreferrer"&gt;blended rate&lt;/a&gt; distributes cost benefits across all member accounts automatically.&lt;/p&gt;

&lt;p&gt;The management account sees total usage and charges for all accounts, while member accounts see their individual (unblended) costs. One thing to note: the free tier applies to total usage across all accounts in the organization, not per account.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Cumulative Effect: Stacking Six Cost Strategies
&lt;/h3&gt;

&lt;p&gt;No single strategy delivers 20-40% savings on its own. The power comes from stacking them.&lt;/p&gt;

&lt;p&gt;Volume discounts provide the automatic foundation at 5-20%. Layer centralized Savings Plans on top for up to 72% off compute. Add SCPs to prevent wasteful spending before it happens. Share infrastructure to eliminate redundant networking costs. Monitor centrally to catch overruns early. Automate cleanup to recover the 10-15% of spend that typically goes to idle resources.&lt;/p&gt;

&lt;p&gt;Each strategy addresses a different cost lever. Together, they compound into multi-account cost savings of 20-40% that organizations consistently achieve. The rest of this guide walks through each one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Centralized Savings Plans and Reserved Instances (Up to 72% Off)
&lt;/h2&gt;

&lt;p&gt;Commitment-based discounts represent the single largest cost reduction lever in a multi-account setup. The discount levels are substantial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EC2 Instance Savings Plans&lt;/strong&gt;: Up to &lt;strong&gt;72% savings&lt;/strong&gt;, locked to a specific instance family in a region but flexible on size, OS, and tenancy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute Savings Plans&lt;/strong&gt;: Up to &lt;strong&gt;66% savings&lt;/strong&gt;, maximum flexibility across instance family, size, region, and also covers Fargate and Lambda&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard Reserved Instances&lt;/strong&gt;: Up to &lt;strong&gt;72% off&lt;/strong&gt; On-Demand pricing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Convertible Reserved Instances&lt;/strong&gt;: Up to &lt;strong&gt;66% off&lt;/strong&gt;, with the ability to exchange across instance families&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Savings Plans&lt;/strong&gt;: Up to &lt;strong&gt;35% off&lt;/strong&gt; various AWS database services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real advantage in a multi-account environment is that these discounts share across your entire organization automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cross-Account Discount Sharing: How It Works
&lt;/h3&gt;

&lt;p&gt;When using consolidated billing, &lt;a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/ri-turn-off.html" rel="noopener noreferrer"&gt;discount sharing is enabled by default&lt;/a&gt;. Savings Plans and Reserved Instances purchased by any member account automatically apply to other accounts' eligible usage.&lt;/p&gt;

&lt;p&gt;AWS provides &lt;a href="https://aws.amazon.com/blogs/aws-cloud-financial-management/control-your-aws-commitments-with-risp-group-sharing/" rel="noopener noreferrer"&gt;three sharing configurations&lt;/a&gt; to control how benefits distribute:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Organization-wide sharing&lt;/strong&gt;: Benefits the owning account first, then shares remaining benefits across all other accounts. Maximizes overall utilization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prioritized group sharing&lt;/strong&gt;: Uses AWS Cost Categories to define account groups that receive priority. Maximizes utilization within priority groups first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restricted group sharing&lt;/strong&gt;: Exclusively shares within defined account groups. Each account belongs to only one sharing group.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One important limitation: discounts only apply within a single AWS Organization. If you manage multiple Organizations, Savings Plans purchased in one cannot benefit accounts in another.&lt;/p&gt;

&lt;h3&gt;
  
  
  Centralized vs. Decentralized Purchasing
&lt;/h3&gt;

&lt;p&gt;This is where many organizations leave money on the table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Centralized purchasing&lt;/strong&gt; means the management account buys Savings Plans based on &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost_pricing_model_master_analysis.html" rel="noopener noreferrer"&gt;payer-level recommendations&lt;/a&gt; that analyze total eligible spend across all accounts. This approach maximizes overall savings because it sees the full picture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decentralized purchasing&lt;/strong&gt; lets each team buy for their own workloads. This preserves budget accountability but fragments your purchasing volume, often resulting in lower total savings.&lt;/p&gt;

&lt;p&gt;I recommend a &lt;strong&gt;hybrid approach&lt;/strong&gt;: centralized purchasing for stable baseline commitments that cover predictable organization-wide workloads, combined with decentralized purchasing for specialized or variable workloads where individual teams understand the patterns best.&lt;/p&gt;

&lt;p&gt;The common mistake is going fully decentralized. When each team buys independently, they miss cross-account sharing benefits and typically achieve &lt;strong&gt;10-15% lower utilization rates&lt;/strong&gt; compared to centralized purchasing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Group Sharing with AWS Cost Categories
&lt;/h3&gt;

&lt;p&gt;If you have distinct business units that need cost separation, group sharing lets you restrict benefits within defined boundaries.&lt;/p&gt;

&lt;p&gt;Configuration uses &lt;a href="https://aws.amazon.com/blogs/aws-cloud-financial-management/control-your-aws-commitments-with-risp-group-sharing/" rel="noopener noreferrer"&gt;AWS Cost Categories&lt;/a&gt; with the Accounts dimension. You define which accounts belong to which group, and sharing stays within those groups. The payer account is not part of any sharing group.&lt;/p&gt;

&lt;p&gt;This works well for organizations where business units operate as separate P&amp;amp;L centers and need clear cost attribution without cross-subsidy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Service Control Policies for Cost Governance
&lt;/h2&gt;

&lt;p&gt;Commitment-based discounts maximize savings on resources you need. But how do you prevent teams from launching resources you do not need? That is where Service Control Policies come in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html" rel="noopener noreferrer"&gt;SCPs&lt;/a&gt; define the maximum available permissions for IAM users and roles in member accounts. They restrict, they do not grant. Most organizations use them for security, but they are equally powerful as &lt;strong&gt;preventive cost controls&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The cost-specific use cases are compelling: restricting expensive instance types in non-production accounts, limiting resource creation to approved regions, blocking expensive services in sandbox environments, and enforcing cost allocation tags before resource creation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preventing Expensive Resource Launches
&lt;/h3&gt;

&lt;p&gt;The most immediate cost impact comes from blocking expensive resources where they are not needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Block GPU and metal instances in non-production OUs&lt;/strong&gt;: A single p4d.24xlarge instance costs over $32/hour. An SCP preventing its launch in dev/test accounts eliminates accidental bills that can reach thousands of dollars overnight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restrict services by OU&lt;/strong&gt;: Disable SageMaker, Redshift, or other expensive services in sandbox accounts where they are not needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce approved instance families&lt;/strong&gt;: Limit production to current-generation instance types (like Graviton-based instances) that offer better price-performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AWS recommends testing SCPs by &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost_govern_usage_controls.html" rel="noopener noreferrer"&gt;moving accounts into an OU one at a time&lt;/a&gt; to validate the effect before broad rollout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enforcing Region and Service Restrictions
&lt;/h3&gt;

&lt;p&gt;Limiting resource creation to 2-3 approved regions delivers a double benefit: it concentrates your usage volume for better discount tiers and reduces cross-region data transfer costs.&lt;/p&gt;

&lt;p&gt;Combine region restrictions with &lt;strong&gt;tag enforcement&lt;/strong&gt;. An SCP that &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost_govern_usage_policies.html" rel="noopener noreferrer"&gt;denies resource creation without required cost allocation tags&lt;/a&gt; ensures every resource can be tracked, attributed, and included in chargeback reporting.&lt;/p&gt;

&lt;p&gt;For ready-to-use policy templates, check out my collection of &lt;a href="https://towardsthecloud.com/blog/aws-scp-examples" rel="noopener noreferrer"&gt;production-ready SCP examples organized by OU&lt;/a&gt;. The cost governance policies in that guide complement the strategies covered here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared Infrastructure to Eliminate Redundant Costs
&lt;/h2&gt;

&lt;p&gt;SCPs prevent unnecessary spending. But you can also reduce legitimate infrastructure costs by sharing resources across accounts instead of duplicating them.&lt;/p&gt;

&lt;p&gt;Shared networking infrastructure is the biggest multi-account cost savings lever most organizations overlook. According to the &lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/framework/cost_type_size_number_resources_shared.html" rel="noopener noreferrer"&gt;Well-Architected Framework guidance on shared resources&lt;/a&gt;, centralized networking patterns can reduce costs by &lt;strong&gt;30-50%&lt;/strong&gt; compared to per-account deployments.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftowardsthecloud.com%2Fimages%2Fblog%2Faws-multi-account-cost-savings%2Fcentralized-egress-architecture.excalidraw" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftowardsthecloud.com%2Fimages%2Fblog%2Faws-multi-account-cost-savings%2Fcentralized-egress-architecture.excalidraw" alt="Centralized NAT Gateway architecture with Transit Gateway hub and spoke VPCs across multiple AWS accounts showing 90 percent cost reduction" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Centralized NAT Gateways
&lt;/h3&gt;

&lt;p&gt;This is the highest-impact shared infrastructure pattern, and the math is straightforward.&lt;/p&gt;

&lt;p&gt;A single NAT Gateway costs &lt;strong&gt;$0.045 per hour&lt;/strong&gt;. In a typical multi-account setup with 10 accounts and 3 Availability Zones, each account deploys its own NAT Gateways: 10 accounts x 3 AZs = &lt;strong&gt;30 NAT Gateways at $972/month&lt;/strong&gt; in hourly charges alone.&lt;/p&gt;

&lt;p&gt;Centralize those NAT Gateways in a dedicated egress VPC and route spoke VPC traffic through &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/building-scalable-secure-multi-vpc-network-infrastructure/using-nat-gateway-for-centralized-egress.html" rel="noopener noreferrer"&gt;Transit Gateway&lt;/a&gt;: 1 egress VPC x 3 AZs = &lt;strong&gt;3 NAT Gateways at $97/month&lt;/strong&gt;. That is roughly a &lt;strong&gt;90% reduction&lt;/strong&gt; in NAT Gateway hourly charges.&lt;/p&gt;

&lt;p&gt;A single NAT Gateway supports up to 5 Gbps (scalable to 100 Gbps) and 440,000 simultaneous connections, so capacity is rarely a concern. Keep same-AZ routing to minimize cross-AZ data transfer charges, and use security groups, blackhole routes, and NACLs for traffic control.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transit Gateway and Shared VPC Endpoints
&lt;/h3&gt;

&lt;p&gt;Beyond NAT Gateway consolidation, Transit Gateway replaces the exponential complexity of VPC peering meshes with a simple hub-and-spoke model. Instead of managing N-squared peering connections, you manage N attachments.&lt;/p&gt;

&lt;p&gt;Transit Gateway pricing includes &lt;strong&gt;$0.05/hour per attachment&lt;/strong&gt; and &lt;strong&gt;$0.02 per GB&lt;/strong&gt; of data processed. The new &lt;a href="https://aws.amazon.com/blogs/networking-and-content-delivery/introducing-flexible-cost-allocation-for-aws-transit-gateway/" rel="noopener noreferrer"&gt;Flexible Cost Allocation feature (2025)&lt;/a&gt; lets you automatically allocate Transit Gateway data processing charges to specific accounts, enabling receiver-pay models for shared networking.&lt;/p&gt;

&lt;p&gt;Shared VPC endpoints are another quick win. Each VPC endpoint costs approximately &lt;strong&gt;$0.01/hour per AZ&lt;/strong&gt;. Instead of every account provisioning its own endpoints for S3, DynamoDB, or other services, share endpoints from a central networking account using AWS Resource Access Manager (RAM).&lt;/p&gt;

&lt;h2&gt;
  
  
  Centralized Monitoring and Budgeting
&lt;/h2&gt;

&lt;p&gt;Sharing infrastructure reduces costs structurally. But to keep costs optimized over time, you need centralized monitoring and proactive budgeting across all accounts.&lt;/p&gt;

&lt;p&gt;Without organization-wide visibility, cost issues hide in individual accounts until the consolidated bill arrives. AWS provides several tools that work together to give you complete monitoring coverage from a single pane of glass.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Account Budget Hierarchy with AWS Budgets
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-managing-costs.html" rel="noopener noreferrer"&gt;AWS Budgets&lt;/a&gt; supports six budget types: cost, usage, RI utilization, RI coverage, Savings Plans utilization, and Savings Plans coverage. In a multi-account environment, you build a budget hierarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Organization-wide&lt;/strong&gt;: Aggregate spending cap across all accounts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OU-level&lt;/strong&gt;: Budget per business unit (Production OU, Development OU)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Account-level&lt;/strong&gt;: Individual team budgets within each OU&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configure &lt;strong&gt;SNS notifications at threshold levels&lt;/strong&gt; (80%, 100%, 120%) so teams get alerted before budgets are exceeded, not after. Budgets update up to three times daily, giving you near real-time visibility.&lt;/p&gt;

&lt;p&gt;For organizations with many accounts, you can &lt;a href="https://aws.amazon.com/blogs/aws-cloud-financial-management/automating-budget-management-across-multi-account-environments/" rel="noopener noreferrer"&gt;automate budget creation across accounts&lt;/a&gt; using Lambda, DynamoDB, and Systems Manager Parameter Store. This eliminates manual budget setup as new accounts are provisioned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost Optimization Hub for Organization-Wide Savings
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/cost-management/latest/userguide/cost-optimization-hub.html" rel="noopener noreferrer"&gt;Cost Optimization Hub&lt;/a&gt; is the aggregation layer that ties everything together. When enabled in the management account with Organizations integration, it consolidates &lt;strong&gt;over 15 recommendation types&lt;/strong&gt; across all accounts and regions into a single prioritized view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EC2 rightsizing and Graviton migration opportunities&lt;/li&gt;
&lt;li&gt;Idle resource detection (EC2, EBS, RDS, Lambda, NAT Gateways, ECS on Fargate)&lt;/li&gt;
&lt;li&gt;EBS volume type upgrades (gp2 to gp3, io1 to io2)&lt;/li&gt;
&lt;li&gt;Savings Plans and Reserved Instance recommendations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can designate a member account as &lt;strong&gt;delegated administrator&lt;/strong&gt;, allowing your FinOps team to access recommendations without management account credentials.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://aws.amazon.com/blogs/aws-cloud-financial-management/measuring-cloud-cost-efficiency-with-the-new-cost-efficiency-metric-by-aws/" rel="noopener noreferrer"&gt;Cost efficiency metric (2025)&lt;/a&gt; gives you a single benchmark score: &lt;strong&gt;(Potential monthly savings / Total optimizable spend) x 100&lt;/strong&gt;. It refreshes daily and supports analysis across accounts, regions, and organizational hierarchies, making it easy to compare efficiency between business units.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost Anomaly Detection for Proactive Alerts
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/cost-management/latest/userguide/getting-started-ad.html" rel="noopener noreferrer"&gt;AWS Cost Anomaly Detection&lt;/a&gt; uses machine learning to identify anomalous spend patterns across your organization. Configure monitors by AWS service, member account, Cost Category, or cost allocation tag to catch unexpected spending spikes before they become significant budget overruns.&lt;/p&gt;

&lt;p&gt;The strength of Cost Anomaly Detection in a multi-account setup is coverage. A single monitor configured at the organization level scans spend across all accounts continuously, surfacing anomalies that account-level monitoring would miss. Combine it with SNS notifications for immediate alerts and integrate with AWS Chatbot for Slack or Teams delivery.&lt;/p&gt;

&lt;p&gt;For organizations managing multiple AWS Organizations, the multi-source custom billing views feature (2025) provides a unified cost view across up to 20 separate Organizations from a single account, closing the visibility gap for complex enterprise structures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automated Cleanup of Idle Resources
&lt;/h2&gt;

&lt;p&gt;Monitoring identifies cost issues. But the most impactful action is automating the cleanup of resources that no longer serve a purpose.&lt;/p&gt;

&lt;p&gt;Industry research consistently shows that &lt;strong&gt;10-15% of total cloud spend&lt;/strong&gt; goes to idle or unused resources. In a multi-account environment, this waste multiplies because each account can accumulate forgotten proof-of-concept deployments, unattached volumes, and unused Elastic IPs independently.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Compute Optimizer Idle Recommendations
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/compute-optimizer/latest/ug/view-idle-recommendations.html" rel="noopener noreferrer"&gt;AWS Compute Optimizer&lt;/a&gt; detects idle resources using specific criteria per resource type:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource Type&lt;/th&gt;
&lt;th&gt;Idle Criteria&lt;/th&gt;
&lt;th&gt;Lookback Period&lt;/th&gt;
&lt;th&gt;Recommended Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EC2 Instances&lt;/td&gt;
&lt;td&gt;Peak CPU below 5% AND network I/O less than 5 MB/day&lt;/td&gt;
&lt;td&gt;14 days&lt;/td&gt;
&lt;td&gt;Delete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EBS Volumes&lt;/td&gt;
&lt;td&gt;Less than 1 read/write per day OR unattached 32+ days&lt;/td&gt;
&lt;td&gt;32 days&lt;/td&gt;
&lt;td&gt;Snapshot and delete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS on Fargate&lt;/td&gt;
&lt;td&gt;Peak CPU and memory below 1%&lt;/td&gt;
&lt;td&gt;14 days&lt;/td&gt;
&lt;td&gt;Delete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RDS Databases&lt;/td&gt;
&lt;td&gt;No connections, low CPU, low read/write&lt;/td&gt;
&lt;td&gt;14 days&lt;/td&gt;
&lt;td&gt;Stop or snapshot and delete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NAT Gateways&lt;/td&gt;
&lt;td&gt;No route table association, no active connections&lt;/td&gt;
&lt;td&gt;14 days&lt;/td&gt;
&lt;td&gt;Verify and delete&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Enable Compute Optimizer at the organization level for centralized visibility across all accounts. This surfaces idle resources that individual teams may not even know exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated EBS Volume Optimization
&lt;/h3&gt;

&lt;p&gt;This &lt;a href="https://aws.amazon.com/blogs/aws-cloud-financial-management/introducing-automated-amazon-ebs-volume-optimization-in-aws-compute-optimizer/" rel="noopener noreferrer"&gt;2025 feature&lt;/a&gt; is a significant advancement for multi-account environments. You can create automation rules that continuously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Snapshot and delete unattached volumes&lt;/strong&gt; older than 32 days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upgrade gp2 volumes to gp3&lt;/strong&gt; for better performance at lower cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A single automation rule operates globally across all AWS Regions. You can configure it to run daily, weekly, or monthly with filtering by region or resource tags.&lt;/p&gt;

&lt;p&gt;Here is why this matters financially: unattached EBS volumes cost the same as attached volumes. Deleting &lt;strong&gt;50 unused 100 GB gp3 volumes saves approximately $400/month&lt;/strong&gt; ($0.08/GB-month x 100 GB x 50 volumes). Unused Elastic IPs add &lt;strong&gt;$3.60/month each&lt;/strong&gt;. Idle EC2 t3.medium instances waste approximately &lt;strong&gt;$30/month each&lt;/strong&gt;. These small amounts compound fast across dozens of accounts.&lt;/p&gt;

&lt;p&gt;Safety mechanisms are built in: eligibility checks run before any action, snapshots are created before deletion, and all automated actions can be reversed through Compute Optimizer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices to Maximize Multi-Account Savings
&lt;/h2&gt;

&lt;p&gt;With the six core strategies in place, a few additional best practices help you extract maximum value from your multi-account setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enable Credit Sharing Across the Organization
&lt;/h3&gt;

&lt;p&gt;AWS credits (promotional, support, migration acceleration) are &lt;a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/useconsolidatedbilling-credits.html" rel="noopener noreferrer"&gt;shared across all member accounts&lt;/a&gt; by default in consolidated billing. Credits apply in this order: oldest credits expire first, then credits with the most eligible services apply first.&lt;/p&gt;

&lt;p&gt;The strategic insight here is tracking and governance. Designate a credit management team, create a centralized tracking dashboard in Cost Explorer, and set up automated alerts for expiration dates. AWS offers several credit programs worth leveraging: &lt;strong&gt;Migration Acceleration Program (MAP)&lt;/strong&gt;, Digital Innovation credits, and Cloud Economics programs. Without centralized tracking, credits often expire unused in individual accounts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement a Cost Allocation Tagging Strategy
&lt;/h3&gt;

&lt;p&gt;You cannot optimize what you cannot measure. A consistent &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/building-a-cost-allocation-strategy.html" rel="noopener noreferrer"&gt;tagging strategy&lt;/a&gt; makes cost allocation and chargeback possible across your organization.&lt;/p&gt;

&lt;p&gt;Start with four essential tags: &lt;strong&gt;CostCenter&lt;/strong&gt;, &lt;strong&gt;Environment&lt;/strong&gt; (prod/dev/test), &lt;strong&gt;Project&lt;/strong&gt;, and &lt;strong&gt;Owner&lt;/strong&gt;. The new &lt;a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/account-tags-cost-allocation.html" rel="noopener noreferrer"&gt;account tags feature (2025)&lt;/a&gt; simplifies this significantly. Apply tags at the account level, and all resources within that account automatically inherit the tag for cost allocation. This eliminates the need to tag thousands of individual resources and even covers resources that do not support resource-level tags.&lt;/p&gt;

&lt;p&gt;Enforce compliance with a three-layer approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tag policies&lt;/strong&gt; in AWS Organizations define acceptable tag values&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SCPs&lt;/strong&gt; deny resource creation without required cost allocation tags&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Config rules&lt;/strong&gt; detect and report non-compliant resources&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  View Recommendations at the Payer Account Level
&lt;/h3&gt;

&lt;p&gt;This is a best practice that many organizations miss. &lt;a href="https://aws.amazon.com/blogs/aws-cloud-financial-management/understanding-aws-savings-plan-recommendations-payer-vs-linked-account-views/" rel="noopener noreferrer"&gt;Payer-level recommendations&lt;/a&gt; analyze total eligible spend across all accounts and capture cross-account sharing benefits that linked-account recommendations miss entirely.&lt;/p&gt;

&lt;p&gt;Use the &lt;strong&gt;Savings Plans Purchase Analyzer&lt;/strong&gt; to compare different purchasing scenarios before committing. Choose your lookback period based on workload predictability: 7 days for volatile workloads, 30 days for stable workloads, 60 days for highly predictable patterns. Review and adjust monthly as your organization evolves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Multi-account architecture delivers &lt;strong&gt;20-40% AWS multi-account cost savings&lt;/strong&gt; through six complementary strategies that work at different layers of your infrastructure and operations.&lt;/p&gt;

&lt;p&gt;Start with the foundations: consolidated billing is automatic once you enable &lt;a href="https://towardsthecloud.com/blog/aws-organizations" rel="noopener noreferrer"&gt;AWS Organizations&lt;/a&gt;, and centralized Savings Plans offer the highest individual impact at up to 72% off compute. Then add preventive controls with SCPs and structural savings with shared infrastructure. Implement centralized monitoring with AWS Budgets and Cost Optimization Hub for ongoing visibility. Finally, automate idle resource cleanup to recover the 10-15% of spend that silently drains your budget.&lt;/p&gt;

&lt;p&gt;The key is that these strategies stack. Each one addresses a different cost lever, and the combined effect is what produces the 20-40% range. The exact savings depend on your organization's size, workload mix, and current optimization maturity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your next step&lt;/strong&gt;: If you have not already, enable AWS Organizations and consolidated billing. Then open Cost Explorer at the payer level, review the Savings Plans recommendations, and calculate how much you are leaving on the table. For deeper implementation guidance, check out the &lt;a href="https://towardsthecloud.com/blog/aws-multi-account-best-practices" rel="noopener noreferrer"&gt;AWS multi-account best practices&lt;/a&gt; and the broader &lt;a href="https://towardsthecloud.com/blog/aws-cost-optimization-best-practices" rel="noopener noreferrer"&gt;AWS cost optimization best practices&lt;/a&gt; guides.&lt;/p&gt;

&lt;p&gt;What cost savings strategies have worked best in your multi-account setup? I'd love to hear what you've implemented in the comments below.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Written by Danny, Founder @ &lt;a href="https://towardsthecloud.com" rel="noopener noreferrer"&gt;towardsthecloud&lt;/a&gt; → Helping startups cut costs and &lt;a href="https://towardsthecloud.com/services/aws-landing-zone" rel="noopener noreferrer"&gt;ship faster on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;FYI; I'm also building &lt;a href="https://cloudburn.io" rel="noopener noreferrer"&gt;cloudburn.io&lt;/a&gt; → Help developers catch expensive infra in PR's before they deploy on AWS Cloud.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>awsorganizations</category>
      <category>costoptimization</category>
      <category>multiaccount</category>
      <category>savingsplans</category>
    </item>
  </channel>
</rss>
