Configure and Switch Between Multiple AWS CLI Profiles

Package aws-cli/2.37.3
AWS Region ap-south-1 for the examples. Shared config and credential files are machine-specific; IAM is global within an AWS account
Lab environment Workstation with AWS CLI v2 and configured credentials — AWS CLI tutorial
Install AWS CLI on Ubuntu · Install AWS CLI on Debian
Privilege Permission to create IAM users, access keys, and roles when following the setup examples; read access to local ~/.aws/ files for day-to-day switching
Scope Configure multiple AWS CLI named profiles, switch between AWS accounts with --profile or AWS_PROFILE, verify the active account or role using aws sts get-caller-identity, and troubleshoot profile and credential precedence. Includes IAM user, assumed-role, and brief SSO examples. Does not cover missing credentials or invalid keys — see Unable to locate credentials and InvalidClientTokenId.
Related guides AWS CLI Tutorial
Which credentials AWS CLI uses
Unable to locate credentials
Fix Terraform AWS credentials error
AWS Tutorial
Short on time?Beta Get the gist of this 14-minute read in seconds, then ask follow-up questions

If you work with multiple AWS accounts, you do not need to run aws configure again every time you switch accounts. AWS CLI named profiles keep separate configuration for environments such as dev and prod, then let you choose the one you want with --profile or AWS_PROFILE.

The important part is verifying which identity the CLI actually selected before a command touches production. Every profile switch in this guide is checked with aws sts get-caller-identity, which shows the active AWS account and IAM user or role.


Quick Answer: Switch Between AWS CLI Profiles

Create a separate named profile for each AWS account, role, or authentication setup you need to select. In this example, dev and prod point at two different AWS accounts.

Create the profiles:

bash
aws configure --profile dev

Add a second profile for the production account:

bash
aws configure --profile prod

Use one profile for one command:

bash
aws sts get-caller-identity --profile prod

Or make it the profile for this shell:

bash
export AWS_PROFILE=prod

Confirm the active account before running anything destructive:

bash
aws sts get-caller-identity
Goal Command or setting
List profile names aws configure list-profiles
One command with a named profile aws sts get-caller-identity --profile prod
Default profile for the shell session export AWS_PROFILE=prod
When both are set --profile on the command wins over AWS_PROFILE
When using AWS_PROFILE Explicit credential environment variables can override credentials stored in that profile
When using --profile name The explicitly selected profile is used for that command
Confirm active identity aws sts get-caller-identity (same flags and env as the next command)

The sections below show where profiles are stored, how SSO and role profiles work, and how to avoid credential conflicts when switching accounts.


Create Multiple AWS CLI Profiles

Create dev and prod profiles

For access-key-based profiles, AWS CLI commonly stores credentials and configuration in two shared files:

File Typical contents
~/.aws/credentials (or AWS_SHARED_CREDENTIALS_FILE) aws_access_key_id, aws_secret_access_key, optional aws_session_token
~/.aws/config (or AWS_CONFIG_FILE) region, output, SSO settings, role_arn, source_profile

This layout applies to the access-key example below. SSO and role-based profiles work differently and may not store long-lived credentials in ~/.aws/credentials.

Profile sections use different syntax in each file:

  • Credentials file: [profile-name] without a profile prefix
  • Config file: [profile profile-name] with the profile prefix (except [default])
NOTE
The examples below use access keys because they make profile files and precedence easy to demonstrate. For regular workforce access, AWS recommends short-term credentials such as IAM Identity Center or aws login instead of long-lived IAM user access keys. Named profiles work with those authentication methods as well.

Create a profile interactively for the dev account:

bash
aws configure --profile dev

The prompts look like this:

text
AWS Access Key ID [None]: ...
AWS Secret Access Key [None]: ...
Default region name [None]: ap-south-1
Default output format [None]: json

aws configure is asking for credentials and defaults for this named profile. The access key ID identifies the AWS credential being used, while the secret access key is used to cryptographically sign API requests. Together, they authenticate the IAM user associated with those credentials. The Region becomes the default for regional AWS services unless you override it on a command. json controls how AWS CLI displays command output; it does not affect authentication or which account is selected.

Repeat for production:

bash
aws configure --profile prod

The access key and secret go into the credentials file; Region and output format go into the config file under [profile dev] and [profile prod].

Where AWS stores named profiles

List every profile name the CLI can see:

bash
aws configure list-profiles
output
dev
prod
audit

A multi-account layout looks like this (secrets replaced with placeholders):

text
--- ~/.aws/credentials ---
[dev]
aws_access_key_id = AKIADEVKEYEXAMPLE
aws_secret_access_key = ***

