Skip to main content

AWS S3 Bucket Versioning: Overview, AWS CLI Commands

883 words·
AWS AWS CLI S3 Bucket Versioning
Table of Contents

Example S3 Bucket
#

Create S3 Bucket
#

# Create a new S3 bucket in "eu-central-1"
aws s3api create-bucket \
    --bucket jkw-example-bucket \
    --region eu-central-1 \
    --create-bucket-configuration LocationConstraint=eu-central-1

# Shell output:
{
    "Location": "http://jkw-example-bucket.s3.amazonaws.com/"
}

Enable Bucket Versioning
#

  • S3 Versioning: Is a feature that keeps multiple versions of an object (for example the terraform.tfstate file) instead of overwriting it.
# Enable versioning
aws s3api put-bucket-versioning \
  --bucket jkw-example-bucket \
  --versioning-configuration Status=Enabled \
  --region eu-central-1
# Verify that versioning is enabled
aws s3api get-bucket-versioning --bucket jkw-example-bucket

# Shell output:
{
    "Status": "Enabled"
}



Object Version Example Commands
#

Retrieve Specific File Version
#

Upload an Example File
#

# Create an example file
echo "Version 1" > example-file.txt

# Upload the file to the S3 Bucket
aws s3 cp example-file.txt s3://jkw-example-bucket/

Verify Object Version
#

# List object versions
aws s3api list-object-versions --bucket jkw-example-bucket

# Shell output:
{
    "Versions": [
        {
            "ETag": "\"174b29d6d688c2b34f6c1bb7361a8b7e\"",
            "Size": 10,
            "StorageClass": "STANDARD",
            "Key": "example-file.txt",
            "VersionId": "OoE7GqIdXWGxXOg56_yQHzxZfGVF85AN",
            "IsLatest": true,
            "LastModified": "2025-01-29T12:34:23+00:00",
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            }
        }
    ],
    "RequestCharged": null,
    "Prefix": ""
}

Upload a New Version of the Same File
#

# Create an example file
echo "Version 2" > example-file.txt

# Upload the file to the S3 Bucket
aws s3 cp example-file.txt s3://jkw-example-bucket/

Verify Object Versions
#

Now there are two versions of the file available:

# List object versions
aws s3api list-object-versions --bucket jkw-example-bucket

# Shell output:
{
    "Versions": [
        {
            "ETag": "\"1f5f1ebe10ac3457ca87427e1772d71f\"",
            "Size": 10,
            "StorageClass": "STANDARD",
            "Key": "example-file.txt",
            "VersionId": "5R6HyZvebeFiP2Jsy1AEaUfndNJCXZXR",
            "IsLatest": true,
            "LastModified": "2025-01-29T12:34:46+00:00",
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            }
        },
        {
            "ETag": "\"174b29d6d688c2b34f6c1bb7361a8b7e\"",
            "Size": 10,
            "StorageClass": "STANDARD",
            "Key": "example-file.txt",
            "VersionId": "OoE7GqIdXWGxXOg56_yQHzxZfGVF85AN",
            "IsLatest": false,
            "LastModified": "2025-01-29T12:34:23+00:00",
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            }
        }
    ],
    "RequestCharged": null,
    "Prefix": ""
}

Retrieve a Specific Version of the Object
#

# Locally retrieve the first version of the example file
aws s3api get-object --bucket jkw-example-bucket --key example-file.txt --version-id OoE7GqIdXWGxXOg56_yQHzxZfGVF85AN example-file-first-version.txt

# Shell output:
{
    "AcceptRanges": "bytes",
    "LastModified": "2025-01-29T12:34:23+00:00",
    "ContentLength": 10,
    "ETag": "\"174b29d6d688c2b34f6c1bb7361a8b7e\"",
    "VersionId": "OoE7GqIdXWGxXOg56_yQHzxZfGVF85AN",
    "ContentType": "text/plain",
    "ServerSideEncryption": "AES256",
    "Metadata": {}
}
  • --key example-file.txt File name

  • --version-id OoE7GqIdXWGxXOg56_yQHzxZfGVF85AN Version of the file

# Verify the file version
cat example-file-first-version.txt

# Shell output:
Version 1



Delete and Restore File
#

Delete the File and Verify Soft Deletion
#

# Delete the example file
aws s3 rm s3://jkw-example-bucket/example-file.txt

# Verify the file was deleted
aws s3 ls s3://jkw-example-bucket/

Verify Object Versions & Delete Markers
#

The file appears deleted in a standard S3 listing but still exists in version history:

# List object versions
aws s3api list-object-versions --bucket jkw-example-bucket

# Shell output:
{
    "Versions": [
        {
            "ETag": "\"1f5f1ebe10ac3457ca87427e1772d71f\"",
            "Size": 10,
            "StorageClass": "STANDARD",
            "Key": "example-file.txt",
            "VersionId": "5R6HyZvebeFiP2Jsy1AEaUfndNJCXZXR",
            "IsLatest": false,
            "LastModified": "2025-01-29T12:34:46+00:00",
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            }
        },
        {
            "ETag": "\"174b29d6d688c2b34f6c1bb7361a8b7e\"",
            "Size": 10,
            "StorageClass": "STANDARD",
            "Key": "example-file.txt",
            "VersionId": "OoE7GqIdXWGxXOg56_yQHzxZfGVF85AN",
            "IsLatest": false,
            "LastModified": "2025-01-29T12:34:23+00:00",
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            }
        }
    ],
    "DeleteMarkers": [
        {
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            },
            "Key": "example-file.txt",
            "VersionId": "R5qIEY80YctUxMV8fl5RFnH0NSMMp9ul",
            "IsLatest": true,
            "LastModified": "2025-01-29T12:35:46+00:00"
        }
    ],
    "RequestCharged": null,
    "Prefix": ""
}

