I Got Burned by AWS Security Once. Here's What I Actually Do Now.
Admin User
Author
Three years ago, I deployed a Postgres database to RDS with encryption disabled because the client wanted to "move fast." Two months later, during a routine audit, we discovered the database was publicly accessible on the internet. No one had accessed it yet—we were lucky. But that incident cost us two days of panic, an emergency security review, and a conversation with the client that I still remember vividly. I learned that day that security isn't something you bolt on after launch. It's the first decision you make, not the last.
Since then, I've deployed dozens of applications across AWS environments—some for startups, some for enterprises handling sensitive user data. Each deployment reinforced the same lesson: the basics matter infinitely more than the fancy stuff. You don't need to be a security expert to avoid the catastrophic mistakes that actually happen in production. You just need to follow practices that feel tedious at first but become second nature.
The Root Account Myth
Let me be direct: if you're still logging into the AWS console with your root credentials, you're making life unnecessarily dangerous for yourself. I see this constantly with small teams and solo founders. The thinking is always the same: "I'm the only person with access, so it's fine."
It's not fine. Your laptop can be compromised. Someone can social engineer your password. An old contractor can have access lingering in a shared team vault. The root account is a master key—keep it locked in a vault and throw away the combination for daily work.
I create an IAM user immediately after setting up any AWS account. Multi-factor authentication goes on before I even deploy my first resource. This takes maybe five minutes and prevents probably 80% of account compromise scenarios. The math is obvious, but people still skip it.
Least Privilege: The Practice That Actually Works
Here's where I disagree with myself from five years ago. I used to think fine-grained IAM policies were overkill for small projects. Now I know they're the opposite—they're the easiest mistake to prevent.
When I build a Lambda function that needs to read from one S3 bucket and write to CloudWatch, I write a policy that does exactly that. Not s3:* on all buckets. Not logs:*. Specific actions on specific resources. Yes, it takes longer. Yes, you need to reference the documentation. But I've caught my own mistakes this way—permissions that I thought existed but didn't, or permissions I granted that weren't actually needed.
This also makes incident response easier. If a Lambda function gets compromised, the blast radius is contained. It can't accidentally delete your entire RDS instance or spin up expensive instances you didn't authorize.
The Monitoring Part Everyone Skips
I'll be honest: setting up CloudTrail and GuardDuty feels bureaucratic. You're not shipping a feature. You're not solving a business problem. But I've used CloudTrail logs to debug production issues that would have been unsolvable otherwise. "Who deleted that security group?" "When did this policy change?" "What did that API call actually do?" CloudTrail answers these questions.
The real value isn't catching attackers—though it does that. The real value is visibility into what your infrastructure is actually doing. I've caught my own mistakes, my team's mistakes, and yes, once or twice, malicious behavior. Every time, I was grateful those logs existed.
My Actual Workflow
Here's what I actually do on every new AWS project:
- Root account gets locked down immediately (MFA, no access keys)
- IAM user created with MFA before anything else
- S3 buckets get default encryption enabled at creation time
- VPC defaults to private subnets; I explicitly create public ones only when needed
- Secrets go into Secrets Manager from the start, never in environment files
- CloudTrail and basic CloudWatch monitoring are part of my Terraform base template
The last point is crucial. I've built a small Terraform module that I reuse for every client. It sets up monitoring, encryption defaults, and basic security controls. This means I'm not making these decisions ad-hoc on each project—I'm using a consistent foundation that's already been through code review.
What I'd Do Differently
The original article mentions automation and Infrastructure as Code, which I agree with completely. But I'd push further: don't just automate security checks, embed them into your deployment pipeline. Fail the build if someone tries to deploy with public S3 access or unencrypted databases. Make security the path of least resistance, not an obstacle to overcome.
What About You?
What's the security practice that actually saved you in production? I'm always curious what catches people off-guard—is it the obvious stuff I've mentioned, or are there subtle misconfigurations that haunt you?
Source: This post was inspired by "AWS Security: 10 Essential Best Practices Every Cloud Engineer Should Implement" by Dev.to. Read the original article