AlgoInsight

Free lesson · Developer on AWS

Your first production-grade AWS account setup

Easy11 min readawscloudbackend

The Gap Nobody Tells You About

You can create an AWS account in about four minutes. What you have at the end of those four minutes is a root user, a credit card on file, and the ability to do enormous damage to both.

The gap between "I have an account" and "I can build real things here safely" is about an hour of setup, and almost nobody does it - because the console lets you start immediately and everything appears to work.

The three ways that ends badly are entirely predictable:

This topic is that hour. It applies whether this is a personal learning account, a startup's first account, or the account you inherited from someone who left.

Note: Course 2 builds on Course 1 rather than repeating it. Course 1 Module 01 Topic 7 covers multi-account architecture at organisational scale, and Module 02 covers IAM comprehensively. This topic is the developer-facing subset: what you personally need in place before you write code. Where a topic there goes deeper, it is linked.


Root: Secure It, Then Never Use It

The root user is the identity that owns the account. It is not an administrator - it is above administration.

What makes it different from every other identity:

graph TD
    R[Root user] --> S1[Set a long unique password<br/>in a password manager]
    R --> S2[**Enable MFA** - hardware key<br/>preferred, TOTP acceptable]
    R --> S3[**Delete any root access keys**]
    R --> S4[Secure the account email:<br/>MFA on the mailbox, a distribution<br/>list rather than a person]
    R --> S5[Set alternate contacts:<br/>billing, operations, security]
    S1 --> N[Then: **never sign in as root**<br/>except for the handful of tasks<br/>that require it]
    S2 --> N
    S3 --> N
    S4 --> N
    S5 --> N
This diagram shows the root user hardening steps. Set a long unique password stored in a password manager. Enable multi-factor authentication, preferring a hardware key over a time-based one-time password app. Delete any root access keys that exist. Secure the account email address with multi-factor authentication on the mailbox, using a distribution list rather than an individual's address. Set the alternate contacts for billing, operations, and security. After that, never sign in as root except for the small number of tasks that genuinely require it.

Warning: Root access keys should not exist, and if they do, delete them today. An access key for the root user is a long-lived credential with unrestricted, unrestrictable power over the account. There is no legitimate use for one - every task that can be automated can be automated with a role.

Check for them explicitly rather than assuming. Accounts created years ago, or by someone following an old tutorial, frequently have one sitting in a ~/.aws/credentials file that has been copied between three laptops.

The account email deserves more thought than it usually gets. It is the recovery path for everything. If it is one person's individual address, the account becomes unrecoverable when they leave. Use a distribution list or shared mailbox that more than one person can reach, with MFA on the mailbox itself - an attacker who controls the email can initiate a password reset.

The tasks that genuinely require root are few: closing the account, changing the account name or email, changing the payment method, restoring an IAM policy that locked everyone out, enabling certain organisation-level features, and a small number of service-specific operations. Everything else has a better path.


Do Not Create IAM Users - Not Even For Yourself

The instinct after securing root is to create an IAM user with administrator access and use that. This is the wrong move, and it is the most common mistake in this topic.

An IAM user means a long-lived access key. A long-lived access key means a credential that:

Important: Use IAM Identity Center instead, even if you are the only person who will ever use this account. It is free, it takes about fifteen minutes to set up, and it gives you temporary credentials that expire rather than a permanent key.

The objection is always that it is overkill for one person. It is not, for two reasons. First, the credential hygiene benefit applies to one person exactly as much as to fifty - your laptop is as losable as anyone's. Second, the moment a second person needs access, you either do this then or you send them a key, and the second option is what actually happens under time pressure.

Set it up before you need it, while it is a fifteen-minute task rather than a migration.

The setup, in order:

  1. Enable AWS Organizations if it is not already - it is free, and Identity Center requires it.
  2. Enable IAM Identity Center in your chosen Region.
  3. Create a user for yourself in the Identity Center directory, with MFA enforced.
  4. Create a permission set - start with a broad one for a personal account, scoped properly for anything shared.
  5. Assign the user to the account with that permission set.
  6. Configure the CLI: aws configure sso, which walks through it and writes a named profile.

You now sign in through a portal, get credentials that expire, and refresh with aws sso login.


Profile Hygiene

Once you have more than one account - and you will - the profile you have active is the difference between deploying to development and deploying to production.

Name profiles unambiguously. dev and prod are fine; default is dangerous, because it is what you get when you forget to specify anything.

Tip: Do not configure a default profile at all. With no default, a command that omits --profile fails with a credentials error rather than succeeding against whatever was configured. That failure is a two-second annoyance; the alternative is running a destructive command against the wrong account and finding out afterwards.

Pair it with a shell prompt that displays the active AWS_PROFILE. Both together mean the account you are operating on is always visible and never assumed, and the habit costs nothing once established.

Environment variables override profiles, which is the subject of Topic 2 and the source of a specific recurring confusion: a stale AWS_ACCESS_KEY_ID in your environment silently overrides the profile you carefully specified.


Cost Guardrails On Day One

Not after the first surprise. Before you launch anything.

Control Set it to
A cost budget with alerts at 50%, 80%, and 100% An amount that would concern you
A forecasted alert Fires before you get there, not after
Cost Anomaly Detection Catches a pattern change within a budget
Billing alerts enabled in account preferences Required for some of the above
IAM access to billing data Off by default for non-root; enable it

Warning: The free tier is not a spending limit. It is a set of allowances, and exceeding them generates charges with no interruption and no confirmation. Several common learning activities - a NAT Gateway, an idle RDS instance, an unattached Elastic IP, a Redshift cluster - are not free tier at all and bill from the first hour.