Restore Object / Remove the Delete Marker
#

# Remove the Delete Marker
aws s3api delete-object --bucket jkw-example-bucket --key example-file.txt --version-id R5qIEY80YctUxMV8fl5RFnH0NSMMp9ul

# Shell output:
{
    "DeleteMarker": true,
    "VersionId": "R5qIEY80YctUxMV8fl5RFnH0NSMMp9ul"
}

Verify Object Versions
#

The file appears deleted in a standard S3 listing but still exists in version history:

# List object versions
aws s3api list-object-versions --bucket jkw-example-bucket

# Shell output:
{
    "Versions": [
        {
            "ETag": "\"1f5f1ebe10ac3457ca87427e1772d71f\"",
            "Size": 10,
            "StorageClass": "STANDARD",
            "Key": "example-file.txt",
            "VersionId": "5R6HyZvebeFiP2Jsy1AEaUfndNJCXZXR",
            "IsLatest": true,
            "LastModified": "2025-01-29T12:34:46+00:00",
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            }
        },
        {
            "ETag": "\"174b29d6d688c2b34f6c1bb7361a8b7e\"",
            "Size": 10,
            "StorageClass": "STANDARD",
            "Key": "example-file.txt",
            "VersionId": "OoE7GqIdXWGxXOg56_yQHzxZfGVF85AN",
            "IsLatest": false,
            "LastModified": "2025-01-29T12:34:23+00:00",
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            }
        }
    ],
    "RequestCharged": null,
    "Prefix": ""
}

Verify the File
#

# Verify the file is available
aws s3 ls s3://jkw-example-bucket/

# Shell output:
2025-01-29 12:34:46         10 example-file.txt



Permanently Delete an Object Version
#

List All Versions of the File
#

# List all versions of the file
aws s3api list-object-versions --bucket jkw-example-bucket --prefix example-file.txt

# Shell output:
{
    "Versions": [
        {
            "ETag": "\"1f5f1ebe10ac3457ca87427e1772d71f\"",
            "Size": 10,
            "StorageClass": "STANDARD",
            "Key": "example-file.txt",
            "VersionId": "5R6HyZvebeFiP2Jsy1AEaUfndNJCXZXR",
            "IsLatest": true,
            "LastModified": "2025-01-29T12:34:46+00:00",
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            }
        },
        {
            "ETag": "\"174b29d6d688c2b34f6c1bb7361a8b7e\"",
            "Size": 10,
            "StorageClass": "STANDARD",
            "Key": "example-file.txt",
            "VersionId": "OoE7GqIdXWGxXOg56_yQHzxZfGVF85AN",
            "IsLatest": false,
            "LastModified": "2025-01-29T12:34:23+00:00",
            "Owner": {
                "ID": "cf6353e10e3f9fbc37d9707ffc86e07fbb1975aebc9ae10b9a820c05d56e3af9"
            }
        }
    ],
    "RequestCharged": null,
    "Prefix": "example-file.txt"
}

Delete all Versions of the File
#

# Delete all versions
aws s3api delete-object --bucket jkw-example-bucket --key example-file.txt --version-id 5R6HyZvebeFiP2Jsy1AEaUfndNJCXZXR
aws s3api delete-object --bucket jkw-example-bucket --key example-file.txt --version-id OoE7GqIdXWGxXOg56_yQHzxZfGVF85AN

Verify the File is Completely Removed
#

# List all versions of the file
aws s3api list-object-versions --bucket jkw-example-bucket --prefix example-file.txt

# Shell output:
{
    "RequestCharged": null,
    "Prefix": "example-file.txt"
}
# List objects
aws s3 ls s3://jkw-example-bucket/ --recursive



Cleanup
#

Delete S3 Bucket
#

# Delete all objects and their versions
aws s3api list-object-versions --bucket jkw-example-bucket --query 'Versions[].{Key:Key,VersionId:VersionId}' --output json | jq -c '.[]' | while read i; do
  key=$(echo $i | jq -r '.Key')
  version=$(echo $i | jq -r '.VersionId')
  aws s3api delete-object --bucket jkw-example-bucket --key "$key" --version-id "$version"
done

# Delete all markers
aws s3api list-object-versions --bucket jkw-example-bucket --query 'DeleteMarkers[].{Key:Key,VersionId:VersionId}' --output json | jq -c '.[]' | while read i; do
  key=$(echo $i | jq -r '.Key')
  version=$(echo $i | jq -r '.VersionId')
  aws s3api delete-object --bucket jkw-example-bucket --key "$key" --version-id "$version"
done

# Delete S3 Bucket
aws s3api delete-bucket \
  --bucket jkw-example-bucket \
  --region eu-central-1