AWS CLI
The AWS CLI Mental Model
Section titled “The AWS CLI Mental Model”Every single AWS CLI command follows this pattern:
aws <service> <action> [--option value] [--option value]<service>=iam,s3,ec2,rds,lambda,vpc(it’s actuallyec2for VPC too)<action>= verb likelist-,create-,delete-,describe-,attach-,put-,get-- options =
-flags that qualify the action
The 4 action prefixes you’ll use 90% of the time:
list-/describe-→ read/query stuffcreate-/run-/put-/add-→ make stuffdelete-/remove-/detach-→ destroy/disconnect stuffattach-/associate-→ link stuff together
If you can guess the verb, you can guess the command. That’s the whole game.
Setup & Config First
Section titled “Setup & Config First”# Install (on ubuntu/debian)sudo apt install awscli# or via pip (gets you latest v2)pip install awscli --break-system-packages
# Configure credentialsaws configure# prompts: Access Key ID, Secret Access Key, region (ap-south-1 for Mumbai), output format (json)
# Config is stored here:cat ~/.aws/credentialscat ~/.aws/config
# Multiple profiles (for multiple accounts)aws configure --profile myprofileaws s3 ls --profile myprofile
# Set default profile in shellexport AWS_PROFILE=myprofile
# Quick sanity check — who am I?aws sts get-caller-identityIAM — Identity & Access Management
Section titled “IAM — Identity & Access Management”The Mental Model for IAM
Section titled “The Mental Model for IAM”IAM has 4 core concepts. Know these cold:
- User → a person or app with long-term credentials (access keys / password)
- Group → a collection of users, you attach policies to the group
- Role → an identity assumed temporarily (by EC2, Lambda, another AWS account, etc.) — no long-term credentials
- Policy → a JSON document that says what’s allowed/denied. Attached to users, groups, or roles.
Policy attachment chain:
Policy → attached to → User / Group / RoleIAM Users
Section titled “IAM Users”# List all usersaws iam list-users
# List users with cleaner output (query is JMESPath)aws iam list-users --query 'Users[*].[UserName,UserId,CreateDate]' --output table
# Create a useraws iam create-user --user-name john
# Get details of a specific useraws iam get-user --user-name john
# Create login profile (console password) for a useraws iam create-login-profile --user-name john --password 'SecurePass@123' --password-reset-required
# Update a user's console passwordaws iam update-login-profile --user-name john --password 'NewPass@456'
# Create access keys (programmatic access) for a useraws iam create-access-key --user-name john# SAVE the output — SecretAccessKey shown only once
# List access keys for a useraws iam list-access-keys --user-name john
# Deactivate an access keyaws iam update-access-key --user-name john --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive
# Delete an access keyaws iam delete-access-key --user-name john --access-key-id AKIAIOSFODNN7EXAMPLE
# Delete a user (must clean up dependencies first)aws iam delete-user --user-name john
# List all users in the account with their ARNsaws iam list-users --query 'Users[*].Arn' --output textIAM Groups
Section titled “IAM Groups”# List all groupsaws iam list-groups
# Create a groupaws iam create-group --group-name Developers
# Add a user to a groupaws iam add-user-to-group --group-name Developers --user-name john
# List users in a groupaws iam get-group --group-name Developers
# List groups a user belongs toaws iam list-groups-for-user --user-name john
# Remove user from groupaws iam remove-user-from-group --group-name Developers --user-name john
# Delete groupaws iam delete-group --group-name DevelopersIAM Policies
Section titled “IAM Policies”# List AWS managed policies (there are 1000s — filter it)aws iam list-policies --scope AWS --query 'Policies[?PolicyName==`AdministratorAccess`]'
# List only customer managed policiesaws iam list-policies --scope Local
# Find a specific AWS managed policy ARN (you need this to attach)aws iam list-policies --scope AWS --query 'Policies[?PolicyName==`AmazonS3FullAccess`].Arn' --output text
# Get policy detailsaws iam get-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
# Get the actual JSON of a policy (need version id first)aws iam get-policy-version \\ --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess \\ --version-id v1
# Create a custom policy from a JSON fileaws iam create-policy \\ --policy-name MyCustomPolicy \\ --policy-document file://policy.json
# Example policy.json:cat > policy.json << 'EOF'{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject"], "Resource": "arn:aws:s3:::my-bucket/*" } ]}EOF
# Delete a customer managed policyaws iam delete-policy --policy-arn arn:aws:iam::<account-id>:policy/MyCustomPolicyAttaching Policies — Users, Groups, Roles
Section titled “Attaching Policies — Users, Groups, Roles”# Attach AWS managed policy directly to a useraws iam attach-user-policy \\ --user-name john \\ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# Attach policy to a groupaws iam attach-group-policy \\ --group-name Developers \\ --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess
# Attach policy to a roleaws iam attach-role-policy \\ --role-name MyLambdaRole \\ --policy-arn arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess
# List policies attached to a useraws iam list-attached-user-policies --user-name john
# List policies attached to a groupaws iam list-attached-group-policies --group-name Developers
# List policies attached to a roleaws iam list-attached-role-policies --role-name MyLambdaRole
# Detach policy from useraws iam detach-user-policy \\ --user-name john \\ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# Inline policies (embedded directly, not reusable) — use sparinglyaws iam put-user-policy \\ --user-name john \\ --policy-name InlineS3Policy \\ --policy-document file://policy.json
# List inline policies on a useraws iam list-user-policies --user-name john
# Get an inline policyaws iam get-user-policy --user-name john --policy-name InlineS3Policy
# Delete inline policyaws iam delete-user-policy --user-name john --policy-name InlineS3PolicyIAM Roles
Section titled “IAM Roles”Roles are what EC2, Lambda, ECS tasks etc. use to get AWS permissions without hardcoding keys.
# List all rolesaws iam list-roles
# List roles with just namesaws iam list-roles --query Roles[*].RoleName --output text
# Create a role — needs a trust policy (who can assume this role)# Trust policy for EC2:cat > trust-policy.json << 'EOF'{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ]}EOF
aws iam create-role \\ --role-name MyEC2Role \\ --assume-role-policy-document file://trust-policy.json
# Trust policy for Lambda:# change "Service": "lambda.amazonaws.com"
# Trust policy for another AWS account to assume this role:# "Principal": { "AWS": "arn:aws:iam::<other-account-id>:root" }
# Get role details (including trust policy)aws iam get-role --role-name MyEC2Role
# Attach policy to roleaws iam attach-role-policy \\ --role-name MyEC2Role \\ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# Create instance profile (needed to attach a role to EC2)aws iam create-instance-profile --instance-profile-name MyEC2Profile
# Add role to instance profileaws iam add-role-to-instance-profile \\ --instance-profile-name MyEC2Profile \\ --role-name MyEC2Role
# List instance profilesaws iam list-instance-profiles
# Delete role (detach all policies first)aws iam detach-role-policy \\ --role-name MyEC2Role \\ --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
aws iam delete-role --role-name MyEC2RoleChecking Permissions (Simulate & Audit)
Section titled “Checking Permissions (Simulate & Audit)”# Simulate whether a user/role CAN do somethingaws iam simulate-principal-policy \\ --policy-source-arn arn:aws:iam::<account-id>:user/john \\ --action-names s3:GetObject \\ --resource-arns arn:aws:s3:::my-bucket/file.txt
# Get credential report (CSV of all users + their MFA/key status)aws iam generate-credential-reportaws iam get-credential-report --query 'Content' --output text | base64 -d
# List all policies attached to a user (managed + inline + via groups)# There's no single command for this — combine:aws iam list-attached-user-policies --user-name john # managed policies directaws iam list-user-policies --user-name john # inline policiesaws iam list-groups-for-user --user-name john # groups (then check group policies)
# Get the full access report for a role/useraws iam generate-service-last-accessed-details \\ --arn arn:aws:iam::<account-id>:user/john
# Then fetch it (takes a second, use the JobId from above)aws iam get-service-last-accessed-details --job-id <job-id># List MFA devices for a useraws iam list-mfa-devices --user-name john
# List virtual MFA devices in the accountaws iam list-virtual-mfa-devices
# Create a virtual MFA deviceaws iam create-virtual-mfa-device \\ --virtual-mfa-device-name john-mfa \\ --outfile /tmp/john-mfa-qr.png \\ --bootstrap-method QRCodePNG# Scan the QR code with Google Authenticator / Authy
# Enable/associate MFA for a user (need 2 consecutive OTP codes)aws iam enable-mfa-device \\ --user-name john \\ --serial-number arn:aws:iam::<account-id>:mfa/john-mfa \\ --authentication-code1 123456 \\ --authentication-code2 789012
# Deactivate MFA for a useraws iam deactivate-mfa-device \\ --user-name john \\ --serial-number arn:aws:iam::<account-id>:mfa/john-mfa
# Delete the virtual MFA device itselfaws iam delete-virtual-mfa-device \\ --serial-number arn:aws:iam::<account-id>:mfa/john-mfa
# Enforce MFA via policy — attach this policy to force MFA usage# Classic "DenyWithoutMFA" pattern:cat > enforce-mfa.json << 'EOF'{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "NotAction": ["iam:CreateVirtualMFADevice","iam:EnableMFADevice", "iam:GetUser","iam:ListMFADevices","iam:ListVirtualMFADevices", "iam:ResyncMFADevice","sts:GetSessionToken"], "Resource": "*", "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } } } ]}EOFIAM Password Policy
Section titled “IAM Password Policy”# Get account password policyaws iam get-account-password-policy
# Set password policyaws iam update-account-password-policy \\ --minimum-password-length 12 \\ --require-symbols \\ --require-numbers \\ --require-uppercase-characters \\ --require-lowercase-characters \\ --allow-users-to-change-password \\ --max-password-age 90 \\ --password-reuse-prevention 5S3 — Simple Storage Service
Section titled “S3 — Simple Storage Service”Mental Model
Section titled “Mental Model”S3 has two CLI interfaces:
aws s3→ high-level, human-friendly (cp,ls,sync,mv)aws s3api→ low-level, full control (bucket policies, ACLs, versioning, etc.)
Use s3 for day-to-day file ops, s3api for configuration.
# List all bucketsaws s3 ls
# List contents of a bucketaws s3 ls s3://my-bucketaws s3 ls s3://my-bucket/some/prefix/ --recursive
# Create a bucketaws s3 mb s3://my-unique-bucket-name# In specific region:aws s3 mb s3://my-unique-bucket-name --region ap-south-1
# Delete empty bucketaws s3 rb s3://my-bucket
# Delete bucket and all contents (nuclear option)aws s3 rb s3://my-bucket --force
# Upload fileaws s3 cp localfile.txt s3://my-bucket/aws s3 cp localfile.txt s3://my-bucket/folder/renamed.txt
# Download fileaws s3 cp s3://my-bucket/file.txt ./
# Upload entire directoryaws s3 cp ./mydir s3://my-bucket/mydir/ --recursive
# Sync local dir to S3 (only uploads changed/new files)aws s3 sync ./mydir s3://my-bucket/mydir/
# Sync S3 to localaws s3 sync s3://my-bucket/mydir/ ./mydir
# Sync and delete files in destination that don't exist in sourceaws s3 sync ./mydir s3://my-bucket/mydir/ --delete
# Move (copy + delete)aws s3 mv s3://my-bucket/old.txt s3://my-bucket/new.txt
# Delete a fileaws s3 rm s3://my-bucket/file.txt
# Delete all files with a prefixaws s3 rm s3://my-bucket/logs/ --recursive
# Presigned URL (temporary access link, default 1 hour)aws s3 presign s3://my-bucket/private-file.pdf# Custom expiry (in seconds)aws s3 presign s3://my-bucket/private-file.pdf --expires-in 3600S3 API — Config & Policies
Section titled “S3 API — Config & Policies”# Create bucket (s3api way — needed for LocationConstraint outside us-east-1)aws s3api create-bucket \\ --bucket my-bucket \\ --region ap-south-1 \\ --create-bucket-configuration LocationConstraint=ap-south-1
# Enable versioningaws s3api put-bucket-versioning \\ --bucket my-bucket \\ --versioning-configuration Status=Enabled
# Check versioning statusaws s3api get-bucket-versioning --bucket my-bucket
# Block all public access (do this for private buckets)aws s3api put-public-access-block \\ --bucket my-bucket \\ --public-access-block-configuration \\ BlockPublicAcls=true,IgnorePublicAcls=true,\\BlockPublicPolicy=true,RestrictPublicBuckets=true
# Get bucket policyaws s3api get-bucket-policy --bucket my-bucket
# Set bucket policyaws s3api put-bucket-policy \\ --bucket my-bucket \\ --policy file://bucket-policy.json
# Enable server-side encryption (SSE-S3)aws s3api put-bucket-encryption \\ --bucket my-bucket \\ --server-side-encryption-configuration '{ "Rules": [{ "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "AES256" } }] }'
# List object versionsaws s3api list-object-versions --bucket my-bucket
# Get object metadataaws s3api head-object --bucket my-bucket --key file.txt
# Enable static website hostingaws s3api put-bucket-website \\ --bucket my-bucket \\ --website-configuration '{ "IndexDocument": {"Suffix": "index.html"}, "ErrorDocument": {"Key": "error.html"} }'EC2 — Elastic Compute Cloud
Section titled “EC2 — Elastic Compute Cloud”Mental Model
Section titled “Mental Model”EC2’s main entities: AMI (the image), Instance (running VM), Security Group (firewall), Key Pair (SSH), EBS (disk).
# Describe all instances (verbose)aws ec2 describe-instances
# Clean list of running instancesaws ec2 describe-instances \\ --query 'Reservations[*].Instances[*].[InstanceId,State.Name,InstanceType,PublicIpAddress,Tags[?Key==`Name`].Value|[0]]' \\ --output table
# Describe instances with a filteraws ec2 describe-instances \\ --filters "Name=instance-state-name,Values=running"
# Launch an instance (bare minimum)aws ec2 run-instances \\ --image-id ami-0f58b397bc5c1f2e8 \\ # Amazon Linux 2 AMI (region-specific) --instance-type t2.micro \\ --count 1
# Launch with key pair + security group + subnetaws ec2 run-instances \\ --image-id ami-0f58b397bc5c1f2e8 \\ --instance-type t2.micro \\ --key-name my-key-pair \\ --security-group-ids sg-0123456789abcdef0 \\ --subnet-id subnet-0123456789abcdef0 \\ --count 1 \\ --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=MyServer}]'
# Launch with user-data script (runs on first boot)aws ec2 run-instances \\ --image-id ami-0f58b397bc5c1f2e8 \\ --instance-type t2.micro \\ --user-data file://userdata.sh \\ --key-name my-key-pair
# Attach IAM role to instance at launchaws ec2 run-instances \\ --image-id ami-0f58b397bc5c1f2e8 \\ --instance-type t2.micro \\ --iam-instance-profile Name=MyEC2Profile
# Stop / Start / Reboot / Terminateaws ec2 stop-instances --instance-ids i-1234567890abcdef0aws ec2 start-instances --instance-ids i-1234567890abcdef0aws ec2 reboot-instances --instance-ids i-1234567890abcdef0aws ec2 terminate-instances --instance-ids i-1234567890abcdef0
# Get public IP of an instanceaws ec2 describe-instances \\ --instance-ids i-1234567890abcdef0 \\ --query 'Reservations[0].Instances[0].PublicIpAddress' \\ --output text
# Describe available AMIs (filter by owner to avoid noise)aws ec2 describe-images \\ --owners amazon \\ --filters "Name=name,Values=amzn2-ami-hvm-*" \\ --query 'Images[*].[ImageId,Name,CreationDate]' \\ --output tableKey Pairs
Section titled “Key Pairs”# List key pairsaws ec2 describe-key-pairs
# Create a key pair and save private keyaws ec2 create-key-pair \\ --key-name my-key-pair \\ --query 'KeyMaterial' \\ --output text > my-key-pair.pem
chmod 400 my-key-pair.pem
# Import existing public keyaws ec2 import-key-pair \\ --key-name my-key-pair \\ --public-key-material fileb://~/.ssh/id_rsa.pub
# Delete key pairaws ec2 delete-key-pair --key-name my-key-pairSecurity Groups
Section titled “Security Groups”# List security groupsaws ec2 describe-security-groupsaws ec2 describe-security-groups \\ --query 'SecurityGroups[*].[GroupId,GroupName,Description]' \\ --output table
# Create security group (needs VPC ID)aws ec2 create-security-group \\ --group-name my-sg \\ --description "My security group" \\ --vpc-id vpc-0123456789abcdef0
# Add inbound rule — SSH from anywhere (don't do this in prod lol)aws ec2 authorize-security-group-ingress \\ --group-id sg-0123456789abcdef0 \\ --protocol tcp \\ --port 22 \\ --cidr 0.0.0.0/0
# Add inbound rule — HTTPaws ec2 authorize-security-group-ingress \\ --group-id sg-0123456789abcdef0 \\ --protocol tcp \\ --port 80 \\ --cidr 0.0.0.0/0
# Add inbound rule from another security group (not CIDR)aws ec2 authorize-security-group-ingress \\ --group-id sg-0123456789abcdef0 \\ --protocol tcp \\ --port 5432 \\ --source-group sg-anothergroup
# Remove inbound ruleaws ec2 revoke-security-group-ingress \\ --group-id sg-0123456789abcdef0 \\ --protocol tcp \\ --port 22 \\ --cidr 0.0.0.0/0
# Delete security groupaws ec2 delete-security-group --group-id sg-0123456789abcdef0EBS Volumes
Section titled “EBS Volumes”# List volumesaws ec2 describe-volumes
# Create a volumeaws ec2 create-volume \\ --size 20 \\ --volume-type gp3 \\ --availability-zone ap-south-1a
# Attach volume to instanceaws ec2 attach-volume \\ --volume-id vol-0123456789abcdef0 \\ --instance-id i-1234567890abcdef0 \\ --device /dev/sdf
# Detach volumeaws ec2 detach-volume --volume-id vol-0123456789abcdef0
# Create snapshotaws ec2 create-snapshot \\ --volume-id vol-0123456789abcdef0 \\ --description "My snapshot"
# List snapshotsaws ec2 describe-snapshots --owner-ids selfVPC — Virtual Private Cloud
Section titled “VPC — Virtual Private Cloud”Mental Model
Section titled “Mental Model”VPC → Subnets (public/private) → Route Tables → Internet Gateway (for public) / NAT Gateway (for private outbound) → Security Groups + NACLs.
# List VPCsaws ec2 describe-vpcsaws ec2 describe-vpcs \\ --query 'Vpcs[*].[VpcId,CidrBlock,Tags[?Key==`Name`].Value|[0]]' \\ --output table
# Create VPCaws ec2 create-vpc --cidr-block 10.0.0.0/16# Tag it right awayaws ec2 create-tags \\ --resources vpc-0123456789abcdef0 \\ --tags Key=Name,Value=MyVPC
# Enable DNS hostnames (needed for many services)aws ec2 modify-vpc-attribute \\ --vpc-id vpc-0123456789abcdef0 \\ --enable-dns-hostnames '{"Value": true}'
# Delete VPC (must remove all dependencies first)aws ec2 delete-vpc --vpc-id vpc-0123456789abcdef0
# List subnetsaws ec2 describe-subnetsaws ec2 describe-subnets \\ --filters "Name=vpc-id,Values=vpc-0123456789abcdef0" \\ --query 'Subnets[*].[SubnetId,CidrBlock,AvailabilityZone,Tags[?Key==`Name`].Value|[0]]' \\ --output table
# Create subnetaws ec2 create-subnet \\ --vpc-id vpc-0123456789abcdef0 \\ --cidr-block 10.0.1.0/24 \\ --availability-zone ap-south-1a
# Enable auto-assign public IP for public subnetaws ec2 modify-subnet-attribute \\ --subnet-id subnet-0123456789abcdef0 \\ --map-public-ip-on-launch
# Create Internet Gateway (for public internet access)aws ec2 create-internet-gateway# Attach to VPCaws ec2 attach-internet-gateway \\ --internet-gateway-id igw-0123456789abcdef0 \\ --vpc-id vpc-0123456789abcdef0
# List internet gatewaysaws ec2 describe-internet-gateways
# Create Route Tableaws ec2 create-route-table --vpc-id vpc-0123456789abcdef0
# Add route to IGW (makes it a "public" route table)aws ec2 create-route \\ --route-table-id rtb-0123456789abcdef0 \\ --destination-cidr-block 0.0.0.0/0 \\ --gateway-id igw-0123456789abcdef0
# Associate route table with subnetaws ec2 associate-route-table \\ --route-table-id rtb-0123456789abcdef0 \\ --subnet-id subnet-0123456789abcdef0
# List route tablesaws ec2 describe-route-tables \\ --filters "Name=vpc-id,Values=vpc-0123456789abcdef0"
# Describe NACLsaws ec2 describe-network-acls \\ --filters "Name=vpc-id,Values=vpc-0123456789abcdef0"
# List NAT Gatewaysaws ec2 describe-nat-gateways
# Create NAT Gateway (needs an Elastic IP first, goes in public subnet)aws ec2 allocate-address --domain vpc # get EIPaws ec2 create-nat-gateway \\ --subnet-id subnet-public-id \\ --allocation-id eipalloc-0123456789abcdef0RDS — Relational Database Service
Section titled “RDS — Relational Database Service”Mental Model
Section titled “Mental Model”RDS instance → lives in a subnet group (spans multiple AZs) → protected by security groups → optionally has Multi-AZ (HA) and Read Replicas.
# List all RDS instancesaws rds describe-db-instancesaws rds describe-db-instances \\ --query 'DBInstances[*].[DBInstanceIdentifier,DBInstanceStatus,Engine,Endpoint.Address]' \\ --output table
# Create a DB subnet group (required before creating RDS)aws rds create-db-subnet-group \\ --db-subnet-group-name my-db-subnet-group \\ --db-subnet-group-description "My DB subnet group" \\ --subnet-ids subnet-0abc subnet-0def
# Create a PostgreSQL RDS instanceaws rds create-db-instance \\ --db-instance-identifier mydb \\ --db-instance-class db.t3.micro \\ --engine postgres \\ --engine-version 14.7 \\ --master-username admin \\ --master-user-password 'SecurePass@123' \\ --allocated-storage 20 \\ --db-subnet-group-name my-db-subnet-group \\ --vpc-security-group-ids sg-0123456789abcdef0 \\ --no-publicly-accessible \\ --backup-retention-period 7
# Create MySQL instance (same thing, different engine)# --engine mysql --engine-version 8.0
# Get the endpoint (wait for status = available first)aws rds describe-db-instances \\ --db-instance-identifier mydb \\ --query 'DBInstances[0].Endpoint.Address' \\ --output text
# Start / Stop RDS instanceaws rds stop-db-instance --db-instance-identifier mydbaws rds start-db-instance --db-instance-identifier mydb
# Create a snapshotaws rds create-db-snapshot \\ --db-instance-identifier mydb \\ --db-snapshot-identifier mydb-snapshot-2024
# List snapshotsaws rds describe-db-snapshots --db-instance-identifier mydb
# Restore from snapshotaws rds restore-db-instance-from-db-snapshot \\ --db-instance-identifier mydb-restored \\ --db-snapshot-identifier mydb-snapshot-2024 \\ --db-instance-class db.t3.micro
# Modify instance (e.g., change instance class)aws rds modify-db-instance \\ --db-instance-identifier mydb \\ --db-instance-class db.t3.small \\ --apply-immediately
# Create read replicaaws rds create-db-instance-read-replica \\ --db-instance-identifier mydb-replica \\ --source-db-instance-identifier mydb
# Delete RDS (with final snapshot)aws rds delete-db-instance \\ --db-instance-identifier mydb \\ --final-db-snapshot-identifier mydb-final-snap
# Delete without snapshot (destructive!)aws rds delete-db-instance \\ --db-instance-identifier mydb \\ --skip-final-snapshotLambda
Section titled “Lambda”Mental Model
Section titled “Mental Model”Lambda = a function packaged as a ZIP or container → triggered by events (API Gateway, S3, SQS, schedule, etc.) → executes with an IAM role.
# List all functionsaws lambda list-functionsaws lambda list-functions \\ --query 'Functions[*].[FunctionName,Runtime,LastModified]' \\ --output table
# Get function detailsaws lambda get-function --function-name my-function
# Get just the config (no download URL)aws lambda get-function-configuration --function-name my-function
# Create a function from a zip# First, zip your code:zip function.zip index.js
aws lambda create-function \\ --function-name my-function \\ --runtime nodejs20.x \\ --role arn:aws:iam::<account-id>:role/MyLambdaRole \\ --handler index.handler \\ --zip-file fileb://function.zip \\ --timeout 30 \\ --memory-size 256
# Update function codezip function.zip index.jsaws lambda update-function-code \\ --function-name my-function \\ --zip-file fileb://function.zip
# Update function config (env vars, timeout, memory)aws lambda update-function-configuration \\ --function-name my-function \\ --timeout 60 \\ --memory-size 512 \\ --environment 'Variables={DB_HOST=myhost,NODE_ENV=production}'
# Invoke a function synchronouslyaws lambda invoke \\ --function-name my-function \\ --payload '{"key": "value"}' \\ output.jsoncat output.json
# Invoke asynchronouslyaws lambda invoke \\ --function-name my-function \\ --invocation-type Event \\ --payload '{"key": "value"}' \\ output.json
# Add environment variablesaws lambda update-function-configuration \\ --function-name my-function \\ --environment 'Variables={KEY1=val1,KEY2=val2}'
# List versionsaws lambda list-versions-by-function --function-name my-function
# Publish a version (immutable snapshot)aws lambda publish-version --function-name my-function
# Create an aliasaws lambda create-alias \\ --function-name my-function \\ --name production \\ --function-version 3
# List event source mappings (SQS, DynamoDB stream triggers)aws lambda list-event-source-mappings --function-name my-function
# Add permission (allow another service to invoke this function)aws lambda add-permission \\ --function-name my-function \\ --statement-id AllowS3Invoke \\ --action lambda:InvokeFunction \\ --principal s3.amazonaws.com \\ --source-arn arn:aws:s3:::my-bucket
# View function policy (permissions)aws lambda get-policy --function-name my-function
# Delete functionaws lambda delete-function --function-name my-functionCloudWatch Logs — Essential for Lambda/EC2 debugging
Section titled “CloudWatch Logs — Essential for Lambda/EC2 debugging”# List log groupsaws logs describe-log-groups
# List log groups for Lambda (they follow a naming pattern)aws logs describe-log-groups \\ --log-group-name-prefix /aws/lambda/
# Get log streams in a group (latest first)aws logs describe-log-streams \\ --log-group-name /aws/lambda/my-function \\ --order-by LastEventTime \\ --descending
# Fetch actual log eventsaws logs get-log-events \\ --log-group-name /aws/lambda/my-function \\ --log-stream-name '2024/01/01/[$LATEST]abc123'
# Live tail logs (v2 only, extremely useful)aws logs tail /aws/lambda/my-function --follow
# Filter logs by patternaws logs filter-log-events \\ --log-group-name /aws/lambda/my-function \\ --filter-pattern "ERROR"
# Filter by time rangeaws logs filter-log-events \\ --log-group-name /aws/lambda/my-function \\ --start-time $(date -d '1 hour ago' +%s000) \\ --end-time $(date +%s000)Output Control — Make CLI Usable
Section titled “Output Control — Make CLI Usable”The --query flag uses JMESPath. Learn this, it saves your life.
# Get a single fieldaws ec2 describe-instances \\ --query 'Reservations[0].Instances[0].InstanceId' \\ --output text
# Get multiple fields as tableaws iam list-users \\ --query 'Users[*].[UserName,CreateDate,PasswordLastUsed]' \\ --output table
# Filter by value (like WHERE clause)aws ec2 describe-instances \\ --query 'Reservations[*].Instances[?State.Name==`running`].[InstanceId,PublicIpAddress]' \\ --output table
# Output as JSON (default), table, text, yaml--output json # default, machine-readable--output table # human-readable grid--output text # plain, good for piping/scripting
# Pagination — some commands paginate, use --no-paginate to get allaws s3api list-objects-v2 --bucket my-bucket --no-paginate
# Dry-run (supported by EC2) — checks permissions without doing the actionaws ec2 run-instances \\ --image-id ami-xxx \\ --instance-type t2.micro \\ --dry-runQuick Reference — Action Verb Pattern
Section titled “Quick Reference — Action Verb Pattern”| What you want to do | Typical verb prefix |
|---|---|
| Read/list things | list-, describe-, get- |
| Create a resource | create-, run- (EC2), put- |
| Delete a resource | delete-, remove- |
| Modify/update | update-, modify-, put- |
| Link two things | attach-, associate-, add- |
| Unlink two things | detach-, disassociate-, remove- |
| Trigger an action | start-, stop-, invoke-, enable- |
When stuck on a command, just run:
aws <service> helpaws <service> <action> helpThat’s your offline docs. Use it constantly.
Handy Aliases to Set Up
Section titled “Handy Aliases to Set Up”# In your ~/.bashrc or ~/.zshrc
# Shorter awsalias a='aws'
# Get your own identity fastalias whoami-aws='aws sts get-caller-identity'
# List running EC2s formattedalias ec2-running='aws ec2 describe-instances \\ --filters Name=instance-state-name,Values=running \\ --query "Reservations[*].Instances[*].[InstanceId,InstanceType,PublicIpAddress,Tags[?Key==\\`Name\\`].Value|[0]]" \\ --output table'That’s the full picture. The intuition is: service → verb → resource → options. Every service follows the same grammar. Once IAM clicks, the rest is just learning the nouns.