Amazon S3 Explained: Classes, Versioning and Policies

AWS 9 min readPublished 17 September 2026

Quick answer

Learn how Amazon S3 stores objects, how storage classes affect cost and retrieval, and how versioning and bucket policies protect data.

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.sql

The 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 classSuitable useAvailability designRetrieval behaviourImportant consideration
S3 StandardFrequently accessed application dataMultiple Availability ZonesImmediateHigher storage price than archive classes
S3 Intelligent-TieringData with uncertain or changing accessMultiple Availability ZonesImmediate in online tiers; optional archive tiers are asynchronousPer-object monitoring and automation charges apply to eligible objects
S3 Standard-IAInfrequently accessed backups and filesMultiple Availability ZonesImmediateRetrieval charges and minimum storage duration apply
S3 One Zone-IARe-creatable infrequently accessed dataOne Availability ZoneImmediateNot appropriate when loss of one AZ cannot be accepted
S3 Glacier Instant RetrievalRarely accessed archives needing millisecond accessMultiple Availability ZonesImmediateRetrieval charge and minimum duration apply
S3 Glacier Flexible RetrievalArchives that can wait minutes or hoursMultiple Availability ZonesRestore requiredObject cannot be read until a restore completes
S3 Glacier Deep ArchiveLong-term compliance and backup archivesMultiple Availability ZonesRestore normally takes hoursLong minimum duration and slower recovery
S3 Express One ZoneVery high request-rate workloads needing consistent single-digit millisecond accessOne Availability Zone using directory bucketsImmediateDifferent 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:

  1. How frequently will the object be read?
  2. Must retrieval be immediate?
  3. Can the data be recreated if an Availability Zone is lost?
  4. How long will the object remain stored?
  5. Are request, retrieval and data transfer charges acceptable?
  6. 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-identity

Create 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-1

Create 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 STANDARD

Inspect the object:

aws s3api head-object \
  --bucket nr-training-lab-12345 \
  --key training/lab.txt

The 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=Enabled

Upload 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.txt

List versions:

aws s3api list-object-versions \
  --bucket nr-training-lab-12345 \
  --prefix config/config.txt

Each 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.txt

List 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_ID

To 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.json

This 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:

ElementPurpose
EffectAllows or denies the request
PrincipalIdentifies the account, user, role or service
ActionSpecifies API operations such as s3:GetObject
ResourceIdentifies a bucket ARN or object ARN
ConditionRestricts 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-12345

An 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-12345

For 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

  1. Run aws sts get-caller-identity to confirm the active principal.
  2. Verify that the identity policy allows the required operation.
  3. Check bucket policies for an explicit deny or incorrect principal.
  4. Inspect Block Public Access if the request depends on public access.
  5. Check permission boundaries, organisation SCPs and VPC endpoint policies.
  6. For SSE-KMS objects, verify kms:Decrypt permission and the KMS key policy.
  7. 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-12345

Then retry with the correct Region:

aws s3 ls s3://nr-training-lab-12345 --region ap-south-1

Archived 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.

Frequently asked questions

What is Amazon S3 used for?

Amazon S3 stores objects such as backups, logs, images, application assets and analytics data. It is object storage accessed through APIs, not a traditional block disk or POSIX file system.

Which S3 storage class should I use?

Use S3 Standard for frequently accessed data and Intelligent-Tiering when access patterns are uncertain. Infrequent Access and Glacier classes suit less frequently accessed data, but minimum durations, retrieval charges and recovery times must be considered.

Does S3 Versioning prevent object deletion?

Versioning preserves earlier versions, but it does not prevent deletion requests. A normal delete creates a delete marker, while a request containing a specific version ID can permanently delete that version if permissions allow it.

What is the difference between an IAM policy and an S3 bucket policy?

An IAM policy is attached to an identity such as a user or role, while a bucket policy is attached to an S3 bucket. AWS evaluates applicable policies together, and an explicit deny overrides an allow.

Can an S3 Glacier object be downloaded immediately?

S3 Glacier Instant Retrieval supports immediate access. Objects in S3 Glacier Flexible Retrieval or Deep Archive normally require an asynchronous restore before they can be downloaded.

Why does S3 return AccessDenied even when IAM allows access?

Another control may deny the request, including a bucket policy, service control policy, permission boundary, VPC endpoint policy, Block Public Access setting or KMS key policy. Confirm the active principal and evaluate every policy layer involved in the request.

Related articles

Train with Network Rhinos

Hands-on CCNA, CCNP, AWS, Azure, DevOps and cybersecurity training in Chennai & Bangalore, with placement support. Talk to our team or attend a free demo class.