Boto3 Cheatsheet
Section titled “Boto3 Cheatsheet”Install & Setup
Section titled “Install & Setup”Install
Section titled “Install”pip install boto3 botocoreBasic Session
Section titled “Basic Session”import boto3from botocore.exceptions import ClientError
session = boto3.Session( profile_name="dev", region_name="us-east-1",)
s3 = session.client("s3")ec2 = session.resource("ec2")Clients vs Resources
Section titled “Clients vs Resources”# Client: low-level API, available for every AWS services3_client = boto3.client("s3")s3_client.list_buckets()
# Resource: higher-level object API, available for selected servicess3_resource = boto3.resource("s3")bucket = s3_resource.Bucket("my-bucket")Credentials Resolution Order
Section titled “Credentials Resolution Order”Common places boto3 checks:
- Explicit parameters in code.
- Environment variables such as
AWS_ACCESS_KEY_ID. - Shared credentials file:
~/.aws/credentials. - Shared config file:
~/.aws/config. - Assume-role profiles.
- Container or EC2 instance role metadata.
Common Imports
Section titled “Common Imports”import jsonimport timeimport boto3
from pathlib import Pathfrom botocore.config import Configfrom botocore.exceptions import ClientError, NoCredentialsError, WaiterErrorRetry & Timeout Config
Section titled “Retry & Timeout Config”from botocore.config import Config
config = Config( retries={"max_attempts": 10, "mode": "standard"}, connect_timeout=5, read_timeout=60,)
s3 = boto3.client("s3", config=config)Error Handling
Section titled “Error Handling”Catch AWS API Errors
Section titled “Catch AWS API Errors”from botocore.exceptions import ClientError
try: s3.head_bucket(Bucket="my-bucket")except ClientError as exc: code = exc.response["Error"]["Code"] message = exc.response["Error"]["Message"] print(code, message)Match Specific Errors
Section titled “Match Specific Errors”try: dynamodb.get_item( TableName="users", Key={"pk": {"S": "user#1"}}, )except ClientError as exc: if exc.response["Error"]["Code"] == "ResourceNotFoundException": print("Table does not exist") else: raisePagination & Waiters
Section titled “Pagination & Waiters”Paginators
Section titled “Paginators”s3 = boto3.client("s3")paginator = s3.get_paginator("list_objects_v2")
for page in paginator.paginate(Bucket="my-bucket", Prefix="logs/"): for obj in page.get("Contents", []): print(obj["Key"], obj["Size"])Waiters
Section titled “Waiters”ec2 = boto3.client("ec2")
ec2.start_instances(InstanceIds=["i-0123456789abcdef0"])
waiter = ec2.get_waiter("instance_running")waiter.wait(InstanceIds=["i-0123456789abcdef0"])Amazon S3
Section titled “Amazon S3”List Buckets
Section titled “List Buckets”s3 = boto3.client("s3")
for bucket in s3.list_buckets()["Buckets"]: print(bucket["Name"], bucket["CreationDate"])Create Bucket
Section titled “Create Bucket”s3.create_bucket( Bucket="my-unique-bucket-name", CreateBucketConfiguration={"LocationConstraint": "ap-south-1"},)For us-east-1, omit CreateBucketConfiguration.
Upload File
Section titled “Upload File”s3.upload_file( Filename="report.csv", Bucket="my-bucket", Key="reports/report.csv",)Upload Bytes or JSON
Section titled “Upload Bytes or JSON”payload = {"status": "ok"}
s3.put_object( Bucket="my-bucket", Key="data/status.json", Body=json.dumps(payload).encode("utf-8"), ContentType="application/json",)Download File
Section titled “Download File”s3.download_file( Bucket="my-bucket", Key="reports/report.csv", Filename="report.csv",)Read Object
Section titled “Read Object”response = s3.get_object(Bucket="my-bucket", Key="data/status.json")data = json.loads(response["Body"].read())List Objects
Section titled “List Objects”paginator = s3.get_paginator("list_objects_v2")
for page in paginator.paginate(Bucket="my-bucket", Prefix="logs/"): for obj in page.get("Contents", []): print(obj["Key"])Copy Object
Section titled “Copy Object”s3.copy_object( Bucket="target-bucket", Key="archive/report.csv", CopySource={"Bucket": "source-bucket", "Key": "reports/report.csv"},)Delete Object
Section titled “Delete Object”s3.delete_object(Bucket="my-bucket", Key="reports/old.csv")Delete Many Objects
Section titled “Delete Many Objects”objects = [{"Key": "tmp/a.txt"}, {"Key": "tmp/b.txt"}]
s3.delete_objects( Bucket="my-bucket", Delete={"Objects": objects, "Quiet": True},)Generate Presigned URL
Section titled “Generate Presigned URL”url = s3.generate_presigned_url( "get_object", Params={"Bucket": "my-bucket", "Key": "reports/report.csv"}, ExpiresIn=3600,)print(url)Amazon EC2
Section titled “Amazon EC2”List Instances
Section titled “List Instances”ec2 = boto3.client("ec2")
response = ec2.describe_instances()
for reservation in response["Reservations"]: for instance in reservation["Instances"]: print(instance["InstanceId"], instance["State"]["Name"])Filter Instances
Section titled “Filter Instances”response = ec2.describe_instances( Filters=[ {"Name": "instance-state-name", "Values": ["running"]}, {"Name": "tag:Environment", "Values": ["prod"]}, ])Start, Stop, Reboot
Section titled “Start, Stop, Reboot”ids = ["i-0123456789abcdef0"]
ec2.start_instances(InstanceIds=ids)ec2.stop_instances(InstanceIds=ids)ec2.reboot_instances(InstanceIds=ids)Launch Instance
Section titled “Launch Instance”response = ec2.run_instances( ImageId="ami-0123456789abcdef0", InstanceType="t3.micro", MinCount=1, MaxCount=1, KeyName="my-key", SecurityGroupIds=["sg-0123456789abcdef0"], SubnetId="subnet-0123456789abcdef0", TagSpecifications=[ { "ResourceType": "instance", "Tags": [{"Key": "Name", "Value": "demo-server"}], } ],)
instance_id = response["Instances"][0]["InstanceId"]Terminate Instance
Section titled “Terminate Instance”ec2.terminate_instances(InstanceIds=["i-0123456789abcdef0"])Get Instance Public IPs
Section titled “Get Instance Public IPs”for reservation in ec2.describe_instances()["Reservations"]: for instance in reservation["Instances"]: print(instance["InstanceId"], instance.get("PublicIpAddress"))Security Groups
Section titled “Security Groups”ec2.authorize_security_group_ingress( GroupId="sg-0123456789abcdef0", IpPermissions=[ { "IpProtocol": "tcp", "FromPort": 443, "ToPort": 443, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "HTTPS"}], } ],)List Users and Roles
Section titled “List Users and Roles”iam = boto3.client("iam")
for user in iam.get_paginator("list_users").paginate(): for item in user["Users"]: print(item["UserName"])
for role_page in iam.get_paginator("list_roles").paginate(): for role in role_page["Roles"]: print(role["RoleName"])Create User
Section titled “Create User”iam.create_user(UserName="alice")Attach Managed Policy
Section titled “Attach Managed Policy”iam.attach_user_policy( UserName="alice", PolicyArn="arn:aws:iam::aws:policy/ReadOnlyAccess",)Create Role
Section titled “Create Role”assume_role_policy = { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole", } ],}
iam.create_role( RoleName="lambda-basic-role", AssumeRolePolicyDocument=json.dumps(assume_role_policy),)Put Inline Policy
Section titled “Put Inline Policy”policy = { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": "arn:aws:s3:::my-bucket/*", } ],}
iam.put_role_policy( RoleName="lambda-basic-role", PolicyName="read-bucket", PolicyDocument=json.dumps(policy),)AWS STS
Section titled “AWS STS”Caller Identity
Section titled “Caller Identity”sts = boto3.client("sts")print(sts.get_caller_identity())Assume Role
Section titled “Assume Role”response = sts.assume_role( RoleArn="arn:aws:iam::123456789012:role/Admin", RoleSessionName="automation-session",)
creds = response["Credentials"]
assumed = boto3.Session( aws_access_key_id=creds["AccessKeyId"], aws_secret_access_key=creds["SecretAccessKey"], aws_session_token=creds["SessionToken"],)AWS Lambda
Section titled “AWS Lambda”List Functions
Section titled “List Functions”lambda_client = boto3.client("lambda")
for page in lambda_client.get_paginator("list_functions").paginate(): for fn in page["Functions"]: print(fn["FunctionName"], fn["Runtime"])Invoke Function
Section titled “Invoke Function”response = lambda_client.invoke( FunctionName="my-function", InvocationType="RequestResponse", Payload=json.dumps({"name": "Alice"}).encode("utf-8"),)
payload = json.loads(response["Payload"].read())Invoke Async
Section titled “Invoke Async”lambda_client.invoke( FunctionName="my-function", InvocationType="Event", Payload=json.dumps({"task": "refresh"}).encode("utf-8"),)Update Environment Variables
Section titled “Update Environment Variables”lambda_client.update_function_configuration( FunctionName="my-function", Environment={ "Variables": { "ENV": "prod", "LOG_LEVEL": "INFO", } },)Update Code from S3
Section titled “Update Code from S3”lambda_client.update_function_code( FunctionName="my-function", S3Bucket="deploy-artifacts", S3Key="lambda/my-function.zip", Publish=True,)Amazon DynamoDB
Section titled “Amazon DynamoDB”Resource Setup
Section titled “Resource Setup”dynamodb = boto3.resource("dynamodb")table = dynamodb.Table("users")Put Item
Section titled “Put Item”table.put_item( Item={ "pk": "user#1", "sk": "profile", "name": "Alice", "age": 30, })Get Item
Section titled “Get Item”response = table.get_item( Key={"pk": "user#1", "sk": "profile"})
item = response.get("Item")Update Item
Section titled “Update Item”response = table.update_item( Key={"pk": "user#1", "sk": "profile"}, UpdateExpression="SET age = :age, updated_at = :updated_at", ExpressionAttributeValues={ ":age": 31, ":updated_at": "2026-05-18T00:00:00Z", }, ReturnValues="ALL_NEW",)
print(response["Attributes"])Query Partition
Section titled “Query Partition”from boto3.dynamodb.conditions import Key
response = table.query( KeyConditionExpression=Key("pk").eq("user#1"))
for item in response["Items"]: print(item)Query Index
Section titled “Query Index”response = table.query( IndexName="email-index", KeyConditionExpression=Key("email").eq("alice@example.com"),)Scan with Filter
Section titled “Scan with Filter”from boto3.dynamodb.conditions import Attr
response = table.scan( FilterExpression=Attr("status").eq("active"))Use scan carefully on large tables.
Batch Write
Section titled “Batch Write”with table.batch_writer() as batch: for i in range(100): batch.put_item(Item={"pk": f"user#{i}", "sk": "profile"})Delete Item
Section titled “Delete Item”table.delete_item(Key={"pk": "user#1", "sk": "profile"})Amazon SQS
Section titled “Amazon SQS”Create Queue
Section titled “Create Queue”sqs = boto3.client("sqs")
response = sqs.create_queue( QueueName="jobs", Attributes={"VisibilityTimeout": "60"},)
queue_url = response["QueueUrl"]Send Message
Section titled “Send Message”sqs.send_message( QueueUrl=queue_url, MessageBody=json.dumps({"job_id": 123}),)Send FIFO Message
Section titled “Send FIFO Message”sqs.send_message( QueueUrl="https://sqs.us-east-1.amazonaws.com/123/jobs.fifo", MessageBody="process-order", MessageGroupId="orders", MessageDeduplicationId="order-123",)Receive Messages
Section titled “Receive Messages”response = sqs.receive_message( QueueUrl=queue_url, MaxNumberOfMessages=10, WaitTimeSeconds=20, VisibilityTimeout=60,)
for message in response.get("Messages", []): print(message["Body"])Delete Message After Processing
Section titled “Delete Message After Processing”sqs.delete_message( QueueUrl=queue_url, ReceiptHandle=message["ReceiptHandle"],)Change Visibility Timeout
Section titled “Change Visibility Timeout”sqs.change_message_visibility( QueueUrl=queue_url, ReceiptHandle=message["ReceiptHandle"], VisibilityTimeout=120,)Amazon SNS
Section titled “Amazon SNS”Create Topic
Section titled “Create Topic”sns = boto3.client("sns")
response = sns.create_topic(Name="alerts")topic_arn = response["TopicArn"]Publish Message
Section titled “Publish Message”sns.publish( TopicArn=topic_arn, Subject="Build failed", Message="The production build failed.",)Subscribe Email
Section titled “Subscribe Email”sns.subscribe( TopicArn=topic_arn, Protocol="email", Endpoint="admin@example.com",)Publish JSON Message
Section titled “Publish JSON Message”sns.publish( TopicArn=topic_arn, Message=json.dumps({"default": "Fallback", "email": "Email body"}), MessageStructure="json",)CloudWatch Logs
Section titled “CloudWatch Logs”List Log Groups
Section titled “List Log Groups”logs = boto3.client("logs")
for page in logs.get_paginator("describe_log_groups").paginate(): for group in page["logGroups"]: print(group["logGroupName"])Read Log Events
Section titled “Read Log Events”response = logs.get_log_events( logGroupName="/aws/lambda/my-function", logStreamName="2026/05/18/[$LATEST]abcdef", startFromHead=True,)
for event in response["events"]: print(event["message"])Filter Logs
Section titled “Filter Logs”response = logs.filter_log_events( logGroupName="/aws/lambda/my-function", filterPattern="ERROR", limit=50,)
for event in response["events"]: print(event["message"])Put Metric Data
Section titled “Put Metric Data”cloudwatch = boto3.client("cloudwatch")
cloudwatch.put_metric_data( Namespace="MyApp", MetricData=[ { "MetricName": "JobsProcessed", "Value": 42, "Unit": "Count", "Dimensions": [{"Name": "Environment", "Value": "prod"}], } ],)AWS Systems Manager Parameter Store
Section titled “AWS Systems Manager Parameter Store”Get Parameter
Section titled “Get Parameter”ssm = boto3.client("ssm")
response = ssm.get_parameter( Name="/myapp/prod/db-url", WithDecryption=True,)
value = response["Parameter"]["Value"]Get Parameters by Path
Section titled “Get Parameters by Path”paginator = ssm.get_paginator("get_parameters_by_path")
for page in paginator.paginate( Path="/myapp/prod/", Recursive=True, WithDecryption=True,): for param in page["Parameters"]: print(param["Name"], param["Value"])Put Parameter
Section titled “Put Parameter”ssm.put_parameter( Name="/myapp/prod/api-key", Value="secret-value", Type="SecureString", Overwrite=True,)Run Command on EC2
Section titled “Run Command on EC2”response = ssm.send_command( InstanceIds=["i-0123456789abcdef0"], DocumentName="AWS-RunShellScript", Parameters={"commands": ["uptime", "df -h"]},)
command_id = response["Command"]["CommandId"]AWS Secrets Manager
Section titled “AWS Secrets Manager”Get Secret
Section titled “Get Secret”secrets = boto3.client("secretsmanager")
response = secrets.get_secret_value(SecretId="prod/db")
if "SecretString" in response: secret = json.loads(response["SecretString"])else: secret = response["SecretBinary"]Create Secret
Section titled “Create Secret”secrets.create_secret( Name="prod/api", SecretString=json.dumps({"token": "secret-token"}),)Update Secret
Section titled “Update Secret”secrets.put_secret_value( SecretId="prod/api", SecretString=json.dumps({"token": "new-secret-token"}),)Amazon ECR
Section titled “Amazon ECR”Get Login Password
Section titled “Get Login Password”ecr = boto3.client("ecr")
response = ecr.get_authorization_token()auth_data = response["authorizationData"][0]print(auth_data["proxyEndpoint"])For Docker login, the AWS CLI is usually simpler:
aws ecr get-login-password --region us-east-1 \ | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.comCreate Repository
Section titled “Create Repository”ecr.create_repository( repositoryName="my-service", imageScanningConfiguration={"scanOnPush": True},)List Images
Section titled “List Images”response = ecr.list_images(repositoryName="my-service")
for image in response["imageIds"]: print(image)Amazon ECS
Section titled “Amazon ECS”List Clusters and Services
Section titled “List Clusters and Services”ecs = boto3.client("ecs")
clusters = ecs.list_clusters()["clusterArns"]
for cluster in clusters: services = ecs.list_services(cluster=cluster)["serviceArns"] print(cluster, services)Update Service Desired Count
Section titled “Update Service Desired Count”ecs.update_service( cluster="my-cluster", service="api", desiredCount=3,)Force New Deployment
Section titled “Force New Deployment”ecs.update_service( cluster="my-cluster", service="api", forceNewDeployment=True,)Run One-Off Task
Section titled “Run One-Off Task”ecs.run_task( cluster="my-cluster", taskDefinition="worker:12", launchType="FARGATE", networkConfiguration={ "awsvpcConfiguration": { "subnets": ["subnet-0123456789abcdef0"], "securityGroups": ["sg-0123456789abcdef0"], "assignPublicIp": "ENABLED", } },)Amazon RDS
Section titled “Amazon RDS”List DB Instances
Section titled “List DB Instances”rds = boto3.client("rds")
for page in rds.get_paginator("describe_db_instances").paginate(): for db in page["DBInstances"]: print(db["DBInstanceIdentifier"], db["DBInstanceStatus"])Create Snapshot
Section titled “Create Snapshot”rds.create_db_snapshot( DBInstanceIdentifier="prod-db", DBSnapshotIdentifier="prod-db-manual-2026-05-18",)Start and Stop DB Instance
Section titled “Start and Stop DB Instance”rds.stop_db_instance(DBInstanceIdentifier="dev-db")rds.start_db_instance(DBInstanceIdentifier="dev-db")Modify DB Instance
Section titled “Modify DB Instance”rds.modify_db_instance( DBInstanceIdentifier="dev-db", AllocatedStorage=100, ApplyImmediately=True,)Route 53
Section titled “Route 53”List Hosted Zones
Section titled “List Hosted Zones”route53 = boto3.client("route53")
for zone in route53.list_hosted_zones()["HostedZones"]: print(zone["Name"], zone["Id"])List Records
Section titled “List Records”records = route53.list_resource_record_sets( HostedZoneId="/hostedzone/Z1234567890",)
for record in records["ResourceRecordSets"]: print(record["Name"], record["Type"])Upsert DNS Record
Section titled “Upsert DNS Record”route53.change_resource_record_sets( HostedZoneId="/hostedzone/Z1234567890", ChangeBatch={ "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "app.example.com.", "Type": "A", "TTL": 300, "ResourceRecords": [{"Value": "203.0.113.10"}], }, } ] },)Common Patterns
Section titled “Common Patterns”Idempotent Create Bucket
Section titled “Idempotent Create Bucket”def ensure_bucket(name: str, region: str = "us-east-1") -> None: s3 = boto3.client("s3", region_name=region)
try: s3.head_bucket(Bucket=name) return except ClientError as exc: status = exc.response["ResponseMetadata"]["HTTPStatusCode"] if status not in (403, 404): raise
kwargs = {"Bucket": name} if region != "us-east-1": kwargs["CreateBucketConfiguration"] = {"LocationConstraint": region}
s3.create_bucket(**kwargs)Poll Until Status
Section titled “Poll Until Status”def wait_for_instance_state(instance_id: str, state: str, timeout: int = 300) -> None: ec2 = boto3.client("ec2") deadline = time.time() + timeout
while time.time() < deadline: response = ec2.describe_instances(InstanceIds=[instance_id]) current = response["Reservations"][0]["Instances"][0]["State"]["Name"] if current == state: return time.sleep(5)
raise TimeoutError(f"{instance_id} did not reach {state}")Tag Resources
Section titled “Tag Resources”ec2.create_tags( Resources=["i-0123456789abcdef0"], Tags=[ {"Key": "Environment", "Value": "prod"}, {"Key": "Owner", "Value": "platform"}, ],)Use Environment Variables
Section titled “Use Environment Variables”import os
session = boto3.Session( profile_name=os.getenv("AWS_PROFILE"), region_name=os.getenv("AWS_REGION", "us-east-1"),)Build a Reusable Client Factory
Section titled “Build a Reusable Client Factory”def client(service: str, profile: str | None = None, region: str = "us-east-1"): session = boto3.Session(profile_name=profile, region_name=region) return session.client(service)
s3 = client("s3", profile="prod")Testing & Local Development
Section titled “Testing & Local Development”Stub AWS Calls
Section titled “Stub AWS Calls”import boto3from botocore.stub import Stubber
s3 = boto3.client("s3")
with Stubber(s3) as stubber: stubber.add_response( "list_buckets", {"Buckets": [], "Owner": {"DisplayName": "me", "ID": "123"}}, )
response = s3.list_buckets()Use moto for Unit Tests
Section titled “Use moto for Unit Tests”pip install moto pytestimport boto3from moto import mock_aws
@mock_awsdef test_create_bucket(): s3 = boto3.client("s3", region_name="us-east-1") s3.create_bucket(Bucket="test-bucket")
buckets = s3.list_buckets()["Buckets"] assert buckets[0]["Name"] == "test-bucket"LocalStack Endpoint
Section titled “LocalStack Endpoint”s3 = boto3.client( "s3", endpoint_url="http://localhost:4566", aws_access_key_id="test", aws_secret_access_key="test", region_name="us-east-1",)Production Checklist
Section titled “Production Checklist”- Use IAM roles instead of hardcoded credentials.
- Use least-privilege IAM policies.
- Set retry and timeout configuration for automation.
- Use paginators for list operations.
- Use waiters for supported async workflows.
- Handle
ClientErrorexplicitly. - Avoid
scanon large DynamoDB tables unless you really need it. - Encrypt S3, RDS, SQS, SNS, SSM, and Secrets Manager data where required.
- Tag resources consistently.
- Log AWS request IDs when debugging production failures.