---
title: "AWS CLI"
lang: "en"
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/aws-cli
---

[Home](/)›[Cheatsheets](/cheatsheets)

Cheatsheets

# AWS CLI

An expert reference for the AWS CLI covering configuration precedence, EC2 lifecycle control, recursive S3 operations, JMESPath querying, output formatting, and secure SSM sessions.

13 Categories23 Sections40 ExamplesPublished: 25 Mar 2026

AWS CLIEC2S3IAMAutomationJMESPathSSM

[Markdown for AI(opens in a new tab)](/aws-cli/index.md "Open the plain-Markdown version of this page, for pasting into an AI tool")

Series

[AWS CLI Guides](/series/aws-cli-guides)1/1

All posts in this series (1)

Cheatsheets1

1.  [AWS CLIYou are here](/cheatsheets/aws-cli)

The AWS Command Line Interface (CLI) lets you orchestrate infrastructure, move cloud data, and configure security entirely from the terminal. This reference covers configuring identity profiles, managing EC2 instances, synchronizing S3 buckets, creating IAM roles, querying nested JSON with JMESPath, formatting output, and securing access with Systems Manager.

Later sections add pagination and waiters, STS cross-account access, CloudWatch Logs, Lambda, Secrets Manager and Parameter Store, and ECR with ECS deployments.

