🖥️ The AWS CLI (aws): Sign In, Profiles, Output and Query
How the aws command is organized, how to sign in without storing permanent keys, how profiles and regions are chosen (with the real config file), output formats and JMESPath queries, and offline help
💡 How this page was tested. On 6 October 2026 I installed AWS CLI 2.37.9 with AWS's own installer into a throwaway folder (with its own empty home directory, so no real configuration was touched) and ran everything that works without signing in: the version, the errors when no credentials exist, the configuration commands and the file they write, environment variables, and the offline help. Anything that needs a real account is marked from the documentation, not run here. See also the pages for az, gcloud and oci, and the comparison.
What aws is
aws is the AWS command-line interface, version 2. Commands are organized as service, then operation: aws s3 ls, aws ec2 describe-instances, aws iam list-users. Almost every operation of every service has a command, and the names follow the API: describe- and list- read, create-, run-, put- make things, delete- and terminate- remove them.
Getting it
AWS's version 2 comes as an installer that is not a pip package: you download a zip, unpack it and run its installer. I installed it into a folder of my own, which leaves the system untouched:
curl -o awscliv2.zip https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip unzip awscliv2.zip ./aws/install -i ~/tools/aws-cli -b ~/tools/aws-bin
(-i is the install folder and -b is where the aws link goes. Without them it installs under /usr/local and needs sudo.) Or skip installing: CloudShell, the terminal in the AWS console, has it ready and signed in. The version, as run:
user@lab:~$ aws --version aws-cli/2.37.9 Python/3.14.6 Linux/7.0.0-38-generic exe/x86_64.ubuntu.24 user@lab:~$ aws configure list NAME : VALUE : TYPE : LOCATION profile : <not set> : None : None access_key : <not set> : None : None secret_key : <not set> : None : None region : <not set> : None : None user@lab:~$ aws sts get-caller-identity aws: [ERROR]: An error occurred (NoCredentials): Unable to locate credentials. You can configure credentials by running "aws login".
Before you sign in
The first output block above also shows what an unconfigured CLI says:
- aws configure list is the "where do my settings come from?" command. The columns are the name, the value, the type (where it came from: config-file, env, shared-credentials-file, and so on) and the location. Everything is <not set>.
- aws sts get-caller-identity failed with NoCredentials: Unable to locate credentials. You can configure credentials by running "aws login". The message itself recommends aws login.
Once signed in, aws sts get-caller-identity is the first command to know: it prints the account ID and the identity you are using (its ARN). It needs no special permission. Run it before every experiment, so a test does not land in the wrong account (from the documentation, not run here).
Signing in
The documentation (read on 6 October 2026) points to temporary credentials rather than permanent keys:
- aws login. A browser sign-in that gives the CLI temporary credentials that are rotated automatically. The CLI's own error message suggests it. AWS's documentation mentions it for signing in with the root user without making access keys, and the same idea is the way to avoid a key in a file.
- IAM Identity Center (SSO). The recommended way for people in an organization: aws configure sso asks for a session name, the SSO start URL, the SSO region and a registration scope, opens your browser, lets you pick an account and a role, and then asks for a default region, an output format and a profile name. Later, aws sso login --profile NAME renews the session, and aws sso logout clears it. If a browser cannot be opened, --use-device-code gives a code to type on another device.
- An IAM user's access keys. A long-lived aws_access_key_id and aws_secret_access_key in ~/.aws/credentials (the old way, from aws configure). They work, but a key in a file can be copied, committed by mistake or stolen. Use them only when nothing else is possible, and never for the root user.
- A role on the machine. On an EC2 instance, a Lambda function or another AWS service, the CLI finds temporary credentials from the machine's role by itself: nothing to configure (see the services map).
The SSO sign-in is cached under ~/.aws/sso/cache, and as long as the SSO session is valid, the CLI renews the short-lived credentials by itself. When the session ends, you sign in again.
Profiles, regions and the config file
Settings live in two plain-text files in ~/.aws/: config (profiles, regions, output, SSO) and credentials (access keys). They are divided into profiles. The profile named default is used unless you say otherwise. This ran for real, in the throwaway home directory:
user@lab:~$ aws configure set region eu-west-1 user@lab:~$ aws configure set output table user@lab:~$ aws configure set region us-east-2 --profile lab user@lab:~$ aws configure list NAME : VALUE : TYPE : LOCATION profile : <not set> : None : None access_key : <not set> : None : None secret_key : <not set> : None : None region : <not set> : None : None user@lab:~$ aws configure list-profiles default lab user@lab:~$ aws configure get region eu-west-1 user@lab:~$ aws configure get region --profile lab us-east-2 user@lab:~$ cat ~/.aws/config; ls -la ~/.aws [default] region = eu-west-1 output = table [profile lab] region = us-east-2 total 16 drwxrwxr-x 3 liloland liloland 4096 Oct 6 16:12 . drwxrwxr-x 3 liloland liloland 4096 Oct 6 16:12 .. drwxrwxr-x 3 liloland liloland 4096 Oct 6 16:12 cli -rw------- 1 liloland liloland 77 Oct 6 16:12 config
Read it:
- aws configure set region eu-west-1 wrote region = eu-west-1 into the [default] section, and aws configure set output table set the default output.
- aws configure set region us-east-2 --profile lab made a second profile. In the file it is [profile lab]: the prefix profile is needed in the config file (but not in credentials).
- aws configure list-profiles lists them, aws configure get region reads one value, and --profile lab points a command at another profile.
- The file is created with permissions -rw------- (only you), because it is the kind of file that can hold secrets.
What overrides what
Settings can come from a command-line option, an environment variable or the config file, and the documentation says a command-line option or an environment variable overrides the file. The real output shows the environment variables at work:
user@lab:~$ AWS_REGION=ap-south-1 aws configure list | grep region region : ap-south-1 : env : ['AWS_REGION', 'AWS_DEFAULT_REGION'] user@lab:~$ AWS_PROFILE=lab aws configure list | grep -E 'profile|region' profile : lab : env : ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE'] region : us-east-2 : config-file : ~/.aws/config
- With AWS_REGION=ap-south-1, aws configure list reports the region as ap-south-1, TYPE env, even though the file says eu-west-1.
- With AWS_PROFILE=lab, it reports the profile as lab (TYPE env) and the region from that profile's section, us-east-2.
This is why aws configure list is the first command to run when something goes to the wrong place: it shows where each value came from. (A trap: aws configure list itself ignores a --region option, so test the option with a real command instead.)
The regions themselves are on the regions page: remember the console shows one region at a time and the CLI uses the one in your profile.
Output and query
--output accepts json (the default unless you set another), yaml, yaml-stream, text and table. And --query takes a JMESPath expression (the same language as az and oci: see the comparison page for a primer). Examples from the documentation, not run here:
aws ec2 describe-regions --output table
aws ec2 describe-regions --query "Regions[].RegionName" --output text
aws ec2 describe-instances --query "Reservations[].Instances[].[InstanceId,InstanceType,State.Name]" --output table
aws ec2 describe-availability-zones --query "AvailabilityZones[].{Name:ZoneName,ID:ZoneId}" --output table
- AWS wraps results in a top-level key (Regions, Reservations, Instances), so a query starts with it: Regions[].RegionName.
- Instances hide inside Reservations: that is why the describe-instances query has two levels (Reservations[].Instances[]).
- --output text gives plain values for scripts, --output table is for reading.
- The pager: version 2 sends long output to a pager (less) by default. In scripts, turn it off with --no-cli-pager or AWS_PAGER="".
Skeletons: let the CLI write the template
For complicated commands, the CLI can print an empty template of all the arguments. This ran for real:
user@lab:~$ aws ec2 run-instances --generate-cli-skeleton | head -12
{
"BlockDeviceMappings": [
{
"Ebs": {
"DeleteOnTermination": true,
"Iops": 0,
"SnapshotId": "",
"VolumeSize": 0,
"VolumeType": "standard",
"KmsKeyId": "",
"Throughput": 0,
"OutpostArn": "",
--generate-cli-skeleton prints the whole JSON input of run-instances with empty values (the first lines only are shown), and you can save it, fill in what you need and run the command with --cli-input-json file://FILE (or --cli-input-yaml). It is also the fastest way to see every option of a command.
Getting help, with no account
The help is built in and works offline: aws help, aws s3 help, aws ec2 describe-instances help. (It is a manual page, so the keys are those of less: space to scroll, q to quit.) And topic guides: aws help topics lists them, aws help config-vars explains every configuration variable and its environment variable. In the real output, aws help topics lists config-vars, return-codes and the S3 topics.
For the commands you use most, notice that aws s3 (the high-level commands: ls, cp, mb, rb, sync) and aws s3api (the low-level ones that follow the API) are two different groups.
Habits that save you
- aws sts get-caller-identity and aws configure list first. Account and region are the two things that go wrong.
- Always know your region. Put region in the profile, and add --region when you work somewhere else. Remember opt-in regions must be enabled first.
- Use temporary credentials. aws login or SSO, and roles on machines. No access keys in scripts, in repositories or in chat.
- Use a profile per account, named for what it is (personal, lab), and --profile or AWS_PROFILE to choose.
- --dry-run exists on many EC2 commands: it checks whether you would be allowed, without doing anything (from the documentation, not run here).
- Check the exit code in scripts: non-zero means failure (aws help return-codes lists them).
- Clean up what you create: there is no resource group, so tag it, or use the tidy-experiment pattern on the services map.
The cheat sheet
- Shape: aws SERVICE OPERATION --option value. Help: aws help, aws SERVICE help, aws SERVICE OPERATION help, aws help topics.
- Who and where: aws sts get-caller-identity, aws configure list (shows the source of each value), aws configure get region.
- Sign in: aws login or aws configure sso then aws sso login --profile P. Roles on machines. Avoid access keys.
- Files: ~/.aws/config ([default], [profile NAME]) and ~/.aws/credentials, mode 600. Env: AWS_PROFILE, AWS_REGION.
- Profiles: aws configure set region R --profile P, aws configure list-profiles, --profile P.
- Output: --output json|yaml|yaml-stream|text|table. Query: --query "Regions[].RegionName" (JMESPath). --no-cli-pager for scripts.
- Templates: aws SERVICE OPERATION --generate-cli-skeleton, --cli-input-json file://F.
← The Azure CLI (az): Sign In, Defaults, Output and Query · ↑ All tutorials · The Google Cloud CLI (gcloud): Sign In, Configurations, Format and Filter →