Jesse A. Green / notebook

AWS CLI User Guide

Generated May 2026 from aws/aws-cli at f141b6c

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

The AWS Command Line Interface (AWS CLI) is a unified tool to manage your AWS services from the terminal. With a single tool, you can control multiple AWS services and automate them through scripts. This guide covers AWS CLI version 1 (v1.44.85).


1. Quick Start

Get up and running in under five minutes:

# Install
pip install awscli

# Configure credentials
aws configure

You will be prompted for four values:

AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-east-1
Default output format [None]: json

Test the installation:

aws --version

Expected output:

aws-cli/1.44.85 Python/3.11.6 Linux/6.1.0 botocore/1.42.95

Tip

Run aws sts get-caller-identity to verify your credentials are working. If it returns your account ID, ARN, and user ID, you are properly authenticated.


2. Installation

Requirements

  • Python 3.9 or later
  • pip (Python package manager)

Install via pip

pip install awscli

To install a specific version:

pip install awscli==1.44.85

Upgrade

pip install --upgrade awscli

Verify installation

aws --version

Dependencies

AWS CLI v1 installs the following dependencies automatically:

Package Version
botocore 1.42.95
docutils latest compatible
s3transfer latest compatible
PyYAML latest compatible
colorama latest compatible
rsa latest compatible

Important

AWS CLI v1 and v2 are separate products. This guide documents v1 only. Do not mix installation methods or expect v2-specific features (such as the built-in installer or auto-prompt) to work with v1.

Shell Completion

Enable tab completion for commands and parameters:

Bash:

complete -C aws_completer aws

Add this line to your ~/.bashrc to make it persistent.

Zsh:

source aws_zsh_completer.sh

Add this line to your ~/.zshrc.


3. Configuration

Configuration Files

AWS CLI uses two files:

File Purpose
~/.aws/credentials Access keys (shared across SDKs)
~/.aws/config Region, output format, profiles, other settings

Initial Setup

aws configure

This creates both files with your default profile. To configure a named profile:

aws configure --profile production

Config File Format

~/.aws/credentials:

