June 24, 2026
Learning AWS Day 1: Account Setup (and the Lockout I Caused Myself)
Infrastructure has always been the layer I let other people own. Someone else’s Terraform, someone else’s AWS console, while I stayed up in React and the occasional HonoJS route. I decided that was the gap I wanted to close, and the only way I know how to actually learn something is to do it for real instead of reading about it. So this is Day 1 of that, and it’s nothing as exciting as spinning up an EC2 instance or deploying a Lambda function. It’s just account setup, the kind of thing that doesn’t produce a URL you can show off. Even so, I still managed to lock myself out of my own user within the first hour.
Why start with the boring stuff
The obvious move is to skip straight to launching a server and deploying something. I get the appeal, that’s the fun part. But the reason account safety comes first is that AWS gives you two separate problems the moment you sign up: can someone (including future you, half asleep) accidentally rack up a huge bill, and can someone do real damage to the account. Billing alarms solve the first problem. IAM solves the second. Neither of those is glamorous, but skipping them is exactly how people end up with a $400 surprise invoice from a forgotten EC2 instance.
Setting up a billing alarm
A billing alarm is just a CloudWatch alarm that emails you when your estimated charges cross a threshold you set. I set mine at $1, not $50. The logic is that if the free tier is doing its job, my bill should sit at $0. The moment it crosses even a dollar, something is misconfigured somewhere, and I want to know immediately rather than finding out at the end of the month.
One thing that tripped me up: billing alarms only work in us-east-1, regardless of which region you’re actually working in. That’s not arbitrary, it’s because AWS’s billing and IAM systems are rooted in that region for historical reasons, it was the original AWS region before multi-region existed in its current form. So even though I have no intention of running anything in us-east-1, that’s where the alarm has to live.
I also hit the classic “the tutorial I’m following is out of date” wall here. Every guide I found told me to look for a “Receive Billing Alerts” checkbox under account settings. That checkbox doesn’t exist anymore. It’s now under Billing Preferences, under Alert preferences. Small thing, but a good reminder that AWS’s console UI drifts and screenshots age fast.
Getting rid of root as a daily driver
Root is the account tied to your signup email, and it has completely unrestricted access to everything. The standard advice is to basically never use it again after initial setup, which made sense in theory but felt slightly paranoid until I understood why: root is your break-glass account, the one you fall back to when everything else is broken. You don’t want to be casually logging in and out of it for daily work.
So I created an IAM user for myself instead, with AdministratorAccess attached for now. I know that’s not properly scoped yet, that’s a lesson for later once I understand what permissions I actually need day to day. I enabled MFA on both root and the new IAM user, and the reasoning for doing both stuck with me: root needs MFA because it’s the ultimate fallback, and if that’s compromised there’s no level above it to recover from. The IAM user needs MFA because that’s the account I’ll actually be using constantly, so it’s the more exposed surface day to day. I also made a note to save the IAM sign-in URL somewhere safe, since it’s a different URL from the standard AWS login page and not something I’d remember on my own.
The mistake: how I locked myself out
This is the part of Day 1 that actually taught me something, mostly because I caused it myself.
The best practice in AWS is that permissions policies attach to groups, and users join those groups, rather than attaching policies directly to individual users. It keeps permissions manageable as your team grows. So I created a group called Developers, attached AdministratorAccess to it, and then went back to my IAM user to remove the AdministratorAccess policy that was directly attached there, assuming I’d already added myself to the group and the group attachment was covering me.
I had not added myself to the group.
The second I removed the direct policy, my IAM user had zero permissions attached anywhere. None. The console response to this is genuinely unsettling the first time you see it: I tried to even just view my own user details and got an access denied error along the lines of “you don’t have permission to perform iam:GetUser, no identity-based policy allows this action.” Not “limited access.” Not “contact your administrator.” My own admin account, the one I’d just set up an hour earlier, couldn’t even look at itself.
The fix was straightforward once I knew what had actually happened: I logged out, logged back in as root, navigated to the Developers group, confirmed exactly what I suspected, my user was never a member, added myself, and logged back in as the IAM user. Access restored, no real damage done, but it was a genuinely uncomfortable few minutes before I figured out the cause.
The lesson here is bigger than IAM specifically. Before you remove an existing permission or access path, verify the replacement is actually active first, don’t assume it is. That principle shows up everywhere outside of AWS too: don’t tear down the old DNS record until you’ve confirmed the new one resolves, don’t kill the old deploy until the new one is verified healthy. Removing the safety net before testing the new one is how a routine cleanup becomes an incident.
AWS CLI setup, and a moment of paranoia about my work account
After sorting out IAM, I moved on to setting up the AWS CLI locally. I already had a separate AWS account configured through my employer using SSO via IAM Identity Center, and running aws configure made me nervous for a second, I didn’t want to accidentally overwrite that setup just to play around with a personal learning account.
It turned out there was no actual collision risk, but only because the two mechanisms store things differently. SSO-based profiles live in ~/.aws/config under named profile blocks. Running plain aws configure with no flags writes to ~/.aws/credentials under the [default] profile. Different files, different default targets. In my case that meant no overlap, but I wouldn’t want to rely on that holding true for everyone, so the actual takeaway is to check first:
# Checking existing AWS config before assuming a clean slate
cat ~/.aws/config
cat ~/.aws/credentials
Rather than touch default at all, I set up a separate named profile for this:
# Configuring a named profile instead of overwriting default
aws configure --profile personal-learning
# Using the named profile without typing --profile every time
export AWS_PROFILE=personal-learning
And to confirm I was actually authenticated as the right identity before doing anything else:
# Checking current AWS CLI identity (used to verify which account/user you're on)
aws sts get-caller-identity
Even without the work-account collision risk turning out to be real, I’d keep doing this. Having multiple AWS accounts configured on one machine is increasingly normal, and a named profile costs nothing extra to set up.
Closing
Day 1 produced absolutely nothing visible. No server running, no app deployed, nothing I could screenshot and call progress in the usual sense. But locking myself out of my own account and having to recover through root taught me more about how IAM actually works than a clean, mistake-free walkthrough would have. I understand groups versus direct policy attachment now in a way I wouldn’t if everything had just worked the first time.
Day 2 is EC2, SSH, and actually deploying a real FastAPI app behind a security group. If you’ve got your own AWS Day 1 disaster story, I’d genuinely like to hear it in the comments, I have a feeling mine isn’t unique.