[prod]
aws_access_key_id = AKIAPRODKEYEXAMPLE
aws_secret_access_key = ***

--- ~/.aws/config ---
[profile dev]
region = ap-south-1
output = json

[profile prod]
region = ap-south-1
output = json

[profile audit]
region = ap-south-1
output = json
role_arn = arn:aws:iam::222222222222:role/audit-readonly
source_profile = prod

Never commit AWS credential files to source control. If ~/.aws/credentials contains long-lived access keys, ensure the file is readable only by your user, for example with chmod 600 ~/.aws/credentials. Prefer short-term credentials instead of storing long-lived access keys when possible.

Optional: use an SSO profile

A named profile does not have to contain long-lived access keys. It can also point to an IAM Identity Center configuration:

bash
aws configure sso --profile prod-sso

Sign in through the browser flow:

bash
aws sso login --profile prod-sso

Confirm the SSO session with the same profile name:

bash
aws sts get-caller-identity --profile prod-sso

Here, prod-sso is just another named profile. The difference is how it obtains credentials: through IAM Identity Center rather than access keys stored in ~/.aws/credentials. Once authenticated, switch and verify SSO profiles with the same --profile or AWS_PROFILE techniques used elsewhere in this guide.


Use a Profile for One AWS CLI Command

Pass --profile when a single command should use a named profile without changing the shell default:

bash
aws sts get-caller-identity --profile prod
output
{
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Account": "222222222222",
    "Arn": "arn:aws:iam::222222222222:user/prod-admin"
}

Inspect what that one invocation loads:

bash
aws configure list --profile prod
output
NAME       : VALUE                    : TYPE             : LOCATION
profile    : prod                     : manual           : --profile
access_key : ****************5TGM     : shared-credentials-file :
secret_key : ****************Iwdx     : shared-credentials-file :
region     : ap-south-1               : config-file      : ~/.aws/config

The LOCATION column confirms keys came from the shared credentials file, not from exported environment variables. --profile is usually safer for scripts and one-off administrative commands because the intended profile is visible directly in the command instead of depending on the shell's current environment.


Switch the AWS Profile for Your Shell

Export AWS_PROFILE when every command in the session should share one profile:

bash
export AWS_PROFILE=prod

Confirm the shell picked it up:

bash
aws sts get-caller-identity
output
{
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Account": "222222222222",
    "Arn": "arn:aws:iam::222222222222:user/prod-admin"
}

The configure list output shows where each value was resolved:

bash
aws configure list
output
NAME       : VALUE                    : TYPE             : LOCATION
profile    : prod                     : env              : ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE']
access_key : ****************5TGM     : shared-credentials-file :
secret_key : ****************Iwdx     : shared-credentials-file :
region     : ap-south-1               : config-file      : ~/.aws/config

Here, AWS_PROFILE selects prod, while the access key still comes from ~/.aws/credentials. The TYPE and LOCATION columns make it easy to see where each value came from.

To return to the implicit default profile:

bash
unset AWS_PROFILE AWS_DEFAULT_PROFILE

Add AWS_PROFILE to .bashrc, .zshrc, or another shell startup file only if you really want that profile selected every time you open a shell. On machines used with several AWS accounts, setting it manually is safer because the active account is less likely to be forgotten.


Check Which AWS Profile and Account Are Active

Three checks answer different questions:

Command What it tells you
echo "$AWS_PROFILE" Which profile name the shell selected through AWS_PROFILE
aws configure list Where AWS CLI resolved the profile, credentials, and Region
aws sts get-caller-identity Which AWS identity actually authenticated the API request

Show the profile name the environment variable selected:

bash
echo "$AWS_PROFILE"
output
prod

echo "$AWS_PROFILE" shows only the profile name selected through that environment variable. It does not prove which AWS identity will sign the next request.

Inspect how the CLI resolved settings:

bash
aws configure list

Read the TYPE and LOCATION columns for the access_key and secret_key rows. If the credential source shows env, exported environment variables are supplying the credentials even though the profile row says prod.

To verify which IAM user or role is authenticating the request:

bash
aws sts get-caller-identity
output
{
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Account": "222222222222",
    "Arn": "arn:aws:iam::222222222222:user/prod-admin"
}

$AWS_PROFILE tells you which profile name was selected through the environment. get-caller-identity verifies the AWS account and IAM user or role that authenticated the request. Run it with the same --profile, AWS_PROFILE, and AWS_* environment variables as the command that follows — especially before terraform apply, aws s3 rm, or other destructive work.

To compare dev and prod in one shell, clear overrides first:

bash
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILE

