Storage: S3, EBS & EFS
.mdVerified against aws-cli/2.33.6, flags verified via `aws <cmd> help`, 2026-08-21 · official docs
S3 object and bucket operations, EBS volume/snapshot management for EC2, and EFS shared file systems.
S3 — copying, syncing, and listing objects#
aws s3 cp file.txt s3://my-bucket/path/file.txt
aws s3 cp s3://my-bucket/path/file.txt ./file.txt
aws s3 sync ./local-dir s3://my-bucket/path/ --delete # mirror local -> bucket, remove extras in the destination
aws s3 sync s3://my-bucket/path/ ./local-dir
aws s3 ls s3://my-bucket/path/ --recursive --human-readable --summarizeThe high-level aws s3 commands (cp, sync, ls, rm, mb, rb) are convenience wrappers over the S3 API — they handle multipart upload/download automatically. --dryrun on cp/sync/rm previews what would change without doing it.
S3 — removing objects and buckets#
aws s3 rm s3://my-bucket/path/file.txt
aws s3 rm s3://my-bucket/path/ --recursive # delete everything under a prefix
aws s3 rb s3://my-bucket --force # delete a bucket, --force empties it firstS3 — bucket configuration (s3api)#
aws s3api create-bucket --bucket my-new-bucket --create-bucket-configuration LocationConstraint=us-west-2
aws s3api put-bucket-versioning --bucket my-bucket --versioning-configuration Status=Enabled
aws s3api put-bucket-policy --bucket my-bucket --policy file://bucket-policy.json
aws s3api head-object --bucket my-bucket --key path/file.txt # metadata only, no downloadAnything below the aws s3 convenience layer — bucket policies, versioning, lifecycle rules, ACLs, encryption config — lives under aws s3api, which maps 1:1 to the raw S3 API and needs --bucket/--key explicitly rather than an s3:// URI.
S3 — listing with s3api for scripting#
aws s3api list-objects-v2 --bucket my-bucket --prefix path/ --query 'Contents[].Key' --output texts3api list-objects-v2 is the scriptable equivalent of aws s3 ls — prefer it when you need --query filtering or pagination control that the high-level ls doesn't expose.
S3 — versioning and listing versions#
aws s3api get-bucket-versioning --bucket my-bucket
aws s3api list-object-versions --bucket my-bucket --prefix path/file.txt
aws s3api get-object --bucket my-bucket --key path/file.txt --version-id <version-id> downloaded-old-version.txtOnce versioning is enabled on a bucket it cannot be disabled, only suspended (Status=Suspended) — plan for the storage cost before turning it on. A "deleted" object in a versioned bucket isn't gone; list-object-versions shows it with a delete-marker entry, and it's recoverable by fetching a specific --version-id.
S3 — lifecycle rules#
aws s3api put-bucket-lifecycle-configuration --bucket my-bucket --lifecycle-configuration file://lifecycle.json
aws s3api get-bucket-lifecycle-configuration --bucket my-bucketA minimal lifecycle.json transitioning old objects to cheaper storage and expiring them later:
{
"Rules": [
{
"ID": "archive-and-expire",
"Filter": { "Prefix": "logs/" },
"Status": "Enabled",
"Transitions": [{ "Days": 30, "StorageClass": "GLACIER" }],
"Expiration": { "Days": 365 }
}
]
}S3 — cross-region/same-region replication#
aws s3api put-bucket-replication --bucket my-bucket --replication-configuration file://replication.jsonReplication requires versioning enabled on both the source and destination buckets, and an IAM role (specified inside replication.json's Role field) with permission to read the source and write the destination — it silently does nothing for objects that existed before the rule was created (it's forward-only, not a one-time backfill).
S3 — presigned URLs#
aws s3 presign s3://my-bucket/path/file.txt --expires-in 3600A presigned URL grants temporary access (default 1 hour, max 7 days for IAM-user/role credentials) to a single object using the credentials of whoever ran the command — anyone holding the URL can perform that action without their own AWS credentials, so treat the URL itself as a secret. It only works for actions the signing principal is actually allowed to perform (GetObject by default).
EBS — creating and attaching volumes#
aws ec2 create-volume --availability-zone us-east-1a --size 100 --volume-type gp3
aws ec2 attach-volume --volume-id vol-0123456789abcdef0 --instance-id i-0123456789abcdef0 --device /dev/xvdf
aws ec2 describe-volumes --volume-ids vol-0123456789abcdef0
aws ec2 delete-volume --volume-id vol-0123456789abcdef0A volume must be in the same Availability Zone as the instance it attaches to — a common source of "InvalidVolume.ZoneMismatch" errors when scripting instance + volume creation together.
EBS — snapshots#
aws ec2 create-snapshot --volume-id vol-0123456789abcdef0 --description "pre-migration backup"
aws ec2 describe-snapshots --owner-ids self
aws ec2 describe-snapshots --filters "Name=volume-id,Values=vol-0123456789abcdef0"EFS — file systems and mount targets#
aws efs create-file-system --performance-mode generalPurpose --throughput-mode bursting --encrypted
aws efs describe-file-systems
aws efs create-mount-target --file-system-id fs-0123456789abcdef0 --subnet-id subnet-0123456789abcdef0 --security-groups sg-0123456789abcdef0
aws efs describe-mount-targets --file-system-id fs-0123456789abcdef0EFS needs one mount target per Availability Zone you want to mount from — an EC2 instance in a subnet with no mount target for that file system will time out trying to mount it, not fail with a clear error.