[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

[production]
aws_access_key_id = AKIAI44QH8DHBEXAMPLE
aws_secret_access_key = je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY

~/.aws/config:

[default]
region = us-east-1
output = json

[profile production]
region = eu-west-1
output = table

Note

In the credentials file, section names are just [profilename]. In the config file, non-default profiles must use the prefix [profile profilename].

Environment Variables

Environment variables override config file values:

Variable Purpose
AWS_ACCESS_KEY_ID Access key
AWS_SECRET_ACCESS_KEY Secret key
AWS_DEFAULT_REGION Default region
AWS_DEFAULT_OUTPUT Output format (json/text/table)
AWS_CONFIG_FILE Path to config file
AWS_SHARED_CREDENTIALS_FILE Path to credentials file
AWS_CA_BUNDLE Path to CA certificate bundle
AWS_DATA_PATH Additional data search paths

Profiles

Use the --profile flag to switch between configured profiles:

aws s3 ls --profile production

SSO Login

If your organization uses AWS SSO:

aws sso login --profile my-sso-profile

Command Aliases

Create shortcuts in ~/.aws/cli/alias (INI format):

[toplevel]
whoami = sts get-caller-identity
running = ec2 describe-instances --filters Name=instance-state-name,Values=running
myip = !curl -s https://checkip.amazonaws.com

Aliases in the [toplevel] section are invoked as:

aws whoami
aws running

External aliases (prefixed with !) run shell commands:

aws myip

4. Core Usage

Command Structure

aws [global-options] <service> <operation> [parameters]

Examples:

aws ec2 describe-instances
aws s3 ls
aws lambda list-functions --region us-west-2

Global Options

Option Description
--version Display version and exit
--output Output format: json, text, or table
--region AWS region to target
--profile Named profile to use
--endpoint-url Override service endpoint URL
--no-verify-ssl Disable SSL certificate verification
--no-paginate Disable automatic pagination
--query JMESPath query to filter output
--debug Enable debug logging
--cli-read-timeout Read timeout in seconds
--cli-connect-timeout Connection timeout in seconds
--no-sign-request Do not sign requests (for public resources)
--ca-bundle Path to CA certificate bundle
--color Color output: on, off, or auto

Output Formats

JSON (default) -- structured, machine-readable:

aws iam list-users --output json
{
    "Users": [
        {
            "UserName": "alice",
            "UserId": "AIDAEXAMPLE1",
            "Arn": "arn:aws:iam::123456789012:user/alice"
        }
    ]
}

Table -- human-readable, formatted columns:

aws iam list-users --output table
------------------------------------------------------------
|                        ListUsers                         |
+----------+----------------+-----------------------------+
| UserName |    UserId      |            Arn              |
+----------+----------------+-----------------------------+
|  alice   |  AIDAEXAMPLE1  | arn:aws:iam::123...:user/al |
+----------+----------------+-----------------------------+

Text -- tab-delimited, suitable for grep/awk/cut:

aws iam list-users --output text
USERS   alice   AIDAEXAMPLE1    arn:aws:iam::123456789012:user/alice

Filtering Output with --query

The --query option accepts JMESPath expressions:

# Get just instance IDs
aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId'

# Filter by state
aws ec2 describe-instances \
  --query 'Reservations[].Instances[?State.Name==`running`].InstanceId'

# Format as table with selected fields
aws ec2 describe-instances \
  --query 'Reservations[].Instances[].[InstanceId, State.Name, InstanceType]' \
  --output table

Input Methods

Inline JSON:

aws ec2 create-tags --resources i-1234567890abcdef0 \
  --tags '[{"Key":"Name","Value":"MyInstance"}]'

Shorthand syntax:

aws ec2 create-tags --resources i-1234567890abcdef0 \
  --tags Key=Name,Value=MyInstance

From a file (file:// prefix):

aws ec2 run-instances --cli-input-json file://params.json

Binary file content (fileb:// prefix):

aws lambda update-function-code \
  --function-name my-function \
  --zip-file fileb://function.zip

Note

Use file:// for text content (UTF-8) and fileb:// for binary content (zip files, images, etc.).

Getting Help

# General help
aws help

# Service help (lists all operations)
aws ec2 help

# Operation help (shows parameters, examples)
aws ec2 describe-instances help

Waiters

Wait for a resource to reach a specific state before proceeding:

aws ec2 wait instance-running --instance-ids i-1234567890abcdef0

The command blocks until the instance is running (or times out). Useful in scripts to ensure sequential operations succeed.

Pagination

By default, AWS CLI automatically paginates results. To get all results in one call:

aws s3api list-objects --bucket my-bucket --no-paginate

5. Common Tasks

5.1 S3: Upload a File

aws s3 cp myfile.txt s3://my-bucket/myfile.txt

Expected output:

upload: ./myfile.txt to s3://my-bucket/myfile.txt

Upload an entire directory:

aws s3 cp ./local-dir s3://my-bucket/prefix/ --recursive

5.2 S3: Download Files

aws s3 cp s3://my-bucket/myfile.txt ./myfile.txt

Download a directory:

aws s3 cp s3://my-bucket/prefix/ ./local-dir/ --recursive

5.3 S3: Sync a Directory

Sync uploads only changed files (like rsync):

aws s3 sync ./local-dir s3://my-bucket/backup/

Sync from S3 to local:

aws s3 sync s3://my-bucket/backup/ ./local-dir/

Delete files in destination that do not exist in source:

aws s3 sync ./local-dir s3://my-bucket/backup/ --delete

5.4 S3: List and Remove

List buckets:

aws s3 ls

List objects in a bucket:

aws s3 ls s3://my-bucket/
aws s3 ls s3://my-bucket/prefix/ --recursive

Remove a file:

aws s3 rm s3://my-bucket/myfile.txt

Remove all objects with a prefix:

aws s3 rm s3://my-bucket/prefix/ --recursive

5.5 S3: Create and Delete Buckets

aws s3 mb s3://my-new-bucket
aws s3 rb s3://my-empty-bucket
aws s3 rb s3://my-bucket --force   # removes all objects first

5.6 EC2: Launch an Instance

aws ec2 run-instances \
  --image-id ami-0abcdef1234567890 \
  --instance-type t3.micro \
  --key-name my-keypair \
  --security-group-ids sg-0123456789abcdef0 \
  --count 1

5.7 EC2: List Running Instances

aws ec2 describe-instances \
  --filters Name=instance-state-name,Values=running \
  --query 'Reservations[].Instances[].[InstanceId, InstanceType, PublicIpAddress]' \
  --output table

5.8 EC2: Stop and Terminate

aws ec2 stop-instances --instance-ids i-1234567890abcdef0
aws ec2 terminate-instances --instance-ids i-1234567890abcdef0

5.9 Lambda: Deploy a Function

aws lambda create-function \
  --function-name my-function \
  --runtime python3.12 \
  --role arn:aws:iam::123456789012:role/lambda-role \
  --handler lambda_function.handler \
  --zip-file fileb://function.zip

Update function code:

aws lambda update-function-code \
  --function-name my-function \
  --zip-file fileb://function.zip

5.10 Lambda: Invoke a Function

aws lambda invoke \
  --function-name my-function \
  --payload '{"key": "value"}' \
  output.json

5.11 IAM: Manage Users

# Create user
aws iam create-user --user-name developer

# Create access key
aws iam create-access-key --user-name developer

# Attach policy
aws iam attach-user-policy \
  --user-name developer \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# List users
aws iam list-users --output table

5.12 CloudFormation: Deploy a Stack

aws cloudformation create-stack \
  --stack-name my-stack \
  --template-body file://template.yaml \
  --capabilities CAPABILITY_IAM

# Wait for completion
aws cloudformation wait stack-create-complete --stack-name my-stack

5.13 Logs: Tail CloudWatch Logs

aws logs get-log-events \
  --log-group-name /aws/lambda/my-function \
  --log-stream-name '2026/05/06/[$LATEST]abc123' \
  --limit 50

5.14 STS: Check Current Identity

aws sts get-caller-identity

Expected output:

{
    "UserId": "AIDAEXAMPLE",
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/myuser"
}

5.15 CloudFront: Create an Invalidation

aws cloudfront create-invalidation \
  --distribution-id E1A2B3C4D5E6F7 \
  --paths "/index.html" "/css/*"

6. Troubleshooting

6.1 "groff or mandoc" Not Found

Error:

Could not find executable named "groff" or "mandoc"

Cause: The help system renders man pages using groff or mandoc, which are not installed.

Solution:

# Ubuntu/Debian
sudo apt install groff

# macOS (usually pre-installed, but if missing)
brew install groff

# Amazon Linux / RHEL
sudo yum install groff

Prevention: Install groff as part of your base system provisioning.

6.2 "Unable to load paramfile" Errors

Error:

Unable to load paramfile file://config.json: [Errno 2] No such file or directory

Cause: The file:// path is relative to your current working directory, or the file does not exist.

Solution: Use an absolute path or verify your working directory:

aws lambda update-function-code \
  --function-name my-func \
  --zip-file fileb:///home/user/deploy/function.zip

Prevention: Always use absolute paths in scripts.

6.3 "Invalid choice, valid choices are..."

Error:

Invalid choice: 'ec2-describe-instances', valid choices are: ...

Cause: Typo in the command, or using old-style command format.

Solution: AWS CLI v1 uses aws <service> <operation> format (space-separated, not hyphens):

# Wrong
aws ec2-describe-instances

# Correct
aws ec2 describe-instances

6.4 "Unknown options" Error

Error:

Unknown options: --my-flag

Cause: The parameter does not exist for this operation, or there is a typo.

Solution: Check available parameters:

aws ec2 describe-instances help

6.5 "Bad value for --endpoint-url"

Error:

Bad value for --endpoint-url "myendpoint.example.com": scheme is missing...

Cause: The endpoint URL must include https:// or http://.

Solution:

# Wrong
aws s3 ls --endpoint-url myendpoint.example.com

# Correct
aws s3 ls --endpoint-url https://myendpoint.example.com

6.6 "Bad value for --query"

Error:

Bad value for --query "Reservations[.Instances[]": invalid expression...

Cause: Invalid JMESPath syntax.

Solution: Validate your JMESPath expression. Common issues:

  • Missing closing brackets
  • Using single quotes inside the expression on Windows (use double quotes and escape)
  • Incorrect field names (case-sensitive)
# Test incrementally
aws ec2 describe-instances --query 'Reservations'
aws ec2 describe-instances --query 'Reservations[0]'
aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId'

6.7 Credentials Not Found

Error:

Unable to locate credentials. You can configure credentials by running "aws configure".

Cause: No credentials in environment variables, config files, or instance metadata.

Solution:

  1. Run aws configure to set up credentials
  2. Or set environment variables:
export AWS_ACCESS_KEY_ID=AKIAEXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  1. Or verify your credentials file exists at ~/.aws/credentials

6.8 Region Not Specified

Error:

You must specify a region. You can also configure your region by running "aws configure".

Cause: No region set in config, environment, or command line.

Solution:

# Per command
aws ec2 describe-instances --region us-east-1

# Or set globally
aws configure set region us-east-1

# Or environment variable
export AWS_DEFAULT_REGION=us-east-1

6.9 SSL Certificate Verification Failed

Error:

SSL validation failed for https://...

Cause: Corporate proxy, custom CA, or outdated certificates.

Solution:

# Point to your CA bundle
aws s3 ls --ca-bundle /path/to/custom-ca-bundle.crt

# Or set globally
export AWS_CA_BUNDLE=/path/to/custom-ca-bundle.crt

# As a last resort (NOT recommended for production)
aws s3 ls --no-verify-ssl

Caution

Using --no-verify-ssl disables all certificate verification. Only use this for debugging, never in production or scripts handling sensitive data.

Prevention: Keep your system CA certificates updated. If behind a corporate proxy, add the proxy CA to your bundle.

6.10 SSO Login Fails to Open Browser (WSL)

Error: Running aws sso login in WSL fails with errors related to gio or the browser not opening.

Cause: WSL does not have a native graphical browser. The SSO flow tries to open one via xdg-open or gio.

Solution:

  1. Set your Windows browser as the default:
export BROWSER="/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
  1. Or manually copy the URL printed to the terminal and paste it into your Windows browser.

Prevention: Add the BROWSER export to your ~/.bashrc in WSL.

6.11 Access Denied

Error:

An error occurred (AccessDenied) when calling the <Operation> operation: User: arn:aws:iam::...

Cause: The IAM identity does not have permission for the requested action.

Solution:

  1. Verify which identity you are using: aws sts get-caller-identity
  2. Check that the required IAM policy is attached
  3. Verify you are in the correct account and region

6.12 Timeout Errors

Error:

Connect timeout on endpoint URL...

Cause: Network issues, DNS resolution failure, or firewall blocking.

Solution:

# Increase timeouts
aws s3 ls --cli-connect-timeout 30 --cli-read-timeout 60

Check that you can reach AWS endpoints:

curl -v https://sts.amazonaws.com

Warning

If you are behind a corporate firewall or VPN, ensure that outbound HTTPS (port 443) is allowed to AWS service endpoints (*.amazonaws.com).


7. FAQ

Q: How do I switch between multiple AWS accounts?

Use named profiles. Configure each account with aws configure --profile <name>, then use --profile <name> on each command, or set export AWS_PROFILE=<name> for the session.

Q: What is the difference between aws s3 and aws s3api?

aws s3 provides high-level commands (cp, sync, mv, ls, rm, mb, rb) with familiar filesystem-like syntax. aws s3api exposes the full S3 API with all parameters. Use aws s3 for everyday tasks and aws s3api when you need fine-grained control.

Q: Can I use AWS CLI without credentials (for public resources)?

Yes. Use --no-sign-request to skip authentication:

aws s3 ls s3://public-bucket --no-sign-request

Q: How do I get output as plain text for scripting?

Use --output text combined with --query:

INSTANCE_ID=$(aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].InstanceId' \
  --output text)

Q: How do I use AWS CLI with a proxy?

Set the standard proxy environment variables:

export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080

Q: Where are the debug logs?

Use --debug to print detailed logs to stderr:

aws s3 ls --debug 2>debug.log

This includes HTTP request/response details, credential resolution, and retry logic.

Q: How do I paginate through large result sets manually?

Use --max-items and --starting-token:

aws s3api list-objects --bucket my-bucket --max-items 100
# Use the NextToken from output:
aws s3api list-objects --bucket my-bucket --max-items 100 --starting-token eyJ...

Q: Can I pipe JSON input from another command?

Yes, but note that --cli-input-json requires file://. You can use process substitution on Linux/macOS:

aws ec2 run-instances --cli-input-json file://<(generate_params.sh)

Or write to a temporary file first.

Q: What Python versions are supported?

AWS CLI v1.44.85 requires Python 3.9 or later.

Q: How do I create command aliases?

Create or edit ~/.aws/cli/alias:

[toplevel]
whoami = sts get-caller-identity
ls-instances = ec2 describe-instances --query 'Reservations[].Instances[].[InstanceId,State.Name]' --output table

Then use them as aws whoami or aws ls-instances.

Tip

For architecture details, configuration internals, extension mechanisms, and security hardening, see the Admin Guide.