Switch to dev and verify the account ID changes:

bash
export AWS_PROFILE=dev

The response should show the dev account:

bash
aws sts get-caller-identity
output
{
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Account": "111111111111",
    "Arn": "arn:aws:iam::111111111111:user/dev-admin"
}

Switch to prod and verify again:

bash
export AWS_PROFILE=prod

The account ID should move to production:

bash
aws sts get-caller-identity
output
{
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Account": "222222222222",
    "Arn": "arn:aws:iam::222222222222:user/prod-admin"
}

When the Account matches but the Arn does not, the CLI is authenticated as a different IAM path than expected — common with role sessions and SSO permission sets. Read the full Arn, not only the 12-digit account ID. For a deeper provider walkthrough, see Which credentials AWS CLI uses.


How AWS CLI Profile and Credential Precedence Works

Selecting a profile and selecting credentials are two related steps. The profile tells AWS CLI which named configuration to use, while the credential provider determines how the CLI authenticates the request. Start with how the profile name was chosen:

              How was the profile selected?
                         |
          +--------------+--------------+
          |              |              |
          v              v              v
   --profile prod   AWS_PROFILE=prod   neither
          |              |              |
          v              v              v
 explicit profile   shell-selected     [default]
                    profile
          |              |
          v              v
 credentials for    credentials for
 "prod" profile     "prod" profile
 (explicit          (exported
  profile)           AWS_ACCESS_KEY_ID
                     can override file
                     keys in "prod")

A profile is only a named configuration. The CLI still needs credentials to authenticate the request. Those credentials might come from access keys, IAM Identity Center, an assumed role, or another supported AWS credential provider.

--profile versus AWS_PROFILE

Both select a named profile, but they are not equivalent for every edge case.

Profile name precedence: --profile on the command line wins over AWS_PROFILE. If AWS_PROFILE=prod is set but the command includes --profile dev, the CLI explicitly uses the dev profile for that invocation.

Set the shell default to prod first:

bash
export AWS_PROFILE=prod

Then override it for one command with --profile dev:

bash
aws sts get-caller-identity --profile dev
output
{
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Account": "111111111111",
    "Arn": "arn:aws:iam::111111111111:user/dev-admin"
}

The identity follows dev from --profile, not prod from the environment.

AWS_PROFILE versus exported credential variables

When the profile is selected through AWS_PROFILE, explicit credential environment variables can override credentials stored in that profile. AWS documents this case for environment variables such as AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN.

This pattern is different from passing --profile on the command line. An explicitly supplied CLI profile is a command-line setting; Botocore resolves credentials through the named profile's configured providers rather than treating exported access keys as an override of that explicit selection.

You normally would not mix a profile name from one account with exported credentials from another. That situation often happens unintentionally after a CI script, credential helper, or temporary shell setup exported AWS_ACCESS_KEY_ID and related variables.

Example with AWS_PROFILE only:

bash
export AWS_PROFILE=dev

Export prod account keys on top of the dev profile name:

bash
export AWS_ACCESS_KEY_ID=AKIAPRODKEYEXAMPLE
export AWS_SECRET_ACCESS_KEY='***'

Check what the CLI will send:

bash
aws configure list
output
NAME       : VALUE                    : TYPE             : LOCATION
profile    : dev                      : env              : ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE']
access_key : ****************5TGM     : env              :
secret_key : ****************Iwdx     : env              :
region     : ap-south-1               : config-file      : ~/.aws/config

STS signs the request with the exported keys, not the dev profile file:

bash
aws sts get-caller-identity
output
{
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Account": "222222222222",
    "Arn": "arn:aws:iam::222222222222:user/prod-admin"
}

The profile row still says dev, but the Arn shows the prod user because environment keys override file-based credentials when the profile was selected through AWS_PROFILE. Clear overrides before trusting a profile switch:

bash
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN

Use a Profile to Assume an IAM Role

A profile can assume an IAM role in another account or the same account. The config profile references a role_arn and a source_profile that holds credentials allowed to call sts:AssumeRole:

text
[profile audit]
region = ap-south-1
output = json
role_arn = arn:aws:iam::222222222222:role/audit-readonly
source_profile = prod

The prod profile must belong to an IAM user or role trusted by audit-readonly, and that identity needs sts:AssumeRole on the role ARN.

Think of source_profile as the identity AWS CLI starts with. Here, AWS CLI first authenticates using the prod profile, then uses that identity to request temporary credentials for the audit-readonly role. This example uses the existing prod identity to switch into a more restricted read-only role in the same account.

        prod profile
             |
             | authenticate as the source identity
             v
        STS AssumeRole
             |
             | returns temporary credentials
             v
      audit-readonly role

