Right, let’s talk about the part of this process that everyone loves to hate: environment variables. We’re going to set them up so you don’t have to type your credentials every single time you want to list an S3 bucket, which is, I assure you, a fate worse than death. Think of environment variables as the sticky notes you leave for your computer. “Hey computer, here’s my secret key. Don’t show it to anyone, and use it when I ask you to do AWS stuff.” It’s a simple, effective, and tragically easy-to-mess-up system.

The Absolute Bare Minimum You Need

To make the AWS CLI or any SDK stop yelling at you about missing credentials, you need to tell it two things: who you are and where you are. This translates to two key variables:

  • AWS_ACCESS_KEY_ID: Your public identifier. It’s like your username. Not super secret, but unique to you.
  • AWS_SECRET_ACCESS_KEY: This is the actual password. Guard this thing with your life. If it gets out, someone can run up a truly impressive bill on “EC2 instances for Bitcoin mining” and you’ll be left explaining it to your CFO.

There’s a third, often-forgotten variable that prevents a shocking amount of head-scratching:

  • AWS_DEFAULT_REGION: This tells the tools which geographical data center to talk to by default. us-east-1 is the classic, but set it to whatever makes sense for you. Not setting this is like telling a taxi driver “drive!” without saying where to go. They’ll just sit there and eventually error out.

Here’s how you set them in your terminal, right now. This is the “quick and dirty” method, perfect for a temporary shell session.

# On Linux/macOS
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=us-west-2

# On Windows Command Prompt (cmd.exe)
set AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
set AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
set AWS_DEFAULT_REGION=us-west-2

# On Windows PowerShell
$env:AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
$env:AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
$env:AWS_DEFAULT_REGION="us-west-2"

Run a quick aws sts get-caller-identity to confirm it worked. If it returns your account info, you’re in business.

Why This is Both Brilliant and Terrible

Setting variables like this is brilliantly simple for development. Your code doesn’t need to know anything; it just checks the environment. This is the magic behind “12-factor app” principles. It also lets you easily switch between different sets of credentials for different projects or roles without changing a line of code.

The terrible part is that these variables are scoped to your current shell session. Close the terminal? They’re gone. This is actually a security feature disguised as an annoyance. It means they’re not permanently written to disk somewhere. The real danger is when people stick these commands in their shell startup file (like .bashrc or .zshrc) and forget about them. Now every script you run, every terminal you open, has access to these powerful keys. It’s like leaving your house keys under the doormat with a sign that says “KEYS HERE.”

The Right Way: Use a Credentials File

For anything more permanent than a five-minute test, you should use the shared credentials file. The CLI and SDKs automatically look for this file, and it keeps your secrets out of your shell history and environment. Let’s set it up properly.

First, create the directory and file. The CLI would do this for you with aws configure, but we’re not animals; we’ll do it manually so you understand what’s happening.

mkdir -p ~/.aws
touch ~/.aws/credentials
touch ~/.aws/config

Now, edit ~/.aws/credentials. This file is where the sensitive credentials live. You can have multiple named profiles.

# ~/.aws/credentials
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

[my-project-dev]
aws_access_key_id = AKIAI44QH8DHBEXAMPLE
aws_secret_access_key = je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY

Next, edit ~/.aws/config. This file is for non-sensitive configuration, like the region and output format. Notice the different key names here—it’s region not aws_region. Because consistency is hard, apparently.

# ~/.aws/config
[default]
region = us-east-1
output = json

[profile my-project-dev]
region = eu-west-1
output = text

To use a profile other than default, simply set the AWS_PROFILE environment variable:

export AWS_PROFILE=my-project-dev
# Now any AWS command will use the credentials and settings from that profile

The Order of Operations (or, Why It’s Not Working)

This is the most important part. The AWS tools check for credentials in a very specific order, and the first one found wins. The order is:

  1. Command Line Options: (e.g., --region, --profile) Highest precedence.
  2. Environment Variables: (AWS_ACCESS_KEY_ID, etc.) Checked second.
  3. CLI Credentials File: (~/.aws/credentials) Checked third.
  4. CLI Config File: (~/.aws/config) For the region setting if not found elsewhere.
  5. Container Credentials: (For ECS tasks)
  6. Instance Profile Credentials: (For EC2 instances using IAM roles) Lowest precedence.

So if you’ve set AWS_ACCESS_KEY_ID in your environment but meant to use a profile from your credentials file, the environment variable wins and your profile is ignored. This hierarchy is your best friend when debugging “why won’t it use my credentials?!” issues. 99% of the time, you have a stray environment variable set that’s clobbering your intended configuration. Run env | grep AWS to check for them.

The Grand Finale: IAM Roles

Once you graduate from running things on your laptop, you will (I hope) stop using long-lived access keys altogether. The most secure way to handle credentials on AWS services like EC2, Lambda, or ECS is through IAM Roles. The SDKs and CLI automatically, and magically, retrieve temporary credentials from the instance metadata service without you lifting a finger. No environment variables to set, no credentials file to manage. It’s beautiful. If you’re on an EC2 instance with a role attached, you can literally just run aws s3 ls and it will work. This is the way.