Three categories exist and they behave differently: 12-month free tier (expires a year after account creation), always free (permanent, within limits), and short-term trials. An account approaching its first anniversary can see charges appear for services that were free yesterday, with no change in usage.

A budget with an alert at a low absolute number is the control that actually protects you, because it does not depend on you understanding which tier anything falls into.

For a sandbox or learning account specifically, budget actions are appropriate: a budget that applies a restrictive policy at 100% means a forgotten GPU instance cannot run for a month. Course 1 Module 13 Topic 2 covers why this is right for sandboxes and wrong for production.


Audit And Visibility

CloudTrail Event history is on automatically and gives you 90 days of management events - enough to answer "what did I do last week," not enough to be an audit trail.

Create a trail delivering to S3 if this account will hold anything real. Course 1 Module 08 Topic 8 covers the full configuration; the developer-relevant minimum is: all Regions, delivered to a bucket, log file validation enabled.

Enable GuardDuty. It is inexpensive in a low-activity account, and it is the thing that tells you your credentials are being used from somewhere unexpected. For a personal account this is the single highest-value security service to enable, and it takes one click.


Region Discipline

Pick a Region and stay in it unless you have a reason not to.

Why it matters more than it seems: the console's Region selector is per-service and easy to change accidentally. Resources created in a Region you do not normally use are invisible in your normal view, and they bill anyway. Every estate that has been running for a while has something in us-east-1 that nobody remembers creating.

An SCP restricting aws:RequestedRegion is the clean answer once you have Organizations - Course 1 Module 02 Topic 8 covers the exemption list you need for global services. For a single account without one, the discipline is manual: check the Region indicator, and periodically audit for resources outside your intended Regions.

Note that some things are pinned to us-east-1 regardless: CloudFront certificates, some billing operations, and a few global service endpoints. That is expected and not a failure of discipline.


One Account Or Several?

Course 1 Module 01 Topic 7 makes the organisational case. The developer-relevant version is simpler.

Two accounts minimum for anything real: development and production. The argument is not primarily security - it is that an account is the only boundary that cannot be misconfigured around. A typo in a resource name deploys to the wrong environment; a typo cannot cross an account boundary, because the credentials are different.

It also gives you clean cost attribution with no tagging discipline required, and a blast radius for anything that goes wrong.

Organizations is free. The cost of the second account is the setup time, and Identity Center means you access both from one sign-in with different permission sets.

For pure learning, one account is fine - but be deliberate about that being the decision rather than the default.


Fixing An Account You Inherited

The realistic case: the account already exists and its setup is unknown.

The audit, in priority order:

  1. Root user - MFA enabled? Access keys present? Who controls the email?
  2. IAM users with access keys - how many, how old, who owns them, are they used? Check last-used dates.
  3. Users with AdministratorAccess - how many, and do they need it?
  4. MFA coverage on every human identity.
  5. Public S3 buckets and security groups open to 0.0.0.0/0.
  6. Running resources you cannot account for, in every Region.
  7. Budget and alerts - do any exist?
  8. CloudTrail - is there a trail, or only Event history?

The remediation order is the same as the audit order, and the first three are the ones that matter most. An old access key belonging to someone who left two years ago is a live credential with whatever permissions it had.


Common Failure Modes

Warning: Root access keys existing. No legitimate use, unrestricted power.

No MFA on root, or MFA tied to a device nobody has any more.

Account email is one person's address. Unrecoverable when they leave.

IAM user with admin access as the daily identity. Long-lived key.

A default profile configured. Commands succeed against the wrong account.

Access keys in dotfiles, copied between machines.

No budget. The first signal is the invoice.

Free tier assumed to be a spending limit.

Resources in Regions you do not use. Invisible and billing.

One account for development and production. No boundary that cannot be misconfigured around.

Identity Center deferred because "it is just me." It is a fifteen-minute task now and a migration later.

GuardDuty not enabled. The cheapest early warning available.


Why This Matters In An Interview

Interview: Account setup questions appear in interviews as security judgement questions, and the answers reveal whether someone has operated an account or only used one.

What interviewers are listening for:

  • Root secured and unused, with the reason it is different from an admin.
  • Identity Center over IAM users, with the temporary-credentials argument.
  • Cost controls as day-one setup rather than a reaction.
  • The account boundary as the strongest isolation available.

Common follow-ups:

  • "You have just been given a new AWS account. What do you do first?" → Secure root - MFA, delete any keys, check the email is a shared mailbox. Then Identity Center rather than an IAM user. Then a budget with a forecasted alert. Then CloudTrail and GuardDuty. In that order, because the first two are irreversible if compromised.
  • "Why not just use an IAM user for yourself?" → Long-lived credentials that never expire, get copied between machines, and survive you leaving. Identity Center gives temporary credentials, is free, and takes fifteen minutes.
  • "You found an access key belonging to someone who left. What now?" → Check its last-used date and what it can do, deactivate rather than delete first so you preserve evidence and can reverse if something breaks, find what was using it, then delete. Course 1 Module 10 Topic 12 covers the compromise case.
  • "How do you stop a developer accidentally deploying to production?" → Separate accounts. Everything else - naming conventions, confirmation prompts, careful profiles - is a mitigation that a tired person defeats.

Practice

Exercise: Starter. Audit your own AWS account against the eight-point inherited-account checklist. Fix anything in the first three items today.

Intermediate. Set up IAM Identity Center with a permission set for yourself, configure the CLI with aws configure sso, and remove any IAM user access keys you were previously using.

Advanced. Create a second account under Organizations for development, assign yourself to both with different permission sets, and configure named profiles with no default. Verify that a command without --profile fails rather than picking one.


Related Topics

Back to Developer on AWS