[Configuration & Profiles](#category-configuration-profiles)

-   [Initial Setup & Profiles](#section-aws-configure)
-   [System Environment Variables](#section-environment-variables)

[EC2 Instance Control & Filtering](#category-ec2-management)

-   [Lifecycle Management & Dry-Runs](#section-ec2-lifecycle)
-   [Server-Side Metadata Filters](#section-ec2-describe)

[S3 Storage Management](#category-s3-storage)

-   [Recursive Sync, Copy & Move Operations](#section-s3-transfers)
-   [Data Analytics, Deletion & Secure Sharing](#section-s3-metadata-sharing)

[Identity & Access Management (IAM)](#category-iam-management)

-   [Principal Auditing & Verification](#section-iam-verification)
-   [Role Delegation & Trust Policies](#section-iam-roles)

[Data Querying with JMESPath](#category-querying-jmespath)

-   [Projections, Filtering & Analytics](#section-jmespath-filters)

[Serialization & Output Formats](#category-output-serialization)

-   [Formatting Types (table, text, json, yaml)](#section-output-formats)

[Systems Manager (SSM) Security](#category-ssm-session-manager)

-   [Interactive Shells & Secure Tunnels](#section-ssm-sessions)

[Pagination & Waiters](#category-pagination-waiters)

-   [Controlling Pagination](#section-pagination)
-   [Waiters & JSON Skeletons](#section-waiters-skeletons)

[STS & Cross-Account Access](#category-sts-cross-account)

-   [Assuming Roles](#section-assume-role)
-   [Config-File Assumption & MFA](#section-config-role-mfa)

[CloudWatch Logs](#category-cloudwatch-logs)

-   [Tailing & Searching](#section-tailing-searching)
-   [Groups & Retention](#section-retention)

[Lambda](#category-lambda)

-   [Inspecting & Invoking](#section-inspect-invoke)
-   [Deploying Code](#section-deploy-code)

[Secrets & Parameter Store](#category-secrets-parameters)

-   [Secrets Manager](#section-secrets-manager)
-   [SSM Parameter Store](#section-parameter-store)

[ECR & Containers](#category-ecr-containers)

-   [Auth, Repositories & Images](#section-ecr-auth-repos)
-   [ECS Deployments](#section-ecs-deployments)

No commands found

Try adjusting your search term

## Configuration & Profiles

Set up credentials, manage named profiles, and understand how the CLI resolves settings so automation runs against the account you expect.

### Initial Setup & Profiles

Configuring the CLI sets the default security context and region for every API call, resolved through a strict precedence hierarchy.

#### Accessibility

Keep credentials in an encrypted secret manager. Never commit ~/.aws/credentials to version control, since it holds long-lived programmatic access keys.

#### Best Practices

-   Prefer aws sso login --profile <name> with IAM Identity Center for temporary credentials over static IAM user access keys.
-   Audit configurations routinely. An "Unable to locate credentials" error in CloudShell often means an expired console session, not missing local files.

#### Common Errors

-   **The security token is invalid or an ExpiredToken exception occurs during execution.:** Temporary credentials (SSO or assumed roles) have expired. Refresh them via your SSO provider, or update AWS\_SESSION\_TOKEN alongside the access keys.

#### Advanced Notes

-   **Configuration precedence hierarchy:** The CLI resolves credentials and parameters in a strict order, which matters in CI/CD: 1. Command line options (--region, --profile) beat everything else. 2. Environment variables like AWS\_DEFAULT\_REGION override local files. 3. Assume-role credentials sourced via CLI assume-role processes. 4. Shared credentials file, usually ~/.aws/credentials. 5. Shared config file, usually ~/.aws/config. 6. Container credentials, fetched when running inside Amazon ECS tasks. 7. Instance profile credentials from the EC2 metadata endpoint.
-   **Deep diagnostics with the debug flag:** Appending --debug prints the full execution lifecycle: where the CLI searches for credentials, the botocore calls it builds, the HTTP payloads sent to AWS, and the raw JSON responses.

#### Keywords

AWS CLIprofileautomationconfiguration

#### Interactive configuration of the default profile

Prompts for standard access credentials and defaults, then persists them to the ~/.aws directory.

Code

Terminal window

```
# Prompt for keys, region, and output format, then save them locallyaws configure
```

Input

```
1AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE2AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY3Default region name [None]: us-east-14Default output format [None]: json
```

-   Writes two files: ~/.aws/credentials (access keys) and ~/.aws/config (region and output format) on Unix-like systems.
-   Commands run without a profile fall back to this default configuration block.

#### Configuring a named profile for isolated environments

Establishes a separate credential set tied to a profile name, which makes safe multi-account work possible.

Code

Terminal window

```
# Create an independent credential set under a profile nameaws configure --profile production-admin
```

Input

```
1AWS Access Key ID [None]: AKIAI44QH8DHBEXAMPLE2AWS Secret Access Key [None]: je7MtGbClwBF/2Zp9Utk/h3yCoEXAMPLEKEY3Default region name [None]: us-west-24Default output format [None]: yaml
```

-   Append --profile production-admin to a command to use this credential block explicitly.
-   Or switch the active shell context with export AWS\_PROFILE=production-admin.

#### Verify the active configuration and its sources

Exposes the active configuration values and the origin type that won the precedence evaluation.

Code

Terminal window

```
# Show current values and where each one came fromaws configure list
```

Output

```
1Name             Value             Type    Location2----             -----             ----    --------3profile             None    None4access_key     ****************7XX  shared-credentials-file5secret_key     ****************KEY  shared-credentials-file6region         us-east-1  config-file  ~/.aws/config
```

-   Use this to audit which credentials will authorize a command before running destructive changes.

### System Environment Variables

Inject authentication and default behavior at runtime without writing config files to disk, which suits stateless containers and pipelines.

#### Accessibility

In CI platforms (GitHub Actions, GitLab CI), populate these from the provider's encrypted secrets. Never hardcode them into shell scripts.

#### Best Practices

-   When automating on AWS, prefer an IAM role attached to the execution environment (like an EC2 instance profile) over exporting static user credentials.

#### Common Errors

-   **SignatureDoesNotMatch or InvalidClientTokenId exceptions.:** The exported AWS\_SECRET\_ACCESS\_KEY is usually truncated or has trailing spaces, or temporary credentials are being used without AWS\_SESSION\_TOKEN.

#### Advanced Notes

-   **Integrating with temporary assumed roles:** With an STS assumed role, static keys are not enough. You must also export AWS\_SESSION\_TOKEN="<long-token-string>". Without it the API rejects the request as unauthenticated.

#### Keywords

AWS CLIautomationenvironment variables

#### Injecting credentials via shell session variables

Assigns security and formatting variables to the environment scope, overriding ~/.aws/credentials for the life of the terminal.

Code

Terminal window

```
# Set credentials and defaults for the current terminal sessionexport AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"export AWS_DEFAULT_REGION="us-east-1"export AWS_DEFAULT_OUTPUT="table"
```

-   Run unset AWS\_ACCESS\_KEY\_ID AWS\_SECRET\_ACCESS\_KEY AWS\_DEFAULT\_REGION AWS\_DEFAULT\_OUTPUT to revoke them and fall back to the config files.

## EC2 Instance Control & Filtering

Manage compute lifecycle safely and filter metadata on the server side to cut bandwidth and avoid client-side timeouts.

### Lifecycle Management & Dry-Runs

Move instances between running, stopped, and terminated states, with dry-run checks so bad permissions or parameters fail before they cause downtime.

#### Accessibility

Enable termination protection on mission-critical instances. Disabling the lock is then an explicit API call before a terminate can succeed.

#### Best Practices

-   Put --dry-run checks in CI/CD test phases to confirm a newly attached IAM role has the privileges it needs before deployment steps run.

#### Common Errors

-   **An error occurred (OperationNotPermitted) when calling the TerminateInstances operation.:** Termination protection is enabled. Disable it with aws ec2 modify-instance-attribute --instance-id i-0123456789abcdef0 --no-disable-api-termination.

#### Advanced Notes

-   **The dry-run exception pattern:** A DryRunOperation error is the intended successful result of a dry-run, not a failure. Automation should trap that specific code and treat it as a green light to run the live command.

#### Keywords

AWS CLIEC2automationlifecycle

#### Validate authorization with the dry-run flag

Asks the EC2 API to validate IAM privileges and request syntax without modifying the instance.

Code

Terminal window

```
# Check IAM permissions and syntax without changing stateaws ec2 stop-instances --instance-ids i-0123456789abcdef0 --dry-run
```

Output

```
1An error occurred (DryRunOperation) when calling the StopInstances operation: Request would have succeeded, but DryRun flag is set.
```

-   Lets you validate automation without risking production downtime.
-   A principal without the permission gets UnauthorizedOperation instead of DryRunOperation.

#### Start and stop instances

Sends state-change signals to transition instances into running or stopped modes.

Code

Terminal window

```
# Start a stopped EC2 instanceaws ec2 start-instances --instance-ids i-0123456789abcdef0
# Stop a running EC2 instanceaws ec2 stop-instances --instance-ids i-0123456789abcdef0
```

-   The response shows both PreviousState and CurrentState for each instance.

#### Terminate an instance permanently

Sends a decommission signal that permanently shuts down and destroys the target node.

Code

Terminal window

```
# Permanently destroy the instance (irreversible)aws ec2 terminate-instances --instance-ids i-0123456789abcdef0
```

-   Final and destructive. Attached EBS volumes with DeleteOnTermination set to true are deleted with the host.

### Server-Side Metadata Filters

Push filtering to the AWS API so only matching resources come back, avoiding client-side memory bloat and pagination throttling.

#### Accessibility

For accounts with thousands of resources, server-side filters are effectively mandatory to avoid pagination throttling and excess bandwidth.

#### Best Practices

-   Use a two-tier approach. Server-side --filters limit the data sent over the network, then a client-side --query shapes the final output.

#### Common Errors

-   **The filter 'status' is invalid.:** Filter properties are case-sensitive and must match the EC2 API schema exactly, like instance-state-name rather than a shorthand.

#### Advanced Notes

-   **Wildcards in filter values:** The Values parameter supports wildcards. Use \* to match zero or more characters and ? to match a single character. Values='prod-\*' captures prod-web, prod-database, and anything else with that prefix.

#### Keywords

AWS CLIEC2\--filtersmetadata

#### Retrieve only running instances

Requests only instances matching the running state, discarding stopped, pending, and terminated nodes before the payload leaves AWS.

Code

Terminal window

```
# Return metadata only for instances in the 'running' stateaws ec2 describe-instances --filters "Name=instance-state-name,Values=running"
```

-   This cuts the JSON payload size.
-   Filters require the exact Name=attribute-name,Values=value string format.

#### Compound filtering with tags and VPC constraints

Chains filters; the API treats multiple filters as a logical AND, so every condition must be true.

Code

Terminal window

```
# Both conditions must match (implicit AND)aws ec2 describe-instances \  --filters "Name=vpc-id,Values=vpc-0123456789abcdef0" "Name=tag:Environment,Values=production"
```

-   To filter on a custom tag, prefix the key with tag: (for example, tag:Environment).

## S3 Storage Management

Move, sync, and audit objects with high-level commands, and understand recursion, filter order, and access control before running destructive operations.

### Recursive Sync, Copy & Move Operations

cp, sync, and mv abstract multipart uploads and can traverse nested directories, with state-checking to transfer only what changed.

#### Accessibility

When copying local to S3, a trailing slash on the destination keeps the original filename inside that prefix. Without it, the file is renamed to the destination string.

#### Best Practices

-   Test destructive recursive operations with --dryrun. It models what will be overwritten or deleted without making any API changes.
-   For large datasets, prefer aws s3 sync over recursive aws s3 cp. sync computes deltas; cp overwrites every destination object regardless of changes.

#### Common Errors

-   **An error occurred (AccessDenied) when calling the PutObject operation.:** Confirm the IAM profile has s3:PutObject. Also check for explicit DENY bucket policies or restrictive VPC endpoint policies, which always beat IAM allow rules.

#### Advanced Notes

-   **How S3 filter patterns are evaluated:** Patterns evaluate against the source directory with the path prepended. For aws s3 cp /tmp/foo s3://bucket/ --recursive --exclude ".git/\*", files evaluate as /tmp/foo/.git/config, so patterns must account for the full path or they may not match nested files.
-   **Direct storage class assignment:** Set the destination storage class during a transfer with --storage-class (STANDARD\_IA, GLACIER, INTELLIGENT\_TIERING) instead of waiting on lifecycle policies.

#### Keywords

AWS CLIS3automationsync

#### Upload objects with recursive directory traversal

Walks the local directory and uploads every discovered file into the target S3 prefix in parallel.

Code

Terminal window

```
# Upload a single local fileaws s3 cp local-archive.tar.gz s3://my-assets-bucket/backups/
# Recursively upload an entire directory treeaws s3 cp ./local-dir s3://my-assets-bucket/backups/ --recursive
```

-   \--recursive works the same for local-to-S3, S3-to-local, and S3-to-S3 copies.

#### Idempotent sync with strict deletion

Compares sizes and timestamps, transfers only deltas, and removes remote objects no longer present locally.

Code

Terminal window

```
# Upload only changed files; delete remote files missing locallyaws s3 sync ./dist/ s3://my-static-web-bucket/ --delete
```

-   sync is content-aware and recursive by default.
-   \--delete is destructive. It purges orphaned objects, which suits static sites and is dangerous for shared buckets.

#### Move objects while stacking exclusion filters

Recursively moves files matching an extension to a new bucket, deleting them from the source on success.

Code

Terminal window

```
# Move only .csv files, then delete them from the sourceaws s3 mv s3://my-source-bucket/logs/ s3://my-destination-bucket/archive-logs/ \  --recursive \  --exclude "*" \  --include "*.csv"
```

-   Filters evaluate left to right. To target only .csv, exclude everything first (\*), then re-include \*.csv.

### Data Analytics, Deletion & Secure Sharing

Audit storage footprints, purge large prefixes, and share private objects with third parties without provisioning IAM users.

#### Accessibility

Presigned URLs are an accessible way to share proprietary reports or binaries with external clients who have no AWS credentials.

#### Best Practices

-   Keep presigned URL expiry to the minimum time needed for the transfer to reduce the risk of leaked links.

#### Common Errors

-   **NoSuchBucket exception during list or delete operations.:** Check the bucket name spelling and confirm the CLI profile targets the region where the bucket actually lives.

#### Advanced Notes

-   **Recursive rm vs S3 lifecycle policies:** aws s3 rm --recursive works, but on millions of objects it makes millions of individual HTTP requests, which is slow and expensive. For massive purges, use an S3 Lifecycle Expiration Policy so AWS deletes asynchronously at no API cost.

#### Keywords

AWS CLIS3presign

#### Recursive audit of storage consumption

Crawls the prefix tree, formats byte counts into readable units, and summarizes total storage used.

Code

Terminal window

```
# Total object count and size under a prefix, in human unitsaws s3 ls s3://my-assets-bucket/images/ --recursive --human-readable --summarize
```

Output

```
12026-03-25 10:15:32    2.4 MiB  images/logo.png22026-03-25 11:42:01   15.1 MiB  images/hero.png3
4Total Objects: 25Total Size: 17.5 MiB
```

-   Handy for spotting storage anomalies from the terminal without touching CloudWatch.

#### Purge a nested prefix

Recursively deletes all objects beneath the key prefix.

Code

Terminal window

```
# Recursively delete every object under the prefixaws s3 rm s3://my-assets-bucket/temp-logs/ --recursive
```

-   S3 folders are logical only. Deleting all keys sharing a prefix effectively removes the folder.

#### Mint a temporary presigned URL

Generates a signed HTTP link that lets an unauthenticated user download a restricted object until the signature expires.

Code

Terminal window

```
# Signed download link valid for 3600 secondsaws s3 presign s3://my-assets-bucket/reports/financials.pdf --expires-in 3600
```

Output

```
1https://my-assets-bucket.s3.amazonaws.com/reports/financials.pdf?AWSAccessKeyId=AKIA...&Signature=abcd...&Expires=1774431600
```

-   The default expiry is 3600 seconds (1 hour).
-   An IAM user can sign up to 604800 seconds (7 days). With STS temporary credentials, it cannot exceed the role's session duration.

## Identity & Access Management (IAM)

Verify the executing principal, define trust and permission policies, and provision least-privilege roles from the terminal.

### Principal Auditing & Verification

Confirm which identity and account a command will run against before it executes, which matters in multi-account Organizations.

#### Accessibility

Add an identity check at the top of every automation script so it halts immediately if the environment maps to the wrong account.

#### Best Practices

-   Use JMESPath to enforce account checks in scripts, for example ACT\_ID=$(aws sts get-caller-identity --query Account --output text).

#### Common Errors

-   **An error occurred (AccessDenied) when calling get-caller-identity.:** This is an authentication failure, not a permissions boundary. Confirm the access keys are structurally valid and that traffic can reach STS endpoints.

#### Advanced Notes

-   **Parsing assumed-role ARNs:** Under an assumed role or SSO federation, the ARN is not a standard IAM user. It reflects STS assumption: arn:aws:sts::123456789012:assumed-role/RoleName/SessionName.

#### Keywords

AWS CLIIAMSTSsecurity

#### Interrogate the active STS context

Validates the authentication tokens and returns the User ID, Account ID, and identity ARN.

Code

Terminal window

```
# The "whoami" of AWS - who am I and in which account?aws sts get-caller-identity
```

Output

```
1{2    "UserId": "AIDASODNN7EXAMPLE",3    "Account": "123456789012",4    "Arn": "arn:aws:iam::123456789012:user/developer-admin"5}
```

-   Think of it as whoami for AWS.

#### List all account users

Returns a JSON array of metadata, creation dates, and ARNs for every IAM user in the account.

Code

Terminal window

```
# Enumerate IAM users with metadata and ARNsaws iam list-users
```

-   Useful for compliance audits and spotting unauthorized "ghost" users.

### Role Delegation & Trust Policies

Roles decouple permissions from static credentials. Creating one splits into a trust policy (who can assume it) and a permissions policy (what it can do).

#### Accessibility

Move workloads off hardcoded secrets by binding IAM execution roles to EC2 instance profiles and ECS task definitions.

#### Best Practices

-   Enforce least privilege. Tighten trust policies with a Condition block to limit sts:AssumeRole to specific org boundaries or source IPs.

#### Common Errors

-   **MalformedPolicyDocument exception halts role creation.:** The JSON payload has a syntax error. Validate the file, or when passing strings inline, escape nested quotes with backslashes.

#### Advanced Notes

-   **Local file path formats:** The file:// parameter is picky about paths. On Unix/Linux/macOS use file://path/to/policy.json. On Windows use drive notation: file://C:\\path\\to\\policy.json.

#### Keywords

AWS CLIIAMrolestrust-policy

#### Provision a service role from a JSON trust document

Creates a role that delegates sts:AssumeRole to the EC2 service principal, letting instances wear the role.

Code

Terminal window

```
# 1. Save the trust policy to ec2-trust.json:# {#   "Version": "2012-10-17",#   "Statement": [#     {#       "Effect": "Allow",#       "Principal": { "Service": "ec2.amazonaws.com" },#       "Action": "sts:AssumeRole"#     }#   ]# }
# 2. Create the role from that documentaws iam create-role \  --role-name ComputeS3ReadOnly \  --assume-role-policy-document file://ec2-trust.json
```

-   \--assume-role-policy-document needs the file:// prefix to read the local JSON file.
-   A trust policy is a resource-based policy attached to the role itself.

#### Attach a managed permissions policy to a role

Attaches an AWS-managed read-only policy to the new role, defining its downstream privileges.

Code

Terminal window

```
# Grant the role read-only S3 accessaws iam attach-role-policy \  --role-name ComputeS3ReadOnly \  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
```

-   This action completes instantly and returns no JSON body on success.

## Data Querying with JMESPath

Filter and reshape JSON responses client-side with the built-in --query engine, no jq or awk required.

### Projections, Filtering & Analytics

Isolate nested keys, restructure dictionaries, run logical checks, and apply math functions against arrays.

#### Accessibility

\--query improves script reliability by piping only exact targets (like a pure list of instance IDs) to downstream commands.

#### Best Practices

-   Wrap the whole --query string in single quotes in bash so the shell does not expand brackets, braces, or asterisks.

#### Common Errors

-   **Bad value for --query: Parse error at column...:** Usually a quote mismatch. On Unix wrap the outer query in single quotes and use double quotes or backticks inside. On Windows CMD the outer string often needs double quotes with deeper escaping.

#### Advanced Notes

-   **JMESPath function arsenal:** JMESPath goes beyond filtering with built-in functions: - length(x): element count of an array or string. Example: length(Reservations\[\]). - sort\_by(x, &key): sort an array by a key. Example: sort\_by(Images, &CreationDate). - starts\_with(s, prefix): boolean prefix test. Example: starts\_with(Name, 'prod-'). - contains(x, val): membership test on strings or arrays. Example: contains(Tags\[\].Key, 'Env'). - join(delim, x): concatenate an array into one string. Example: join(',', InstanceIds).

#### Keywords

AWS CLIJMESPath\--queryJSON

#### Extract a flat list of running instance IDs

Traverses the nested reservations array, filters to active nodes, and returns a flat space-delimited string of IDs.

Code

Terminal window

```
# Filter to running nodes and return only their IDs, space-delimitedaws ec2 describe-instances \  --query "Reservations[].Instances[?State.Name=='running'].InstanceId" \  --output text
```

Output

```
1i-0123456789abcdef0 i-0987654321fedcba0
```

-   The empty projection \[\] flattens the nested arrays.
-   String comparisons must use single quotes ('running').

#### Project metadata into custom JSON mappings

Builds new dictionaries by mapping native AWS keys to custom aliases.

Code

Terminal window

```
# Rename fields into a custom, readable shapeaws ec2 describe-instances \  --query "Reservations[].Instances[].{NodeID:InstanceId,ComputeType:InstanceType,Zone:Placement.AvailabilityZone}"
```

Output

```
1[2    {3        "NodeID": "i-0123456789abcdef0",4        "ComputeType": "t3.medium",5        "Zone": "us-east-1a"6    }7]
```

-   Multi-select hashes use comma-separated NewName:OldName pairs inside curly braces {}.

#### Apply numerical logic and array functions

Shows numerical operators and built-in functions to filter by size and calculate lengths.

Code

Terminal window

```
# Volumes larger than 100 GBaws ec2 describe-volumes \  --query "Volumes[?Size > \`100\`].{ID:VolumeId,Size:Size}"
# Count of running instancesaws ec2 describe-instances \  --query "length(Reservations[].Instances[?State.Name=='running'])"
```

-   Numeric literals must be wrapped in backticks (for example, \`100\`) so they parse as integers, not strings.
-   length() works on strings, arrays, and objects.

## Serialization & Output Formats

Switch the output serializer at runtime to suit humans reading diagnostics or machines consuming automated streams.

### Formatting Types (table, text, json, yaml)

Render ASCII tables for reporting, strip syntax for scripting, keep JSON for payloads, or emit YAML for IaC audits.

#### Accessibility

\--output table adds visual clarity for manual checks and lowers cognitive load when scanning for misconfigured parameters.

#### Best Practices

-   Use --output text when capturing output into shell variables (ID=$(aws ec2 ...)). It strips quotes and brackets, saving you messy sed cleanup.

#### Common Errors

-   **The table format shows blanks, fails to align, or prints 'None'.:** ASCII tables cannot render flat strings or deeply nested arrays. Project the data into a clean, uniform list of simple dictionaries first.

#### Advanced Notes

-   **Output format changes pagination behavior:** Format silently affects pagination. With --output text, data is paginated before --query runs, so the query runs on each page. With --output json, the CLI pulls all pages, aggregates them, then runs --query once. This explains seemingly intermittent missing data.

#### Keywords

AWS CLI\--outputautomationformatting

#### Render metadata as an ASCII table

Interprets the projected dictionaries and aligns them into labeled columns.

Code

Terminal window

```
# Project fields, then format as a tableaws ec2 describe-instances \  --query "Reservations[].Instances[].{ID:InstanceId,Zone:Placement.AvailabilityZone}" \  --output table
```

Output

```
1------------------------------------------------2|               DescribeInstances              |3+-----------------------+----------------------+4|  ID                   |  Zone                |5+-----------------------+----------------------+6|  i-0123456789abcdef0  |  us-east-1a          |7|  i-0987654321fedcba0  |  us-east-1a          |8+-----------------------+----------------------+
```

-   Table rendering needs JMESPath multi-select hashes ({Key: Value}) to build columns correctly.

#### Emit YAML for GitOps-friendly output

Dumps nested response parameters into legible YAML.

Code

Terminal window

```
# Dump structured output as readable YAMLaws sts get-caller-identity --output yaml
```

Output

```
1Account: '123456789012'2Arn: arn:aws:iam::123456789012:user/admin-developer3UserId: AIDASODNN7EXAMPLE
```

-   Handy for capturing current system state into GitOps repositories.

## Systems Manager (SSM) Security

Replace SSH and bastion hosts with SSM Session Manager, routing encrypted shells and tunnels over the AWS backbone with no inbound ports.

### Interactive Shells & Secure Tunnels

The SSM agent makes outbound connections to the Systems Manager endpoint, so you never open inbound security group rules.

#### Accessibility

For instances in private subnets with no internet gateway, deploy VPC interface endpoints (notably ssmmessages) to reach the SSM control plane.

#### Best Practices

-   Eliminate bastion hosts and close inbound port 22 in every security group, routing all access through auditable Session Manager connections.

#### Common Errors

-   **An error occurred (TargetNotConnected) when calling the StartSession operation.:** The SSM Agent cannot reach the control plane. Confirm the agent is running, the instance profile has AmazonSSMManagedInstanceCore, and VPC endpoints or a NAT gateway provide outbound routing.

#### Advanced Notes

-   **Session logging and audit trails:** Unlike SSH, Session Manager integrates with auditing. Session input and output can be tracked, encrypted with AWS KMS, and streamed to S3 buckets or CloudWatch Log groups for compliance.

#### Keywords

AWS CLIEC2automationSession ManagerSSM

#### Start an interactive shell without SSH

Opens a secure real-time terminal directly inside the target EC2 instance.

Code

Terminal window

```
# Open a secure terminal on the instance, no SSH key neededaws ssm start-session --target i-0123456789abcdef0
```

Output

```
1Starting session with SessionId: developer-admin-0123456789abcdef02sh-4.2$
```

-   Requires the Session Manager plugin installed on your local machine.
-   The instance must run the SSM Agent and have AmazonSSMManagedInstanceCore attached to its instance profile.

#### Open a secure local port-forwarding tunnel

Routes traffic from your local port 33060 through SSM into port 3306 on the private EC2 target.

Code

Terminal window

```
# Forward local port 33060 to port 3306 on the private instanceaws ssm start-session \  --target i-0123456789abcdef0 \  --document-name AWS-StartPortForwardingSession \  --parameters '{"portNumber":["3306"],"localPortNumber":["33060"]}'
```

Output

```
1Starting session with SessionId: local-tunnel-01234...2Port 33060 opened for session id local-tunnel-01234...
```

-   Uses the AWS-StartPortForwardingSession document to build the tunnel.
-   Lets a local DB client reach a private database tier with no internet exposure.

## Pagination & Waiters

Control how the CLI fetches multi-page results, block until a resource reaches a state, and reuse JSON input skeletons.

### Controlling Pagination

Tune per-call size and total items, or disable auto-pagination entirely.

#### Best Practices

-   Use --page-size to avoid throttling on large accounts and --max-items only to limit output; treating them as the same thing causes surprises.

#### Common Errors

-   **A truncated result with a printed NextToken.:** More data remains. Resume with --starting-token <token> rather than assuming the list is complete.

#### Keywords

paginationpage-sizemax-items

#### Page size, item cap, and resuming

\--page-size sets the per-request round-trip size; --max-items caps total output and prints a NextToken if more remains.

Code

Terminal window

```
aws ec2 describe-instances --page-size 20   # 20 items per API callaws iam list-users --max-items 50           # cap total returned at 50aws iam list-users --max-items 50 --starting-token <token> # resume
```

-   \--page-size and --max-items are independent. One controls API load, the other how much you get back.

### Waiters & JSON Skeletons

Block until a state is reached, and generate or reuse structured JSON input.

#### Best Practices

-   Chain a waiter after any create/start command in scripts instead of sleep loops. Waiters fail fast on terminal errors rather than waiting out the timeout.

#### Keywords

waitcli-input-jsongenerate-cli-skeleton

#### Wait for a resource state

Waiters poll on the right interval and exit non-zero on failure or a terminal state like ROLLBACK.

Code

Terminal window

```
aws ec2 wait instance-running --instance-ids i-0abc123aws cloudformation wait stack-create-complete --stack-name my-stack
```

#### Generate and reuse a JSON skeleton

Emit a template of every parameter, edit it, then run from the file instead of long inline flags.

Code

Terminal window

```
aws ec2 run-instances --generate-cli-skeleton input > params.jsonaws ec2 run-instances --cli-input-json file://params.json
```

## STS & Cross-Account Access

Assume IAM roles for temporary credentials, export them, and configure automatic role assumption with MFA.

### Assuming Roles

Request temporary credentials for a cross-account role and export them to the environment.

#### Best Practices

-   Prefer source\_profile + role\_arn in config over manual export. The CLI assumes and refreshes automatically, while static exports expire mid-task and leak easily.

#### Common Errors

-   **An error occurred (ExpiredToken): the security token included in the request is expired.:** Temporary credentials aged out (default 1 hour). Re-run assume-role, or use a config profile that auto-refreshes.

#### Keywords

stsassume-rolesession-token

#### Assume a role and export the credentials

Temporary credentials require all three variables, including AWS\_SESSION\_TOKEN. A meaningful --role-session-name shows up in CloudTrail.

Code

Terminal window

```
aws sts assume-role \  --role-arn arn:aws:iam::222222222222:role/DeployRole \  --role-session-name deploy# export via --query (repeat for SecretAccessKey and SessionToken)export AWS_ACCESS_KEY_ID=$(aws sts assume-role --role-arn <arn> \  --role-session-name s --query 'Credentials.AccessKeyId' --output text)
```

### Config-File Assumption & MFA

Assume roles transparently from a named profile, including MFA-protected roles.

#### Best Practices

-   Keep a long-lived base profile as source\_profile and put mfa\_serial in config; the cached session means one OTP prompt instead of one per command.

#### Keywords

source\_profilerole\_arnmfa\_serial

#### A role-assuming profile with MFA

The CLI assumes the role transparently and caches the MFA-backed session, so you enter the token code once, not per command.

Code

~/.aws/config

```
[profile deploy]role_arn       = arn:aws:iam::222222222222:role/DeployRolesource_profile = defaultmfa_serial     = arn:aws:iam::111111111111:mfa/alice# then: aws s3 ls --profile deploy  (prompts for the OTP once)
```

-   credential\_process = /path/to/program delegates credential retrieval to an external helper that outputs JSON.

## CloudWatch Logs

Stream, search, and manage retention on CloudWatch Logs groups from the terminal.

### Tailing & Searching

Live-tail new events or search historical events across all streams in a group.

#### Best Practices

-   Combine --follow with --since (e.g. --since 10m) so you get recent context immediately rather than waiting only for brand-new events.

#### Common Errors

-   **ResourceNotFoundException: the specified log group does not exist.:** Usually a typo or wrong region. Confirm the exact name with aws logs describe-log-groups and check --region.

#### Keywords

logstailfilter-log-events

#### Tail live and search history

tail --follow streams new events; --since adds recent context; filter-log-events searches history.

Code

Terminal window

```
aws logs tail /aws/lambda/my-func --follow --since 1h # like tail -faws logs tail /aws/lambda/my-func --follow --filter-pattern ERRORaws logs filter-log-events --log-group-name /aws/lambda/my-func \  --filter-pattern "ERROR" # search all streams
```

-   filter-log-events uses epoch MILLISECONDS for --start-time/--end-time. Generate them with date -d '1 hour ago' +%s000.

### Groups & Retention

List log groups and control how long events are retained.

#### Best Practices

-   Set a retention policy on every log group. The default "never expire" grows storage cost forever.

#### Keywords

describe-log-groupsput-retention-policyretention

#### Set a retention policy

New groups never expire by default; put-retention-policy caps storage (valid values include 1, 7, 14, 30, 90, 365 days).

Code

Terminal window

```
aws logs describe-log-groups --log-group-name-prefix /aws/lambda/aws logs put-retention-policy --log-group-name /aws/lambda/my-func \  --retention-in-days 30
```

## Lambda

List, inspect, invoke, and deploy Lambda functions, including the AWS CLI v2 base64 payload gotcha.

### Inspecting & Invoking

Read function config and invoke functions synchronously or asynchronously.

#### Best Practices

-   Use get-function-configuration (not get-function) when you only need settings. It skips generating the code-download URL and returns faster.

#### Common Errors

-   **Invalid base64: "{"name":"Bob"}".:** Add --cli-binary-format raw-in-base64-out (or set it as default) so --payload is read as raw JSON in AWS CLI v2.

#### Keywords

lambdainvokecli-binary-format

#### Invoke with a raw JSON payload

In v2 --payload is base64 by default; --cli-binary-format raw-in-base64-out lets you pass literal JSON. The output file is a required positional arg.

Code

Terminal window

```
aws lambda invoke --function-name my-func \  --cli-binary-format raw-in-base64-out \  --payload '{"name":"Bob"}' response.jsonaws lambda list-functions --query 'Functions[].FunctionName' --output text
```

-   Set it once with aws configure set cli-binary-format raw-in-base64-out to omit the flag on future invokes.

### Deploying Code

Ship a new zip or image and change runtime settings without redeploying.

#### Best Practices

-   After an update, wait with aws lambda wait function-updated --function-name my-func before the next change to avoid ResourceConflictException.

#### Keywords

update-function-codefilebupdate-function-configuration

#### Deploy a new package

Use fileb:// (binary), not file:// (text), for --zip-file, because file:// UTF-8-decodes the archive and corrupts the upload.

Code

Terminal window

```
aws lambda update-function-code --function-name my-func \  --zip-file fileb://function.zip # fileb:// reads raw binaryaws lambda update-function-configuration --function-name my-func \  --timeout 30 --memory-size 512
```

## Secrets & Parameter Store

Retrieve and write secrets from Secrets Manager and SSM Parameter Store, including encrypted SecureString handling.

### Secrets Manager

Create secrets and fetch their values, optionally pulling a single JSON field.

#### Best Practices

-   Reference secrets by full ARN when identical names might exist across replicated regions, to avoid ambiguity.

#### Keywords

secretsmanagerget-secret-valueSecretString

#### Read and create secrets

\--query SecretString --output text strips the JSON envelope; pipe to jq -r .password to pull one field.

Code

Terminal window

```
aws secretsmanager get-secret-value --secret-id prod/db \  --query SecretString --output textaws secretsmanager create-secret --name prod/db \  --secret-string '{"user":"admin","password":"s3cr3t"}'
```

### SSM Parameter Store

Read and write plain and encrypted parameters, and load a whole path in one call.

#### Best Practices

-   Use SecureString for static config secrets (cheaper) and Secrets Manager where built-in automatic rotation matters.

#### Common Errors

-   **A SecureString value comes back as an unreadable KMS blob.:** You forgot --with-decryption. Add it, and give the caller kms:Decrypt on the key.

#### Keywords

ssmget-parameterSecureString

#### Read and write parameters

\--with-decryption returns the plaintext of a SecureString (needs kms:Decrypt); --overwrite is required to update an existing parameter.

Code

Terminal window

```
aws ssm get-parameter --name /prod/db/password --with-decryption \  --query 'Parameter.Value' --output textaws ssm get-parameters-by-path --path /prod/db/ --recursive --with-decryptionaws ssm put-parameter --name /prod/db/password --value 's3cr3t' \  --type SecureString --overwrite
```

-   Namespace parameters as /app/env/key so get-parameters-by-path --recursive loads a whole environment in one request.

## ECR & Containers

Authenticate Docker to ECR, manage repositories and images, and trigger ECS redeployments.

### Auth, Repositories & Images

Log Docker into ECR and manage repositories and images.

#### Best Practices

-   Always pipe get-login-password into --password-stdin; never pass the token as --password where it lands in shell history.

#### Common Errors

-   **denied: your authorization token has expired. Reauthenticate and try again.:** The ECR token lasts only 12 hours. Re-run the get-login-password | docker login command.

#### Keywords

ecrget-login-passworddocker

#### Authenticate Docker to ECR

Pipes a 12-hour token into docker login via stdin, keeping it out of shell history and the process list.

Code

Terminal window

```
aws ecr get-login-password --region us-east-1 | docker login \  --username AWS --password-stdin \  111111111111.dkr.ecr.us-east-1.amazonaws.com
```

-   The old aws ecr get-login (which printed docker login -p <token>) is removed in AWS CLI v2, so get-login-password is the only supported command.

#### Create a repo and list images

scanOnPush=true enables vulnerability scanning on push; filtering untagged images finds cleanup candidates.

Code

Terminal window

```
aws ecr create-repository --repository-name my-app \  --image-scanning-configuration scanOnPush=trueaws ecr list-images --repository-name my-app --filter tagStatus=UNTAGGED
```

### ECS Deployments

Force a service to redeploy or scale its running task count.

#### Best Practices

-   For auditable rollbacks, prefer immutable image tags and a new task-definition revision over force-redeploying a mutable :latest tag.

#### Keywords

ecsupdate-serviceforce-new-deployment

#### Force a redeploy or scale

\--force-new-deployment rolls tasks to the newest image on a mutable tag; --desired-count scales the running task count.

Code

Terminal window

```
aws ecs update-service --cluster prod --service web \  --force-new-deployment # pull latest :tag, same task defaws ecs update-service --cluster prod --service web --desired-count 4
```

Was this useful?

## Tags

#AWS CLI#EC2#S3#IAM#Automation#JMESPath#SSM

## Share

[Facebook](https://facebook.com/sharer/sharer.php?u=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Faws-cli "Share on Facebook")[Twitter](https://twitter.com/intent/tweet/?text=AWS%20CLI&url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Faws-cli "Share on Twitter")[LinkedIn](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Faws-cli&title=AWS%20CLI&summary=An%20expert%20reference%20for%20the%20AWS%20CLI%20covering%20configuration%20precedence%2C%20EC2%20lifecycle%20control%2C%20recursive%20S3%20operations%2C%20JMESPath%20querying%2C%20output%20formatting%2C%20and%20secure%20SSM%20sessions.&source=https://mkabumattar.com "Share on LinkedIn")[WhatsApp](https://wa.me/?text=AWS%20CLI%20https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Faws-cli "Share on WhatsApp")[Telegram](https://t.me/share/url?url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Faws-cli&text=AWS%20CLI "Share on Telegram")[Reddit](https://www.reddit.com/submit?url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Faws-cli&title=AWS%20CLI "Share on Reddit")[Hacker News](http://news.ycombinator.com/submitlink?u=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Faws-cli&t=AWS%20CLI "Share on Hacker News")[Pinterest](https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Faws-cli&media=&description=An%20expert%20reference%20for%20the%20AWS%20CLI%20covering%20configuration%20precedence%2C%20EC2%20lifecycle%20control%2C%20recursive%20S3%20operations%2C%20JMESPath%20querying%2C%20output%20formatting%2C%20and%20secure%20SSM%20sessions. "Share on Pinterest")[Email](<mailto:?subject=AWS%20CLI&body=Check out this article: https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Faws-cli>)

## Comments

## You might also enjoy

More posts on similar topics

## [kubectl](/cheatsheets/kubectl)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   DevOps
-   Kubernetes
-   CLI
-   Container Orchestration
-   Cloud Native

kubectl is the command-line tool you use to talk to a Kubernetes cluster. Whatever you can do through a dashboard, you can do faster here: deploy apps, inspect resources, stream logs, run commands ins

#Kubectl#Kubernetes#K8s+5 tags

[read more](/cheatsheets/kubectl)

## [Linux Networking](/cheatsheets/linux-networking)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Linux
-   Networking
-   DevOps
-   CLI
-   SysAdmin

Every Linux box speaks the network through a small set of tools, and knowing them turns "the network is broken" into a specific, fixable answer. This cheatsheet covers the modern stack: ip for inter

#Linux networking#Ip command#Tcpdump+5 tags

[read more](/cheatsheets/linux-networking)

## [GitHub Actions](/cheatsheets/github-actions)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   CI/CD
-   DevOps
-   GitHub
-   Automation
-   YAML

GitHub Actions runs your CI/CD directly from YAML files in .github/workflows/, and most of the job is knowing which key does what. A workflow reacts to events, splits into jobs that run on runners,

#GitHub Actions#Workflow#CI/CD+5 tags

[read more](/cheatsheets/github-actions)

## [Bash](/cheatsheets/bash)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Scripting
-   Shell
-   Linux
-   Unix
-   Command Line
-   Automation

Bash is a Unix shell and command language written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell. The sections below cover Bash commands, syntax, and examples.

#Scripting#Shell#Linux+3 tags

[read more](/cheatsheets/bash)

## [Cron](/cheatsheets/cron)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Terminal
-   System Administration
-   Linux
-   Scheduling
-   Automation
-   Tools

Quick reference Field layout Min Hour Day Month Weekday Command\* /path/to/command ┬ ┬ ┬ ┬ ┬ │ │ │ │ └───── Weekday (0=Sunday,

#Cron#Crontab#Scheduling+3 tags

[read more](/cheatsheets/cron)

## [Terraform Cheatsheet](/cheatsheets/terraform)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Infrastructure as Code
-   DevOps

A practical cheatsheet covering the Terraform CLI commands engineers reach for constantly: init, plan, apply, import, taint, and state operations. It also covers the key HCL patterns for variables, lo

#Terraform#HCL#State management+3 tags

[read more](/cheatsheets/terraform)

6 related posts
