Amazon Simple Storage Service (Amazon S3) is AWS object storage for files, backups, logs, application assets and data lakes. This guide explains its core behaviour through practical examples useful for learners preparing for an AWS Solutions Architect course.
What is Amazon S3 and how does it work?
Amazon S3 stores data as objects inside buckets. Each object contains data, a unique key and associated metadata; it is not a traditional disk or hierarchical file system.
A simple diagram in words is:
AWS account
└── S3 bucket: nr-training-lab-12345
├── images/router.jpg
├── logs/2026/09/app.log
└── backups/database.sqlThe apparent folders are prefixes within object keys. For example, logs/2026/09/app.log is one complete key, not a file placed inside physical directories.
S3 general purpose bucket names must be unique across the relevant AWS partition. A bucket is created in an AWS Region, but access is controlled separately through IAM policies, bucket policies, Block Public Access and other security controls.
S3 provides strong read-after-write consistency for object uploads, overwrites and deletes. After a successful write, a subsequent read or list request reflects the change.
S3 is suitable for static content, backups, log archives and large datasets. It is not a boot disk for an EC2 instance or a direct replacement for a POSIX file system. See Amazon EC2 instances and storage explained for the difference between object and block storage.
What are Amazon S3 storage classes?
S3 storage classes provide different combinations of storage price, resilience, access pattern and retrieval behaviour. Selecting a class should be based on how often objects are read, how quickly they must be restored and how long they will remain stored.
| Storage class | Suitable use | Availability design | Retrieval behaviour | Important consideration |
|---|---|---|---|---|
| S3 Standard | Frequently accessed application data | Multiple Availability Zones | Immediate | Higher storage price than archive classes |
| S3 Intelligent-Tiering | Data with uncertain or changing access | Multiple Availability Zones | Immediate in online tiers; optional archive tiers are asynchronous | Per-object monitoring and automation charges apply to eligible objects |
| S3 Standard-IA | Infrequently accessed backups and files | Multiple Availability Zones | Immediate | Retrieval charges and minimum storage duration apply |
| S3 One Zone-IA | Re-creatable infrequently accessed data | One Availability Zone | Immediate | Not appropriate when loss of one AZ cannot be accepted |
| S3 Glacier Instant Retrieval | Rarely accessed archives needing millisecond access | Multiple Availability Zones | Immediate | Retrieval charge and minimum duration apply |
| S3 Glacier Flexible Retrieval | Archives that can wait minutes or hours | Multiple Availability Zones | Restore required | Object cannot be read until a restore completes |
| S3 Glacier Deep Archive | Long-term compliance and backup archives | Multiple Availability Zones | Restore normally takes hours | Long minimum duration and slower recovery |
| S3 Express One Zone | Very high request-rate workloads needing consistent single-digit millisecond access | One Availability Zone using directory buckets | Immediate | Different bucket model and regional availability from general purpose S3 |
How does S3 Intelligent-Tiering work?
S3 Intelligent-Tiering monitors access and moves eligible objects between access tiers automatically. It is useful when access patterns cannot be predicted accurately, but its monitoring charge should be considered when storing many small objects.
Objects begin in the Frequent Access tier. Objects not accessed for defined periods can move to the Infrequent Access and Archive Instant Access tiers. Optional Archive Access and Deep Archive Access tiers can also be enabled, but retrieval from those optional tiers is asynchronous.
How should you select a storage class?
Start with recovery requirements rather than choosing the cheapest storage rate. An archive class may reduce storage cost but introduce retrieval charges, minimum storage-duration charges and restore delays.
Use these practical questions:
- How frequently will the object be read?
- Must retrieval be immediate?
- Can the data be recreated if an Availability Zone is lost?
- How long will the object remain stored?
- Are request, retrieval and data transfer charges acceptable?
- Does the workload contain millions of small objects?
For unknown access patterns, S3 Intelligent-Tiering is often easier to manage. For predictable long-term archives, a Glacier class can be appropriate after recovery procedures have been tested.
How do you create a bucket and upload objects?
You can manage S3 through the AWS Management Console, AWS CLI, SDKs or infrastructure-as-code tools. The following lab uses AWS CLI commands and the ap-south-1 Region.
First confirm the caller identity:
aws sts get-caller-identityCreate a bucket using a globally unique name:
aws s3api create-bucket \
--bucket nr-training-lab-12345 \
--region ap-south-1 \
--create-bucket-configuration LocationConstraint=ap-south-1Create and upload a test file:
printf 'S3 practical lab\n' > lab.txt
aws s3 cp lab.txt \
s3://nr-training-lab-12345/training/lab.txt \
--storage-class STANDARDInspect the object:
aws s3api head-object \
--bucket nr-training-lab-12345 \
--key training/lab.txtThe output includes properties such as ContentLength, ContentType, ETag, LastModified and StorageClass when applicable. An ETag should not automatically be treated as an MD5 checksum because multipart uploads and some encryption configurations produce different ETag formats.
What is S3 Versioning?
S3 Versioning preserves multiple versions of an object under the same key. It helps recover from accidental overwrites and deletes, but retained versions continue to consume storage until lifecycle rules or explicit deletion remove them.
Enable versioning:
aws s3api put-bucket-versioning \
--bucket nr-training-lab-12345 \
--versioning-configuration Status=EnabledUpload two versions:
printf 'configuration version 1\n' > config.txt
aws s3 cp config.txt s3://nr-training-lab-12345/config/config.txt
printf 'configuration version 2\n' > config.txt
aws s3 cp config.txt s3://nr-training-lab-12345/config/config.txtList versions:
aws s3api list-object-versions \
--bucket nr-training-lab-12345 \
--prefix config/config.txtEach upload receives a unique VersionId. The version with IsLatest: true is returned by a normal GetObject request.
What happens when a versioned object is deleted?
A normal delete request adds a delete marker instead of permanently removing existing versions. S3 then treats the key as deleted, while earlier versions remain available by version ID.
aws s3 rm s3://nr-training-lab-12345/config/config.txtList the versions and delete markers, identify the delete marker's version ID, and remove only that marker to make the previous version current again:
aws s3api delete-object \
--bucket nr-training-lab-12345 \
--key config/config.txt \
--version-id DELETE_MARKER_VERSION_IDTo permanently remove a particular object version, supply that version's ID to the same command. Suspending versioning stops new objects from receiving normal unique version IDs, but it does not delete versions already stored.
How do S3 lifecycle rules control storage and versions?
Lifecycle rules automatically transition or expire objects according to age and prefix or tag filters. They are important in versioned buckets because deleting the current object does not automatically remove older versions.
Create lifecycle.json:
{
"Rules": [
{
"ID": "ArchiveTrainingLogs",
"Status": "Enabled",
"Filter": { "Prefix": "logs/" },
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" },
{ "Days": 90, "StorageClass": "GLACIER" }
],
"Expiration": { "Days": 365 },
"NoncurrentVersionTransitions": [
{ "NoncurrentDays": 30, "StorageClass": "GLACIER" }
],
"NoncurrentVersionExpiration": { "NoncurrentDays": 365 }
}
]
}Apply it:
aws s3api put-bucket-lifecycle-configuration \
--bucket nr-training-lab-12345 \
--lifecycle-configuration file://lifecycle.jsonThis rule applies only to keys beginning with logs/. Review minimum storage durations, object-size behaviour and retrieval requirements before using similar rules in production.
What is an S3 bucket policy?
An S3 bucket policy is a resource-based JSON policy attached to a bucket. It defines who can perform specified S3 actions, on which bucket or objects, and under what conditions.
A policy statement normally contains:
| Element | Purpose |
|---|---|
Effect | Allows or denies the request |
Principal | Identifies the account, user, role or service |
Action | Specifies API operations such as s3:GetObject |
Resource | Identifies a bucket ARN or object ARN |
Condition | Restricts access using context such as TLS, source network or organisation |
The following policy allows one IAM role to read objects and denies all non-TLS requests. Replace the account ID, role name and bucket name before applying it.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowApplicationRoleRead",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/S3ReadRole"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::nr-training-lab-12345/app/*"
},
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::nr-training-lab-12345",
"arn:aws:s3:::nr-training-lab-12345/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}Apply and inspect the policy:
aws s3api put-bucket-policy \
--bucket nr-training-lab-12345 \
--policy file://bucket-policy.json
aws s3api get-bucket-policy \
--bucket nr-training-lab-12345An explicit deny overrides an allow. Effective access may also depend on identity policies, permission boundaries, session policies, service control policies, VPC endpoint policies, KMS key policies and S3 Block Public Access. The AWS IAM users, roles and policies guide explains the identity side of this evaluation.
How should an S3 bucket be secured?
Keep Block Public Access enabled unless public access is an intentional and reviewed requirement. Use least-privilege IAM roles, TLS, logging, encryption and controlled network paths where appropriate.
S3 automatically encrypts new uploads at rest with server-side encryption using S3-managed keys as the base level. Workloads that require customer-controlled key permissions or auditing can use SSE-KMS, but callers must then have suitable KMS permissions as well as S3 permissions.
Check public-access settings:
aws s3api get-public-access-block \
--bucket nr-training-lab-12345For new general purpose buckets, Object Ownership commonly uses the bucket-owner-enforced setting, which disables ACLs. Prefer IAM and bucket policies over object ACLs for normal designs.
Teams automating bucket creation should also validate policies and lifecycle rules in deployment pipelines. These controls are covered further in the AWS DevOps course.
How do you troubleshoot common S3 errors?
S3 problems are usually caused by permissions, Region selection, object state, encryption or an incorrect key. Test with the same principal, command and network path used by the failing application.
AccessDenied or HTTP 403
- Run
aws sts get-caller-identityto confirm the active principal. - Verify that the identity policy allows the required operation.
- Check bucket policies for an explicit deny or incorrect principal.
- Inspect Block Public Access if the request depends on public access.
- Check permission boundaries, organisation SCPs and VPC endpoint policies.
- For SSE-KMS objects, verify
kms:Decryptpermission and the KMS key policy. - Confirm that the object key and prefix match the allowed resource ARN.
For example, permission on arn:aws:s3:::bucket-name/app/* does not cover logs/file.txt.
PermanentRedirect or incorrect endpoint
Find the bucket Region:
aws s3api get-bucket-location \
--bucket nr-training-lab-12345Then retry with the correct Region:
aws s3 ls s3://nr-training-lab-12345 --region ap-south-1Archived object cannot be downloaded
S3 Glacier Flexible Retrieval and Deep Archive objects must be restored before they can be read. Request a temporary restored copy:
aws s3api restore-object \
--bucket nr-training-lab-12345 \
--key archives/report.zip \
--restore-request '{"Days":7,"GlacierJobParameters":{"Tier":"Standard"}}'Use head-object to inspect the Restore status. The restore does not change the object's storage class; it creates a temporary accessible copy for the requested period.
Summary
Amazon S3 is regional object storage built around buckets, keys and API operations. Storage classes control cost and retrieval characteristics, versioning preserves older object states, lifecycle rules manage retention, and bucket policies provide resource-based access control.
A reliable design combines these features instead of treating them separately. Test recovery from delete markers and archive classes, validate effective permissions, and monitor the cost of noncurrent versions and small objects.
*Reviewed by Network Rhinos AWS and cloud trainers.*
To practise S3, IAM, EC2, VPC and architecture labs, enquire about upcoming batch details for the AWS Solutions Architect course.
