AWS Account Setup
Securing a new AWS account. Root user hardening, MFA, billing alarms, CloudTrail, account contacts, and the settings that are painful to add later.
A new AWS account arrives with a root user, no guardrails, and a credit card attached. This page covers what to do in the first hour. The things that are quick now and awkward later.
The root user is the whole problem
When you create an account, you get a root user identified by the email address you signed up with. It has unconditional power over the account and cannot be restricted by any IAM policy or service control policy.
That makes it the highest-value credential in your organisation, and it should be treated accordingly.
Enable MFA immediately
Hardware MFA is the right choice for anything that matters. A physical security key kept where access is controlled. A virtual authenticator app is acceptable for personal or learning accounts, but it lives on someone's phone.
AWS now supports multiple MFA devices on root, which removes the old single-point-of-failure problem of one lost token locking you out. Register two.
Delete root access keys
There is no legitimate reason for root to have programmatic credentials. Check and remove them:
aws iam get-account-summary --query 'SummaryMap.AccountAccessKeysPresent'
A result of 1 means root access keys exist. Delete them from the security credentials page.
Use an address that outlives people
Sign up with a shared mailbox, aws-root@acme.com, not an individual's address. People leave, and recovering an account whose root email belongs to a former employee is genuinely difficult.
The same applies to the phone number used for account recovery.
Alert on root usage
Root should be used perhaps a handful of times ever. Any sign-in is worth knowing about, via CloudTrail and an EventBridge rule on ConsoleLogin where the user identity type is Root.
What genuinely needs root
Very little: closing the account, changing the account name or root email, changing the support plan, restoring an IAM policy that locked everyone out, and a small number of billing operations. Nothing in that list is daily work.
Set the account contacts
Frequently skipped and genuinely important. AWS uses these to reach you about security issues, billing problems and service events:
aws account put-alternate-contact \
--alternate-contact-type SECURITY \
--name "Security Team" \
--title "Security" \
--email-address security@acme.com \
--phone-number "+441234567890"
Set SECURITY, BILLING and OPERATIONS, each to a team address. A security notification sent to a personal mailbox that nobody reads is the same as no notification.
Billing guardrails before anything else
Create these before launching a single resource.
A budget with an alert, so overspend is a notification rather than a discovery:
aws budgets create-budget \
--account-id 111122223333 \
--budget '{"BudgetName":"monthly","BudgetLimit":{"Amount":"100","Unit":"USD"},"TimeUnit":"MONTHLY","BudgetType":"COST"}' \
--notifications-with-subscribers '[{
"Notification":{"NotificationType":"ACTUAL","ComparisonOperator":"GREATER_THAN","Threshold":80,"ThresholdType":"PERCENTAGE"},
"Subscribers":[{"SubscriptionType":"EMAIL","Address":"billing@acme.com"}]}]'
Set both an ACTUAL alert at 80% and a FORECASTED alert, since the forecast warns you mid-month rather than after the fact.
Cost Anomaly Detection needs no threshold tuning and catches the pattern budgets miss. A sudden change in one service while the total stays plausible.
Activate cost allocation tags in the billing console. Tags exist on resources from the moment you create them, but they do not appear in Cost Explorer until activated, and activation is not retroactive.
Enable IAM access to billing data, otherwise only root can see the billing console, which pushes people toward using root for routine work.
Understand the Free Tier honestly
Three different things share the name:
| Type | Duration |
|---|---|
| 12-month free | 12 months from signup: EC2 t2.micro/t3.micro hours, 30 GB EBS, 5 GB S3 |
| Always free | Perpetual: 1M Lambda requests/month, 25 GB DynamoDB |
| Trials | Short-term, service-specific |
The twelve-month ones expiring is a common source of a surprising thirteenth-month bill. Set a calendar reminder at month eleven.
Note also that Free Tier limits are per consolidated billing family, not per account, so additional accounts under one Organization do not multiply the allowance.
Turn on CloudTrail and GuardDuty
CloudTrail records every API call, and it cannot be applied retroactively. Events before it was enabled are simply not recorded.
Create a multi-Region trail delivering to S3. In an Organization, create an organisation trail from the management account and send logs to a separate security account, so someone who compromises a workload account cannot erase the evidence.
aws cloudtrail describe-trails --query 'trailList[].{Name:Name,MultiRegion:IsMultiRegionTrail}'
GuardDuty analyses CloudTrail, VPC flow logs and DNS logs for threats. It takes one click, costs little at low volume, and catches things nobody is watching for. Cryptomining on a compromised instance, credentials used from an unusual location, communication with known-malicious addresses.
Account-level defaults
Two settings that apply above individual resources:
# Block public S3 access for the whole account, overriding any bucket setting
aws s3control put-public-access-block \
--account-id 111122223333 \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
# Encrypt every new EBS volume. Note this is PER REGION
aws ec2 enable-ebs-encryption-by-default --region eu-west-1
EBS encryption by default must be set in every Region you use, which is easy to forget when expanding to a second one later.
Closing an account
Worth knowing before you need it. A closed account enters a 90-day post-closure period during which it can be reopened, after which it is permanently gone along with all its data.
Closing does not stop charges already incurred, and resources continue to be billed until they are actually deleted, so delete resources first, confirm the bill has settled, then close. In an Organization, an account must be removed from the Organization or closed from the management account.
Quick reference
| Task | Command |
|---|---|
| Who am I | aws sts get-caller-identity |
| Root keys present? | aws iam get-account-summary --query 'SummaryMap.AccountAccessKeysPresent' |
| Set a contact | aws account put-alternate-contact --alternate-contact-type SECURITY ... |
| Create a budget | aws budgets create-budget ... |
| CloudTrail status | aws cloudtrail describe-trails |
| Account S3 block | aws s3control put-public-access-block --account-id <id> ... |
| EBS encryption default | aws ec2 enable-ebs-encryption-by-default --region <r> |
| Current spend | aws ce get-cost-and-usage --time-period Start=<d>,End=<d> --granularity MONTHLY --metrics UnblendedCost |
Key takeaways
- Root cannot be restricted by any policy. Hardware MFA, no access keys, and use it almost never.
- Register two MFA devices on root now that multiple are supported.
- Use a shared mailbox for the root email, not an individual's.
- Set the SECURITY, BILLING and OPERATIONS alternate contacts to team addresses.
- Budget alerts before creating anything: both ACTUAL and FORECASTED.
- Cost allocation tags are not retroactive. Activate them on day one.
- CloudTrail cannot be applied retroactively either. Enable it multi-Region immediately.
- EBS encryption by default is per Region.
Check your understanding
Restricting the root user
Can a service control policy or IAM policy limit what the AWS root user can do in an account?
Tags missing from Cost Explorer
Resources have been tagged with Project since the account was created, but Cost Explorer shows no Project dimension. Why?
Frequently Asked Questions
What should I do first with a new AWS account?
Enable hardware MFA on the root user and delete any root access keys, since root cannot be restricted by any policy. Set a budget alert before creating resources. Enable CloudTrail across all Regions, because it does not record anything retroactively. Set the security, billing and operations alternate contacts to team addresses rather than an individual's. Then set up IAM Identity Center before creating any IAM users, which saves a migration later.
How do I secure the AWS root user?
Register two hardware MFA devices, now that AWS supports multiple. Delete any access keys. There is no legitimate programmatic use for root. Use a shared mailbox for the root email address and a phone number that is not an individual's, because recovering an account whose contact details belong to a former employee is genuinely painful. Set a CloudTrail and EventBridge alert on root sign-in, and use it only for the handful of tasks that require it.
How do I set up a billing alarm in AWS?
Create an AWS Budget with a notification, ideally two: an ACTUAL alert at around 80% of expected spend, and a FORECASTED alert so you hear about a problem mid-month rather than afterwards. Also enable Cost Anomaly Detection, which needs no threshold and catches a sudden change in one service even when the total looks plausible. Do both before creating resources. A guardrail added after the first surprise is too late for that surprise.
What does the AWS Free Tier actually include?
Three separate things. Twelve-month offers that expire a year after signup, including EC2 micro instance hours, 30 GB of EBS and 5 GB of S3. Always-free offers that never expire, such as a million Lambda requests a month and 25 GB of DynamoDB. And short trials for specific services. The twelve-month expiry is the common surprise, so set a reminder at month eleven. Note also that Free Tier applies per consolidated billing family, not per account.
Why can't my IAM users see the billing console?
Access to billing data is disabled for IAM principals by default and must be enabled by the root user in the account settings. Until then only root can view costs, which perversely encourages people to use root for routine work. Enable IAM access to billing information, then grant the relevant permissions through a policy so the people responsible for cost can actually see it without elevated access.
What happens when I close an AWS account?
It enters a 90-day post-closure period during which it can be reopened; after that it is permanently gone along with all data. Closing does not stop charges already incurred, and resources keep billing until they are genuinely deleted, so delete resources first, confirm the final bill has settled, then close. If the account belongs to an AWS Organization, close it from the management account or remove it from the Organization first.