Build a Resilient S3 Vault
Build a local S3 vault and recover deleted documents with Versioning.
Introduction
30 Second Summary
Important documents can disappear through ordinary actions like saving over a file or pressing delete. Recovery only matters once the copy you needed is gone.
In this project, you will build a local document vault with LocalStack for AWS that follows an Amazon S3 workflow on your Mac. The vault will show how S3 Versioning recovers a document after accidental changes.
What You'll Build
Picture opening an approved report that you recovered after an accidental overwrite followed by deletion.
By the end of this project, you'll have:
- An inspectable local vault that returns the report you stored together with its object details.
- Direct evidence of the unversioned failure caused by an overwrite followed by deletion.
- A versioned recovery that brings the approved report back as the current document.
- Secret Mission: Generate a short-lived presigned URL to investigate LocalStack's default expiration behavior.
Are there any prerequisites?
You'll need a Mac with Docker Desktop running. Homebrew plus AWS CLI v2 must already be installed.
You'll also need a LocalStack account that can log in.
Before We Start
This first checkpoint is your moment to commit to building a recoverable document vault with LocalStack for AWS. You will use Amazon S3 object storage and S3 Versioning to understand how a vault handles accidental changes.
Set Up LocalStack for AWS
The AWS CLI sends service requests to AWS by default. Your document vault needs a verified local destination before you create any storage resources.
LocalStack for AWS provides that destination through a local emulator running in Docker. You will install its command-line interface through Homebrew so every project command can stay on your Mac.
In this step, get ready to:
- Verify your existing command-line prerequisites.
- Install the current lstk release through Homebrew.
- Start a verified local AWS emulator.
Verify your existing tools
The emulator depends on a working container engine. Its AWS wrapper also depends on AWS CLI version 2.
- Verify both installed prerequisites by running these commands:
docker ps
aws --version
What do these checks prove?
- The docker ps command confirms that Docker can answer container requests.
- The aws --version command prints the installed AWS CLI release.
You should see a container table without a Docker daemon problem. The AWS output should begin with aws-cli/2.
Prerequisite Check Failing?
- Confirm Docker Desktop is still running if the container check cannot reach the Docker daemon.
- Confirm your installed AWS CLI uses major version 2 if its output starts with a different number.
Help me diagnose my Docker or AWS CLI prerequisite check. You can also use the LocalStack community help page.
Install and diagnose the lstk CLI
The lstk CLI manages the local emulator. Its built-in diagnostic checks whether your Mac can support a working LocalStack session.
- Check whether lstk is already installed by running this command:
lstk --version
What Does This Check Show?
The command prints the installed lstk release. This project requires version 1.4.1 or a newer stable Homebrew release.
✔️ I see version 1.4.1 or higher
Good, your installed lstk release meets the project requirement. Continue to the diagnostic check below.
ⓧ I see an older version
Homebrew can upgrade the installed formula to its current stable release.
- Upgrade the installed lstk formula by running this command:
brew upgrade localstack/tap/lstk
What Does This Command Do?
Homebrew replaces the outdated formula with the current release from the LocalStack tap. The command leaves your other project tools in place.
- Check the upgraded version by running this command:
lstk --version
What Should You See?
The output should now include version 1.4.1 or a newer stable release.
Upgrade Still Showing an Older Version?
Make sure the upgrade completed without a Homebrew failure. Run the version check again in a fresh terminal window after the upgrade finishes.
Help me troubleshoot an lstk upgrade that still reports an older version. You can also ask in the LocalStack community.
ⓧ Command not found
Your Mac needs the lstk formula before it can manage the emulator.
- Install lstk through Homebrew by running this command:
brew install localstack/tap/lstk
What Does This Command Do?
Homebrew downloads the current stable lstk formula from the LocalStack tap. It then makes the command available in your terminal.
- Confirm the installation by running this command:
lstk --version
What Should You See?
The output should include version 1.4.1 or a newer stable Homebrew release.
Installation Command Failing?
Check the Homebrew output for a network problem or a write-permission problem. Resolve the named problem before repeating the installation.
Help me troubleshoot my Homebrew installation of lstk. You can also ask in the LocalStack community.
A version check proves that the command can start. The next diagnostic checks the local requirements that the emulator depends on.
- Diagnose your LocalStack environment by running this command:
lstk doctor
What Does the Diagnostic Check?
The diagnostic checks the container engine plus the local network. It also checks available memory plus disk access.
A passing result confirms that lstk can start the emulator with your current environment.
That clears the environment hurdle. The final line should report All checks passed.
Doctor Reports a Failed Check?
Use the failed check's description to identify the affected requirement. Confirm Docker Desktop is running before repeating the diagnostic.
Help me resolve the failed lstk doctor check. You can also bring the diagnostic result to the LocalStack community.
Start and verify the AWS emulator
The healthy CLI can now start the emulator inside Docker. Once it is running, lstk aws routes standard AWS service commands to that local endpoint.
Browser sign-in is expected during the first start. This is the normal authentication flow for the LocalStack account you already have.
- Start the AWS emulator by running this command:
lstk start
What Does This Command Start?
The command starts the LocalStack AWS Emulator in a Docker container. Its first execution can also trigger browser-based authentication.
- Choose the AWS emulator if the first-run selector appears.
- Complete the browser login with your LocalStack account when prompted.
Emulator Not Starting?
- Confirm Docker Desktop is still running if the container cannot start.
- Return to the browser login if the terminal is waiting for authentication.
Help me troubleshoot lstk start on my Mac. You can also ask in the LocalStack community.
Before you check the status, which emulator details do you expect the CLI to report?
- Check the emulator's running state by running this command:
lstk status
What Does the Status Prove?
The status check reads the running emulator session. It reports the local endpoint plus the Docker container name.
These details confirm that later lstk aws commands have a local destination.
You should see LocalStack AWS Emulator is running in the output. You should also see a local endpoint plus a container name.
✔️ My status matches
Your authenticated LocalStack AWS Emulator is running in Docker. The lstk aws wrapper is ready for your S3 commands.
ⓧ I'd like to double check the setup
Compare your setup with this completed state:
- The lstk CLI is installed through Homebrew at version 1.4.1 or a newer stable release.
- The lstk doctor diagnostic reports All checks passed.
- The LocalStack AWS Emulator is authenticated through your LocalStack account.
- The emulator runs in Docker with a local endpoint plus a container name reported by lstk status.
- The emulator is accessible through lstk aws.
Your local AWS foundation is ready. Next, you will create the document vault's first bucket plus its first object.
Store and Retrieve Your First Object
Your LocalStack for AWS emulator is running. Its local endpoint gives you a safe place to build the vault.
Amazon S3 stores each file as an object inside a bucket. A key names the object within that bucket.
You will put a report into that model with user-defined metadata. A download proves the vault returns the same content.
In this step, get ready to:
- Prepare the vault's local report plus its S3 bucket.
- Upload the report under a folder-like key with metadata.
- Inspect the object before retrieving its stored bytes.
Create the document and bucket
The local report provides the bytes that your first object stores. The bucket provides their destination inside the emulator.
- Switch back to the terminal from the previous step.
- Create the local report plus its bucket by running these commands:
mkdir -p vault
printf 'Quarterly report: draft 1\n' > vault/report.txt
lstk aws s3api create-bucket --bucket localstack-s3-vault
lstk aws s3api list-buckets
What do these commands do?
- The mkdir -p command creates the vault directory.
- The printf command writes the draft text to vault/report.txt.
- The create-bucket command creates localstack-s3-vault inside the emulator.
- The list-buckets command requests the current bucket list.
S3 Versioning is not enabled on this new bucket. It currently has no version history.
- Find localstack-s3-vault in the bucket listing.
Good, localstack-s3-vault is ready for your report.
Bucket missing from the listing?
- Confirm the LocalStack emulator from the previous step still reports a running state.
- Compare the bucket name in the creation command with localstack-s3-vault.
Help me diagnose why my LocalStack S3 bucket is missing from the bucket listing.
Upload the object with metadata
The key documents/report.txt gives the object a folder-like path in listings. Its metadata records the document stage plus its owner.
- Upload the report with its key plus metadata by running this command:
lstk aws s3api put-object \
--bucket localstack-s3-vault \
--key documents/report.txt \
--body vault/report.txt \
--metadata document-stage=draft,owner=learner
What does this upload command do?
- The --bucket option selects localstack-s3-vault as the destination.
- The --key option assigns the object its documents/report.txt name.
- The --body option reads the bytes from vault/report.txt.
- The --metadata option adds document-stage=draft plus owner=learner.
- Check the upload response for an ETag value.
That response confirms the emulator accepted the upload. Your draft now lives at documents/report.txt.
Upload command failing?
- Confirm vault/report.txt was created in the terminal's current location.
- Check the bucket name for an exact match with localstack-s3-vault.
- Check the object key for an exact match with documents/report.txt.
Help me troubleshoot my LocalStack S3 object upload.
Inspect and download the object
The bucket listing reveals the stored key. The metadata request reveals details without downloading the object body.
- Inspect the stored object by running these commands:
lstk aws s3api list-objects --bucket localstack-s3-vault
lstk aws s3api head-object --bucket localstack-s3-vault --key documents/report.txt
What do these inspection commands show?
- The list-objects command shows the current objects inside localstack-s3-vault.
- The head-object command returns details about documents/report.txt without returning its body.
- Locate documents/report.txt in the bucket listing.
- Find the size, ETag plus content type in the inspection response.
- Confirm the metadata includes document-stage plus owner.
These fields identify the stored object without exposing its contents.
Object missing from the inspection?
- Compare the inspected bucket name with localstack-s3-vault.
- Compare the inspected key with documents/report.txt.
- Return to the upload response to confirm it included an ETag.
Help me find why my uploaded S3 object is missing from the listing or metadata response.
Before you download the object, what exact line do you expect cat to print?
- Download the object plus display its stored content by running these commands:
lstk aws s3api get-object --bucket localstack-s3-vault --key documents/report.txt vault/downloaded-report.txt
cat vault/downloaded-report.txt
What do these retrieval commands do?
- The get-object command retrieves the bytes stored at documents/report.txt.
- The final path saves those bytes as vault/downloaded-report.txt.
- The cat command prints the downloaded file in your terminal.
- Confirm the terminal prints Quarterly report: draft 1.
You have completed the full object loop. Your vault stored the draft under a key before returning the same bytes to a new local file.
Downloaded file empty or missing?
- Check the retrieval response for a successful object download.
- Confirm the output path is exactly vault/downloaded-report.txt.
- Confirm the requested key is exactly documents/report.txt.
Help me troubleshoot why my downloaded S3 object does not contain the expected report text.
Your local vault can now store, inspect, plus retrieve a document. Next, you will test what happens when an unversioned object is replaced.
Break the Unversioned Vault
Your LocalStack for AWS vault already stores a draft report at documents/report.txt. Now you'll test how that vault behaves when routine commands go wrong.
An unversioned Amazon S3 object keeps one current value for an object key. You'll replace that value before deleting the current object.
In this step, get ready to:
- Overwrite the existing report at the same object key.
- Download the object to reveal which report the key returns.
- Delete the current object to expose the recovery gap.
Overwrite the report at the same key
Uploading new content to an existing key changes what a normal download returns. You'll reuse documents/report.txt so the destination stays exactly the same.
- Predict whether reusing the key will preserve both report contents.
- Rewrite vault/report.txt by running the first command below.
- Upload the rewritten report to the existing key by running the second command below.
printf 'Quarterly report: accidental overwrite\n' > vault/report.txt
lstk aws s3api put-object \
--bucket localstack-s3-vault \
--key documents/report.txt \
--body vault/report.txt
What do these commands do?
- The printf command rewrites the local report with the accidental overwrite text.
- The put-object command sends the rewritten file to the existing object key.
- The returned ETag confirms that the emulator stored the uploaded bytes.
Good, the emulator accepted the replacement request. The next check reveals which content the key now returns.
Did the overwrite command fail?
- Confirm the LocalStack container from earlier is still running.
- Check that the bucket name is exactly localstack-s3-vault.
- Check that vault/report.txt exists relative to your current terminal location.
Help me diagnose why this LocalStack overwrite command is failing.
Download the replacement
A normal object download asks for the current value at a key. Saving that response to a new local file gives you direct evidence of what survived the overwrite.
- Predict whether the downloaded file will contain the draft or the accidental overwrite.
- Download the current value to vault/overwritten-report.txt by running the first command below.
- Display the downloaded file by running the second command below.
lstk aws s3api get-object --bucket localstack-s3-vault --key documents/report.txt vault/overwritten-report.txt
cat vault/overwritten-report.txt
What do these commands prove?
- The get-object command retrieves the current value stored at documents/report.txt.
- The final argument saves those bytes to vault/overwritten-report.txt.
- The cat command prints the downloaded content in your terminal.
There it is: the same key now returns Quarterly report: accidental overwrite. The original draft is no longer available through that object key.
Still seeing the original draft?
- Check that the download command uses the key documents/report.txt.
- Check that the displayed file is vault/overwritten-report.txt.
- Confirm the earlier upload response included an ETag.
Help me find out why the downloaded object still contains the original draft.
Delete the current object
The overwrite left one current object at documents/report.txt. The next request removes that object before a metadata check tests what remains.
- Predict whether the metadata request will still find an object at the key.
- Delete the current object by running the first command below.
- Test whether the key still has a current object by running the second command below.
lstk aws s3api delete-object --bucket localstack-s3-vault --key documents/report.txt
lstk aws s3api head-object --bucket localstack-s3-vault --key documents/report.txt
What do these commands test?
- The delete-object command removes the current unversioned object at the specified key.
- The head-object command requests the object's metadata without downloading its body.
- Together, the commands test whether any current object remains available at that key.
The metadata request fails because the current object no longer exists. This failure is the intended result.
Because S3 Versioning was not enabled, this deletion created no delete marker. The bucket has no retained S3 version from which to recover the original draft.
Your earlier local copy in vault/downloaded-report.txt remains untouched. It still contains Quarterly report: draft 1.
Does head-object still return metadata?
- Check that the --bucket value is localstack-s3-vault.
- Check that the --key value is documents/report.txt.
- Confirm the delete request completed before the metadata request ran.
Help me diagnose why head-object still finds the object after delete-object ran.
That's the recovery gap exposed: your unversioned vault has no object history to restore. Next, you'll enable S3 Versioning so future replacements and deletions leave recoverable evidence behind.
Protect the Vault with S3 Versioning
Your LocalStack vault has exposed the cost of an unversioned key. The overwrite erased its earlier value.
The later deletion removed the current object. There was no stored history available for recovery.
Now you will enable S3 Versioning on the same bucket. Future overwrites will create recoverable object versions.
A future delete will add a delete marker that hides the current key. The saved versions will remain available for recovery.
In this step, get ready to:
- Enable S3 Versioning on the existing vault bucket.
- Create approved and accidental object versions at the same key.
- Delete the current object to reveal its retained history.
Enable S3 Versioning
Versioning is a bucket-level setting that applies to future changes. Once enabled, each new upload at the same key receives its own version ID.
Before you run these commands, picture the status you expect the bucket to report.
- Apply the enabled status and read it back by running these commands:
lstk aws s3api put-bucket-versioning \
--bucket localstack-s3-vault \
--versioning-configuration Status=Enabled
lstk aws s3api get-bucket-versioning --bucket localstack-s3-vault
What do these commands do?
- The put-bucket-versioning operation changes the bucket's Versioning status to Enabled.
- The get-bucket-versioning operation reads the current status from the bucket.
- The LocalStack AWS wrapper keeps both operations inside your local emulator.
You should see "Status": "Enabled" in the second response.
That is the safety layer in place: new writes can now leave recoverable history.
Versioning status missing?
- Check that the bucket name is exactly localstack-s3-vault.
- Return to the LocalStack status check from Step 1 if the wrapper cannot reach the emulator.
- Confirm that the Versioning configuration uses Status=Enabled with matching capitalization.
Help me diagnose why my LocalStack bucket does not report Versioning as enabled.
Create two recoverable versions
Versioning records each upload separately even when the key stays the same. You will first store an approved report at documents/report.txt.
- Create the approved object version by running both commands below:
printf 'Quarterly report: approved\n' > vault/report.txt
lstk aws s3api put-object \
--bucket localstack-s3-vault \
--key documents/report.txt \
--body vault/report.txt
What creates the approved version?
- The printf command replaces the local report with the approved content.
- The put-object operation uploads those bytes to documents/report.txt.
- Enabled Versioning assigns a unique VersionId to this upload.
The upload response should now include a VersionId for the approved report.
- Record the returned ID for the approved upload: approved version ID.
Missing a VersionId?
- Confirm that the bucket still reports a Versioning status of Enabled.
- Look above the upload response for a connection error or bucket error.
- Check that vault/report.txt exists inside the same terminal location used in the earlier steps.
Help me find out why my versioned LocalStack upload did not return a VersionId.
Before you replace the file, predict whether the approved version will remain in the bucket history.
- Create the accidental replacement version by running both commands below:
printf 'Quarterly report: accidental replacement\n' > vault/report.txt
lstk aws s3api put-object \
--bucket localstack-s3-vault \
--key documents/report.txt \
--body vault/report.txt
Why does this preserve both values?
- The local vault/report.txt file now contains the accidental replacement.
- The upload uses the existing documents/report.txt key.
- Versioning stores this upload under a new VersionId while retaining the approved version.
The replacement response should show a different VersionId from the approved response.
- Record the returned ID for the accidental replacement: replacement version ID.
Good work. The same key now has two recoverable values.
Version IDs look the same?
- Confirm that the approved upload completed before you ran the replacement upload.
- Check that each upload response contains its own VersionId.
- Confirm that Versioning remained enabled between the two uploads.
Help me verify whether my two LocalStack S3 uploads created separate object versions.
Add a delete marker and inspect the history
A simple delete in a versioned bucket creates a marker that becomes the current version. The marker hides the key without erasing the stored object versions.
Before you run these commands, predict how many saved versions and delete markers the history will contain.
- Reveal the versioned deletion behavior by running these commands:
lstk aws s3api delete-object --bucket localstack-s3-vault --key documents/report.txt
lstk aws s3api list-object-versions \
--bucket localstack-s3-vault \
--prefix documents/report.txt
What does versioned deletion preserve?
- The delete-object operation creates a delete marker for the key.
- The delete marker becomes the current version of documents/report.txt.
- The list-object-versions operation returns the retained object versions plus the current marker.
- Record the version ID attached to the current delete marker: delete marker version ID.
The history output should contain two entries under Versions.
It should also contain one entry under DeleteMarkers.
The newest delete marker now hides documents/report.txt from a normal current-object request. Both stored versions remain available.
You have turned the destructive path into a recoverable history: two values survive behind one delete marker.
History entries missing?
- Confirm that the approved upload returned a VersionId.
- Confirm that the replacement upload returned a different VersionId.
- Check that the delete response identifies a delete marker.
Help me diagnose why my LocalStack object history does not show two versions and one delete marker.
✔️ Awesome, I've got everything!
Your bucket reports Versioning as enabled. Its object history now shows two retained versions plus one current delete marker.
ⓧ I'd like to double check the full code
Compare your terminal commands with the complete sequence for this step:
lstk aws s3api put-bucket-versioning \
--bucket localstack-s3-vault \
--versioning-configuration Status=Enabled
lstk aws s3api get-bucket-versioning --bucket localstack-s3-vault
printf 'Quarterly report: approved\n' > vault/report.txt
lstk aws s3api put-object \
--bucket localstack-s3-vault \
--key documents/report.txt \
--body vault/report.txt
printf 'Quarterly report: accidental replacement\n' > vault/report.txt
lstk aws s3api put-object \
--bucket localstack-s3-vault \
--key documents/report.txt \
--body vault/report.txt
lstk aws s3api delete-object --bucket localstack-s3-vault --key documents/report.txt
lstk aws s3api list-object-versions \
--bucket localstack-s3-vault \
--prefix documents/report.txt
What should this sequence produce?
- The first operation enables Versioning on localstack-s3-vault.
- The status check confirms that the bucket reports Enabled.
- The two upload pairs create the approved version plus the accidental replacement version.
- The final pair creates a current delete marker before displaying the retained history.
Your vault now keeps evidence of overwrites and deletions. Next up, you will choose the approved version and restore it as the current document.
Recover the Deleted Document
Your S3 Versioning history now holds two object versions behind a delete marker. That retained history gives you a recovery path.
You will use the approved version ID to download the earlier bytes. You will upload those bytes as a new current version.
In this step, get ready to:
- Download the approved historical version.
- Promote the recovered document to the current key.
- Verify that a normal download returns the approved report.
Retrieve the approved version
Each retained object version has its own version ID. Selecting that ID retrieves one exact historical value from the key.
- Return to the list-object-versions output from the previous step.
- Locate the VersionId for the earlier upload containing Quarterly report: approved.
- Copy that VersionId into this field: your approved version ID.
- Replace PASTE_VERSION_ID_HERE in the command below with your approved version ID.
Before you run these commands, predict which retained report value cat prints:
- Retrieve the approved version by running these edited commands:
lstk aws s3api get-object \
--bucket localstack-s3-vault \
--key documents/report.txt \
--version-id PASTE_VERSION_ID_HERE \
vault/recovered-report.txt
cat vault/recovered-report.txt
How Does Version Recovery Work?
- The --version-id option selects one retained object version instead of requesting the current key state.
- The vault/recovered-report.txt path stores the historical bytes on your Mac.
- The cat command prints the recovered file so you can identify its content.
You should see Quarterly report: approved in your terminal. That is the recovery turning point: the approved historical version now exists in vault/recovered-report.txt.
Retrieved the Wrong Version?
- Check that you replaced PASTE_VERSION_ID_HERE with the approved version ID from the earlier upload.
- Try the other stored version ID if cat prints Quarterly report: accidental replacement.
Help me retrieve the approved object version.
Promote the recovered document
The historical download gives you a local recovery file. A new upload creates a current version at the same key.
- Upload the recovered bytes as the current object by running this command:
lstk aws s3api put-object \
--bucket localstack-s3-vault \
--key documents/report.txt \
--body vault/recovered-report.txt
What Does This Upload Do?
- The put-object request writes the bytes from vault/recovered-report.txt to documents/report.txt.
- The enabled versioning setting creates a new VersionId for this upload.
- The earlier object versions remain in the bucket history.
- The delete marker also remains in the bucket history.
You should see a new VersionId in the response. Your recovered report now has its own current version.
Upload Not Completing?
- Check that the --body value points to vault/recovered-report.txt.
- Confirm the emulator from earlier is still running.
Help me promote my recovered report.
Verify the current object
A normal download omits the version ID. This check proves the recovered upload is now current.
Before you run the final check, predict which report text a request without a version ID returns:
- Download the current object to vault/final-report.txt by running these commands:
lstk aws s3api get-object \
--bucket localstack-s3-vault \
--key documents/report.txt \
vault/final-report.txt
cat vault/final-report.txt
What Does the Final Check Prove?
- The get-object request omits --version-id, so it retrieves the current object.
- The downloaded bytes are saved in vault/final-report.txt.
- The cat command reveals which report is current.
You should see Quarterly report: approved in your terminal. You did it: the approved report is current again without erasing its history.
Final Report Not Approved?
- Check that the download command saves the object to vault/final-report.txt.
- Confirm the previous upload used vault/recovered-report.txt as its body.
- Repeat the historical retrieval with the other stored version ID if the accidental replacement was promoted.
Help me verify the recovered current object.
Secret mission
Share the Vault with a Presigned URL
Your recovered report is private to CLI requests. Generate a 60-second presigned URL to share it. Then test whether the emulator enforces the expiry you expect.
Clean Up Your Resources
Clean Up Your Resources
Your vault runs locally through the free LocalStack for AWS Hobby plan for non-commercial learning, so this project creates no Amazon S3 charges. Decide whether to keep the emulator running, stop it while retaining your local files, or remove the project entirely.
Resources you used:
- A LocalStack for AWS emulator container running in Docker Desktop.
- An emulated Amazon S3 bucket named localstack-s3-vault with retained S3 Versioning history for documents/report.txt.
- The local vault folder containing your five report files.
Keep everything running
No action needed. Choose this if you want to keep testing the current vault session.
Your bucket remains available while the current emulator session stays running. The emulator continues using your Mac's memory and CPU.
There are no Amazon S3 charges for keeping this local session active.
Pause - I'll come back to this later
Stop the emulator to reclaim local memory while keeping the vault folder on disk. LocalStack's default ephemeral storage clears the emulated bucket when the instance stops.
- Switch back to Docker Desktop from earlier.
- Select the running LocalStack container in the container list.
- Use the stop control in that container's row.
That's the local compute reclaimed: the emulator is no longer using your Mac's memory or CPU.
Your report files remain inside vault. You need to recreate the bucket plus its version history when you return.
Delete - I don't want to use this again
This option removes the emulator container plus the vault folder. The project files cannot be restored after the next actions.
Everything removed here belongs only to this local exercise. Your real Amazon S3 resources stay untouched.
- Switch back to Docker Desktop from earlier.
- Select the LocalStack container in the container list.
- Use the stop control in the container's row.
- Use the delete control in the same row after the container stops.
That removes the local emulator session. Stopping the default ephemeral instance also clears localstack-s3-vault plus its object version history.
- Switch back to the terminal directory where you created vault.
- Remove the vault folder by running this command:
rm -rf vault
What does this command remove?
The command permanently removes the vault folder plus every report file inside it.
- Click Finder in your Mac's Dock.
- Navigate to the directory that previously contained vault.
- Confirm that vault is no longer listed.
Still see the vault folder?
- Return to the terminal directory that directly contains vault.
- Run the removal command above again.
Get help locating the correct folder with this cleanup prompt.
Nice Work!
Nice Work!
You did it! Your recoverable Amazon S3 document vault in LocalStack for AWS now serves the approved report you restored from retained history.
You've learned how to:
- Operated a local vault through AWS CLI requests routed by lstk aws. You stored a report under a folder-like object key. You inspected its metadata. You downloaded its exact contents.
- Demonstrated the risk of an unversioned vault through an accidental overwrite. You deleted the current object. You confirmed that no recoverable history remained.
- Enabled S3 Versioning to preserve later overwrites as separate versions. You observed a delete marker while earlier versions remained available. You recovered the approved report with its version ID. You promoted the recovered bytes to the current object.
- Completed the optional Secret Mission by generating a short-lived presigned URL for the recovered report. You found that LocalStack could still serve it after the nominal 60-second lifetime. That result exposed an emulator parity gap with Amazon S3.
Ready to quiz yourself?