Create an AWS Account
On this page, you will:
- Create a new AWS account
- Secure the root user with MFA
- Create your personal IAM user
- Create
AdminRole,DataEngineerRole, andInfrastructureAdminRolefor permissions - Set up cost-based alerts
- Configure AWS CLI for local development
Set Root User Email Alias
Consider setting up an email alias for your root account (e.g., aws-root@yourcompany.com) that forwards to multiple administrators. This ensures business continuity if the original account creator leaves.
You can change the root email at any time through Account Settings.
Create a New Account
Visit the AWS sign-up page and complete the registration process. You'll need to provide:
- Email address (this becomes the root account email)
- Account name (use your company/project name)
- Contact information
- Payment method (credit/debit card)
- Phone verification
About the Root User
The email you provide creates the root user - the most powerful account in AWS with unrestricted access to all services and billing. You should not use this account for day-to-day operations.
Store Credentials in 1Password
As you complete sign-up, immediately create a new entry in your 1Password vault for "AWS Root User". Store the email address and password securely. You'll add MFA details to this entry shortly. Make sure to store this in a Vault that has locked down access - you should only give root user access to a small handful of people.
Selecting Your Home Region
During the sign-up process and when first logging in, AWS will ask you to select a default region. Choose the region nearest to your data and that fulfils any data residency requirements.
Choosing a Region
Common choices for UK-based companies:
- eu-west-2 (London) - lowest latency for UK users, GDPR-compliant
- eu-west-1 (Ireland) - AWS's largest European region, more services available
- us-east-1 (N. Virginia) - AWS's original region, newest services launch here first
You can use services in any region, but your "home region" is where you'll primarily work. Learn more about AWS regions here.
Account Type: Personal vs Business
AWS offers two account types:
- Personal - for individual use, simpler verification
- Business - for company use, may require business verification documents
For a data stack project, either works. Business accounts provide some additional support options but aren't required to access any AWS services.
Secure the Root User
After creating your account, your first priority is securing the root user. You should never use the root account for daily operations.
Sign In as Root
- Go to the AWS Console
- Click "Sign in to the Console"
- Select "Root user"
- Enter your root account email address
- Enter the password you created during sign-up
Enable MFA on Root User
Multi-factor authentication (MFA) is critical for the root account. Enable it immediately:
- In the AWS Console, click your account name (top-right)
- Select "Security credentials"
- Scroll to "Multi-factor authentication (MFA)"
- Click "Assign MFA device"
- Choose your MFA type:
- 1Password (recommended) - stores both password and TOTP codes together
- Authenticator app - Google Authenticator, Authy, etc.
- Security key - hardware key like YubiKey
- Hardware TOTP token - physical device that generates codes
Using 1Password for MFA
1Password can generate TOTP codes directly. When setting up MFA:
- Select "Authenticator app" in AWS
- In 1Password, edit your "AWS Root User" entry
- Add a new field: One-time password
- Scan the QR code or enter the secret key
- 1Password will now generate codes for this account
This keeps your password and MFA codes together securely.
Store Recovery Codes
When setting up MFA, AWS provides recovery codes. Add these to your 1Password entry as a secure note or attachment. If you lose your MFA device and recovery codes, you cannot access your account.
When to Use the Root User
Only use the root account for tasks that specifically require it, such as:
- Changing account settings
- Restoring IAM user permissions
- Activating IAM access to billing
- Closing the account
For all other tasks, use IAM users or roles (which we'll create next).
Account alias
Your account can be referenced by both an ID and an alias. The name should be something human-readable and memorable, for example my-company-name.
To change the account alias, when logged in as the root user, open the IAM console at console.aws.amazon.com/iam. In the navigation pane, choose Dashboard. In the AWS Account section, next to Account Alias, choose Create. In the dialog box, enter the name you want to use for your alias, then choose Save changes.
Enable IAM Access to Billing
By default, IAM users cannot access billing information, even with admin permissions. Enable this so your admin users can manage costs:
- Still signed in as root, navigate to "Account" (top-right menu)
- Scroll to "IAM User and Role Access to Billing Information"
- Click "Edit"
- Check "Activate IAM Access"
- Click "Update"
This allows IAM users with appropriate permissions to view and manage billing.
Why This Matters
Without this enabled, only the root user can see costs and billing, which defeats the purpose of limiting root access. This is a one-time configuration that must be done by the root user.
Create IAM Roles for Access Control
AWS uses role-based access control (RBAC). Rather than granting permissions directly to users, you create roles with specific permissions and assign roles to users.
We'll create three roles:
- AdminRole - full administrative access (use sparingly)
- DataEngineerRole - permissions needed for data platform work
- InfrastructureAdminRole - permissions needed for managing infrastructure (use only for terraform apply)
Additional Roles
You will find that you may need to introduce new roles as you scale. We'll talk about better ways of managing roles in the terraform setup. This is just to get you started.
Create the AdminRole
- Navigate to IAM service (search "IAM" in the top search bar)
- Click "Roles" in the left sidebar
- Click "Create role"
- Select "AWS account" as the trusted entity type
- Select "This account" and note the account ID
- Click "Next"
- In the permissions policies search, type
AdministratorAccess - Check the box next to AdministratorAccess policy
- Click "Next"
- For role name, enter:
AdminRole - For description, enter:
Full administrative access for account administrators - Review the settings and click "Create role"
Create the DataEngineerRole
For the data engineer role, we'll use a managed policy that provides permissions for common data services:
- Return to IAM → Roles
- Click "Create role"
- Select "AWS account" as the trusted entity type
- Select "This account"
- Click "Next"
- Search for and select the following managed policies:
AmazonS3FullAccess- for data lake storageAmazonDynamoDBFullAccess- for Terraform state lockingSecretsManagerReadWrite- for managing credentialsCloudWatchFullAccess- for logging and monitoringIAMReadOnlyAccess- to view users and roles
- Click "Next"
- For role name, enter:
DataEngineerRole - For description, enter:
Permissions for data platform development and operations - Click "Create role"
Refining Permissions
These permissions are a starting point. As you build your data platform, you'll likely need to add more specific permissions for services. We'll address these as they become relevant in later sections.
Create the InfrastructureAdminRole
This role is specifically for Terraform and infrastructure operations. It has write access to Terraform state files, which DataEngineerRole intentionally lacks.
- Return to IAM → Roles
- Click "Create role"
- Select "AWS account" as the trusted entity type
- Select "This account"
- Click "Next"
- Search for and select the following managed policies:
AmazonS3FullAccess- for Terraform state and infrastructureAmazonDynamoDBFullAccess- for Terraform state lockingSecretsManagerReadWrite- for managing infrastructure secretsIAMFullAccess- for managing IAM resourcesCloudWatchFullAccess- for logging and monitoring
- Click "Next"
- For role name, enter:
InfrastructureAdminRole - For description, enter:
Role for Terraform infrastructure management - Click "Create role"
Why a Separate Infrastructure Role?
You might wonder why we need InfrastructureAdminRole when DataEngineerRole has similar permissions. The key difference is state file access:
- InfrastructureAdminRole: Full read/write to Terraform state files
- DataEngineerRole: Read-only access to state files (we'll configure this in Terraform setup)
This separation ensures data engineers can't accidentally run terraform apply locally - only the InfrastructureAdminRole (and later, the CI/CD pipeline) can modify infrastructure.
Configure Role Trust Relationships
Roles need to specify who can assume them. We'll configure both roles to allow users in this account:
- Click on AdminRole from the roles list
- Click the "Trust relationships" tab
- Click "Edit trust policy"
- The policy should look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT_ID:root"
},
"Action": "sts:AssumeRole"
}
]
}
- Replace
ACCOUNT_IDwith your actual AWS account ID (visible in the top-right corner) - Click "Update policy"
- Repeat these steps for DataEngineerRole and InfrastructureAdminRole
Create Your Personal IAM User
Now create an IAM user for yourself. This user will be able to assume both roles we created.
Create the User
- In IAM, click "Users" in the left sidebar
- Click "Create user"
- Enter username. Use a consistent format, such as:
firstname.lastname(e.g.,jane.bloggs)firstinitiallastname(e.g.,jbloggs)
- Click "Next"
- Do not attach any policies directly - we'll use role assumption instead
- Click "Next"
- Review and click "Create user"
Why No Direct Permissions?
By not attaching permissions directly to the user, we enforce the practice of assuming roles. This provides:
- Better audit trails (CloudTrail shows which role was used)
- Easier permission management (modify the role, not individual users)
- Principle of least privilege (only assume elevated permissions when needed)
Enable Console Access
- Click on your newly created user
- Click the "Security credentials" tab
- In "Console sign-in", click "Enable console access"
- Choose "Custom password" and create a secure password
- Uncheck "Users must create a new password at next sign-in" (optional)
- Click "Apply"
Store in 1Password
Create a new 1Password entry for "AWS IAM User - [your name]" in your personal Vault. Store:
- Account ID (for sign-in)
- Username
- Password
- You'll add MFA codes to this entry next
Enable MFA for Your User
You're still signed in as root and viewing the IAM user you just created — root can assign MFA to any IAM user directly from the user's profile page, without needing to sign in as that user first.
- Still on the IAM user's "Security credentials" tab, scroll to "Multi-factor authentication (MFA)"
- Click "Assign MFA device"
- Choose device name (e.g.,
jbloggs-phone) - Select your MFA type (1Password or authenticator app)
- If using 1Password, add a one-time password field to your IAM user entry and scan the QR code
- Follow the setup wizard
- Click "Add MFA"
MFA is Essential
Every IAM user should have MFA enabled, especially those with role assumption permissions. This is a critical security control.
Allow User to Assume Roles
We need to grant your user permission to assume the roles we created. In the later terraform section, we'll set this up programmatically, but for now, we'll simply add an in-line policy
- While viewing your user, click the "Permissions" tab
- Click "Add permissions" → "Create inline policy"
- Click the JSON tab
- Paste the following policy (replace
ACCOUNT_IDwith your account ID):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::ACCOUNT_ID:role/AdminRole",
"arn:aws:iam::ACCOUNT_ID:role/DataEngineerRole",
"arn:aws:iam::ACCOUNT_ID:role/InfrastructureAdminRole"
]
}
]
}
- Click "Next"
- For policy name, enter:
AssumeRolesPolicy - Click "Create policy"
Role Usage Guidelines
- DataEngineerRole: Use for day-to-day data platform work (queries, pipelines, monitoring)
- InfrastructureAdminRole: Use only when running Terraform locally during initial setup
- AdminRole: Use sparingly for account-level administration tasks
Test Console Access with Roles
- Sign out of the root account
- Go to the AWS Console
- Click "Sign in to the Console"
- Select "IAM user"
- Enter your account ID or account alias
- Enter your username and password
- Complete MFA challenge
You're now signed in as your IAM user. To assume a role:
- Click your username (top-right)
- Click "Switch role"
- Enter:
- Account: Your 12-digit account ID
- Role:
DataEngineerRole - Display Name:
DataEngineer(this is what appears in the top-right) - Colour: Choose a colour to distinguish this role
- Click "Switch Role"
The console now shows you're using the DataEngineerRole with the permissions attached to that role.
Switching Roles
Once you've switched to a role, AWS remembers it. You can quickly switch between your recent roles using the menu in the top-right corner.
Set Up Cost-Based Alerts
AWS can notify you when spending exceeds thresholds. This is critical to avoid unexpected bills.
Switch to AdminRole first
Budgets and billing preferences require billing permissions. Switch to AdminRole before continuing: click your username (top-right) → "Switch role" → enter AdminRole.
Create a Budget
- Navigate to AWS Budgets (search "Budgets" or go through Billing Dashboard)
- Click "Create budget"
- Select "Customise (advanced)"
- Choose "Cost budget"
- Click "Next"
- Configure budget details:
- Name:
Monthly-Cost-Budget - Period: Monthly
- Budget effective dates: Recurring budget
- Start month: Current month
- Budgeting method: Fixed
- Budget amount: Enter your monthly limit (e.g., £100)
- Name:
- Click "Next"
- Click "Add an alert threshold"
- Configure alert:
- Threshold: 80% of budgeted amount (adjust as needed)
- Trigger: Actual costs
- Email recipients: Your email address
- Optionally add more thresholds (e.g., 50%, 100%, 120%)
- Click "Next"
- Review and click "Create budget"
Free Tier Tracking
You can also create a budget specifically for Free Tier usage to track when you're approaching or exceeding free tier limits. This is particularly useful in the first 12 months of your AWS account.
Set Up Billing Alerts
In addition to budgets, enable billing alerts:
- Go to Billing Preferences (under your account menu → Billing Dashboard)
- Scroll to "Alert preferences"
- Check "Receive AWS Free Tier alerts"
- Check "Receive Billing Alerts"
- Enter your email address
- Click "Save preferences"
You'll receive an email when you approach free tier limits or exceed defined thresholds.
Configure AWS CLI Access
The AWS CLI allows you to interact with AWS services from your terminal. We'll configure it to use your IAM user credentials and support role assumption.
Install AWS CLI
On macOS (using Homebrew):
brew install awscli
Verify installation:
aws --version
# Expected output: aws-cli/2.x.x Python/3.x.x Darwin/23.x.x
Other Installation Methods
- Linux: AWS CLI Linux installation guide
- Windows: AWS CLI Windows installation guide
Create Access Keys
You need programmatic access credentials for the CLI:
- Sign in to AWS Console as your IAM user
- Go to IAM → Users → [your username]
- Click "Security credentials" tab
- Scroll to "Access keys"
- Click "Create access key"
- Select "Command Line Interface (CLI)"
- Check the confirmation box
- Click "Next"
- Optionally add a description tag (e.g.,
Local development - MacBook Pro) - Click "Create access key"
- Important: Copy the Access Key ID and Secret Access Key - you won't see the secret again
Store Access Keys in 1Password
Add the access keys to your "AWS IAM User" entry in 1Password:
- Add a field for "Access Key ID"
- Add a field for "Secret Access Key"
This provides a secure backup if you need to reconfigure the CLI later.
Protect Your Access Keys
Access keys are like passwords. Never commit them to Git, share them in Slack, or store them unencrypted.
Configure AWS CLI
Configure the CLI with your access keys:
aws configure --profile default
When prompted, enter:
AWS Access Key ID: [your access key]
AWS Secret Access Key: [your secret key]
Default region name: eu-west-2 # or your preferred region
Default output format: json
This creates ~/.aws/credentials and ~/.aws/config files with your configuration.
Configure Role Profiles
To easily switch between roles, add profiles to your AWS config. Edit ~/.aws/config:
code ~/.aws/config # or use your preferred editor
Add the following configurations (replace ACCOUNT_ID with your account ID):
[default]
region = eu-west-2
output = json
[profile data-engineer]
role_arn = arn:aws:iam::ACCOUNT_ID:role/DataEngineerRole
source_profile = default
region = eu-west-2
output = json
[profile infrastructure-admin]
role_arn = arn:aws:iam::ACCOUNT_ID:role/InfrastructureAdminRole
source_profile = default
region = eu-west-2
output = json
[profile admin]
role_arn = arn:aws:iam::ACCOUNT_ID:role/AdminRole
source_profile = default
region = eu-west-2
output = json
This configuration:
- Uses your IAM user credentials as the base (
defaultprofile) - Defines
data-engineerprofile that assumes the DataEngineerRole (day-to-day work) - Defines
infrastructure-adminprofile that assumes the InfrastructureAdminRole (Terraform operations) - Defines
adminprofile that assumes the AdminRole (account administration) - All role profiles use the default credentials to assume their respective roles
Test Your Configuration
Test the default profile (your IAM user with no role):
aws sts get-caller-identity
Expected output:
{
"UserId": "AIDAEXAMPLEUSERID",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/jane.bloggs"
}
Test the data-engineer profile:
aws sts get-caller-identity --profile data-engineer
Expected output:
{
"UserId": "AROAEXAMPLEROLEID:aws-cli-session",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/DataEngineerRole/aws-cli-session"
}
Notice the ARN shows you're using the assumed role, not your base user.
Set Default Profile
By default, AWS CLI uses the default profile. To use a different profile by default, set an environment variable:
# Use data-engineer role by default
export AWS_PROFILE=data-engineer
Add this to your shell configuration file (~/.zshrc) to persist:
echo 'export AWS_PROFILE=data-engineer' >> ~/.zshrc
source ~/.zshrc
Switch Between Profiles
To temporarily use a different profile for a single command:
# Use admin role for this command only
aws s3 ls --profile admin
# Use data-engineer role for this command only
aws s3 ls --profile data-engineer
# Use base user (no role) for this command only
aws s3 ls --profile default
Or change the environment variable:
# Switch to admin role for subsequent commands
export AWS_PROFILE=admin
# Verify
aws sts get-caller-identity
# Switch back to data-engineer
export AWS_PROFILE=data-engineer
Verify Your Role
Get in the habit of running aws sts get-caller-identity when switching roles to confirm you're using the intended credentials. This prevents accidentally making changes with the wrong permissions.
(Optional) Install and Configure aws-vault
For enhanced security, consider using aws-vault to manage AWS credentials. It stores credentials encrypted in your operating system's keychain and generates temporary session credentials.
Install aws-vault
On macOS:
brew install aws-vault
Configure aws-vault
Import your existing credentials:
aws-vault add default
When prompted, enter your Access Key ID and Secret Access Key. These are stored encrypted in your macOS Keychain.
You can now remove credentials from ~/.aws/credentials:
# Back up first
cp ~/.aws/credentials ~/.aws/credentials.backup
# Remove credentials (keep config)
rm ~/.aws/credentials
Use aws-vault
Execute commands with aws-vault:
# Using base IAM user
aws-vault exec default -- aws s3 ls
# Using data-engineer role
aws-vault exec data-engineer -- aws s3 ls
# Using admin role
aws-vault exec admin -- aws s3 ls
For interactive sessions:
# Start a shell with data-engineer credentials
aws-vault exec data-engineer
# All subsequent aws commands use those credentials
aws sts get-caller-identity
aws s3 ls
# Exit the session
exit
Why Use aws-vault?
Benefits of aws-vault:
- Credentials never stored in plaintext
- Automatic session token rotation
- MFA support for role assumption
- Prevents accidental credential exposure
- Better audit trail of credential usage
Configure aws-vault with Profiles
Your ~/.aws/config remains the same as before. aws-vault reads these profiles and uses the encrypted credentials from the Keychain.
Test your setup:
# Verify base user
aws-vault exec default -- aws sts get-caller-identity
# Verify data-engineer role
aws-vault exec data-engineer -- aws sts get-caller-identity
# Verify admin role
aws-vault exec admin -- aws sts get-caller-identity
# Verify infrastructure admin role
aws-vault exec infrastructure-admin -- aws sts get-caller-identity
Best Practices Summary
Security Checklist
- Root user secured with MFA and strong password
- Root user only used for tasks that require it
- IAM users have MFA enabled
- No permissions attached directly to users (use roles)
- Separate roles for different permission levels
- Access keys stored securely (aws-vault or password manager)
- Never commit credentials to version control
- Cost alerts configured to prevent surprise bills
- IAM user uses
DataEngineerRoleby default -
AdminRoleonly used when necessary -
InfrastructureAdminRoleused for Terraform state operations
What's Next
Success
You now have a secure AWS account with proper IAM configuration and CLI access!
Your next step is to configure Terraform to manage AWS infrastructure as code. This ensures all future resources are:
- Version controlled
- Reproducible
- Peer reviewed
- Documented
Continue to Set Up Terraform →