Call the role profile like any other named profile:

bash
aws sts get-caller-identity --profile audit
output
{
    "UserId": "AROAXXXXXXXXXXXXXXXXX:botocore-session-1790561406",
    "Account": "222222222222",
    "Arn": "arn:aws:sts::222222222222:assumed-role/audit-readonly/botocore-session-1790561406"
}

The output confirms that the request is using an assumed-role session. The Arn contains assumed-role/audit-readonly/..., while UserId identifies the role session. get-caller-identity does not display the temporary access key, secret key, or session token — only identity metadata.

Run aws configure list --profile audit to inspect how the profile resolved its temporary credentials. For role and SSO profiles, AWS CLI can display the temporarily cached access key and secret key used for that session. The same verification step also works with SSO and other temporary credential methods: authenticate or refresh the credentials, then run aws sts get-caller-identity.

  dev profile  ──→ AWS account 111111111111
 prod profile  ──→ AWS account 222222222222
audit profile  ──→ AssumeRole ──→ prod account (read-only role)

Safely Switch Between AWS Accounts

Before production changes:

  1. unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN when switching away from CI-style exports
  2. Set export AWS_PROFILE=<name> or pass --profile on the command
  3. Run aws sts get-caller-identity and read Account and Arn
  4. Run aws configure list if the identity still looks wrong — check LOCATION for env versus shared-credentials-file

Terraform uses the same files but resolves credentials through the AWS provider. When terraform plan targets the wrong account, align AWS_PROFILE and any profile argument in the provider block — see Fix Terraform AWS credentials error.


Troubleshooting AWS CLI Profiles

Symptom Likely cause Fix
Wrong account despite AWS_PROFILE AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY exported unset env vars; re-run aws configure list
--profile set but identity unexpected Role chain, SSO expiry, wrong config path, or custom credential process aws configure list --profile <name> then aws sts get-caller-identity --profile <name>
The config profile (x) could not be found Profile name is misspelled, or the profile section uses the wrong syntax — for example [x] instead of [profile x] in ~/.aws/config aws configure list-profiles; use [profile x] in config and [x] in credentials
Role profile fails with AccessDenied on AssumeRole Missing trust or sts:AssumeRole on source identity Fix role trust policy and IAM policy on the source user
InvalidClientTokenId after switching Stale keys in env or inactive access key InvalidClientTokenId
Unable to locate credentials Selected profile has no usable credentials, or no default credential source exists Unable to locate credentials

Summary

Named profiles let one workstation keep separate AWS CLI configurations for different accounts, roles, or authentication methods. Access-key profiles commonly use ~/.aws/credentials for credentials and ~/.aws/config for settings such as Region and role configuration. Use aws configure list-profiles to see valid names, --profile for a single command, and AWS_PROFILE for a session default.

If --profile and AWS_PROFILE specify different profiles, --profile takes precedence for that command. When a profile is selected with AWS_PROFILE, exported variables such as AWS_ACCESS_KEY_ID can still override credentials stored in that profile. Using an explicit --profile name tells AWS CLI to resolve credentials through that named profile for the command. Role profiles add role_arn and source_profile; the active principal shows as an assumed-role ARN after STS succeeds.

Make aws sts get-caller-identity part of every switch — read Account and the full Arn before destructive API calls. When keys are missing or rejected outright, use the dedicated troubleshooting guides for Unable to locate credentials and InvalidClientTokenId rather than guessing at profile names.


References


Frequently Asked Questions

Which wins: --profile or AWS_PROFILE?

--profile wins over AWS_PROFILE. For example, if AWS_PROFILE=prod is set but the command includes --profile dev, the CLI explicitly uses the dev profile for that invocation. Credential environment variables require a separate distinction: they can override credentials from a profile selected through AWS_PROFILE, while an explicitly supplied --profile causes the CLI to resolve credentials through that named profile.

Where are profile files stored?

By default the credentials file is ~/.aws/credentials and the config file is ~/.aws/config. Override paths with AWS_SHARED_CREDENTIALS_FILE and AWS_CONFIG_FILE. The credentials file holds access keys; the config file holds [profile name] sections with Region, output format, SSO settings, and role assumption settings.

Can profiles assume roles?

Yes. Add role_arn and source_profile to a [profile …] section in the config file. The CLI uses credentials from source_profile to call sts:AssumeRole and caches temporary keys for the role session. Verify with aws sts get-caller-identity --profile <role-profile> — the Arn contains assumed-role.

Finished reading?Beta Get the key takeaways in seconds, then ask follow-up questions
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with 15+ years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)