{"id":2117,"date":"2026-02-08T01:07:58","date_gmt":"2026-02-07T12:07:58","guid":{"rendered":"https:\/\/www.ronella.xyz\/?p=2117"},"modified":"2026-02-08T01:07:59","modified_gmt":"2026-02-07T12:07:59","slug":"simple-terraform-config-to-setup-aws-s3-sandbox-in-localstack","status":"publish","type":"post","link":"https:\/\/www.ronella.xyz\/?p=2117","title":{"rendered":"Simple Terraform Config to Setup AWS S3 Sandbox in LocalStack"},"content":{"rendered":"<p>This article shows how to run a local AWS\u2011like S3 environment with LocalStack in Docker, manage buckets with Terraform, and inspect everything visually using an S3 GUI client such as S3 Browser (or any S3\u2011compatible desktop app).<\/p>\n<hr \/>\n<h2>1. Overview of the setup<\/h2>\n<p>You will end up with:<\/p>\n<ul>\n<li>LocalStack running via <code>docker-compose.yml<\/code>, exposing S3 on <code>http:\/\/localhost:4566<\/code>.<\/li>\n<li>Terraform creating an S3 bucket, enabling versioning, and adding a lifecycle rule.<\/li>\n<li>S3 Browser (or a similar S3 GUI) connected to LocalStack so you can see buckets and object versions visually.<\/li>\n<\/ul>\n<p><strong>Rationale:<\/strong> this mirrors a real AWS workflow (Infra as Code + GUI) while remaining entirely local and safe to experiment with.<\/p>\n<hr \/>\n<h2>2. LocalStack with <code>docker-compose.yml<\/code><\/h2>\n<p>Create a working directory, e.g. <code>localstack-s3-terraform<\/code>, and add <code>docker-compose.yml<\/code>:<\/p>\n<pre><code class=\"language-yaml\">version: &quot;3.8&quot;\n\nservices:\n  localstack:\n    image: localstack\/localstack:latest\n    container_name: localstack\n    ports:\n      - &quot;4566:4566&quot;          # Edge port: all services, including S3\n      - &quot;4510-4559:4510-4559&quot;\n    environment:\n      - SERVICES=s3          # Only start S3 for this demo\n      - DEBUG=1\n      - DOCKER_HOST=unix:\/\/\/var\/run\/docker.sock\n    volumes:\n      - &quot;.\/localstack-data:\/var\/lib\/localstack&quot;\n      - &quot;\/var\/run\/docker.sock:\/var\/run\/docker.sock&quot;<\/code><\/pre>\n<p>Key aspects:<\/p>\n<ul>\n<li>Port <strong>4566<\/strong> is the single \u201cedge\u201d endpoint for S3 and other services in current LocalStack.<\/li>\n<li><code>SERVICES=s3<\/code> keeps the environment focused and startup fast.<\/li>\n<li><code>.\/localstack-data<\/code> persists LocalStack state (buckets and objects) between restarts.<\/li>\n<\/ul>\n<p>Start LocalStack:<\/p>\n<pre><code class=\"language-shell\">docker compose up -d<\/code><\/pre>\n<hr \/>\n<h2>3. Terraform config with versioning and lifecycle<\/h2>\n<p>In the same directory, create <code>main.tf<\/code> containing the AWS provider configured for LocalStack and S3 with versioning + lifecycle policy:<\/p>\n<pre><code class=\"language-terraform\">terraform {\n  required_providers {\n    aws = {\n      source  = &quot;hashicorp\/aws&quot;\n      version = &quot;~&gt; 5.0&quot;\n    }\n  }\n}\n\nprovider &quot;aws&quot; {\n  region                      = &quot;ap-southeast-2&quot;\n  access_key                  = &quot;test&quot;\n  secret_key                  = &quot;test&quot;\n  skip_credentials_validation = true\n  skip_metadata_api_check     = true\n  skip_requesting_account_id  = true\n  s3_use_path_style           = true\n\n  endpoints {\n    s3 = &quot;http:\/\/localhost:4566&quot;\n  }\n}\n\nresource &quot;aws_s3_bucket&quot; &quot;demo&quot; {\n  bucket = &quot;demo-bucket-localstack&quot;\n}\n\nresource &quot;aws_s3_bucket_versioning&quot; &quot;demo_versioning&quot; {\n  bucket = aws_s3_bucket.demo.id\n\n  versioning_configuration {\n    status = &quot;Enabled&quot;\n  }\n}\n\nresource &quot;aws_s3_bucket_lifecycle_configuration&quot; &quot;demo_lifecycle&quot; {\n  bucket = aws_s3_bucket.demo.id\n\n  rule {\n    id     = &quot;expire-noncurrent-30-days&quot;\n    status = &quot;Enabled&quot;\n\n    filter {\n      prefix = &quot;&quot; # apply to all objects\n    }\n\n    noncurrent_version_expiration {\n      noncurrent_days = 30\n    }\n  }\n}<\/code><\/pre>\n<p>Important Terraform points:<\/p>\n<ul>\n<li><strong>Provider<\/strong>: points to <code>http:\/\/localhost:4566<\/code> so all S3 calls go to LocalStack, not AWS.<\/li>\n<li><strong>Dummy credentials<\/strong> (<code>test<\/code> \/ <code>test<\/code>) are sufficient; LocalStack doesn\u2019t validate real AWS keys.<\/li>\n<li><strong>Versioning<\/strong> is modeled as a separate resource to clearly express bucket behavior.<\/li>\n<li><strong>Lifecycle configuration<\/strong> is modeled explicitly as well, aligning with AWS best practices and lifecycle examples.<\/li>\n<\/ul>\n<p>Initialize and apply:<\/p>\n<pre><code class=\"language-shell\">terraform init\nterraform apply<\/code><\/pre>\n<p>Confirm when prompted; Terraform will create the bucket, enable versioning, and attach the lifecycle rule.<\/p>\n<hr \/>\n<h2>4. Configuring S3 Browser (or similar GUI) for LocalStack<\/h2>\n<p>Now that LocalStack is running and Terraform has created your bucket, you connect S3 Browser (or any S3 GUI) to LocalStack instead of AWS.<\/p>\n<p>In S3 Browser, create a new account\/profile with something like:<\/p>\n<ul>\n<li><strong>Account name<\/strong>: <code>LocalStack<\/code> (any label you like).<\/li>\n<li><strong>S3 endpoint \/ server<\/strong>: <code>http:\/\/localhost:4566<\/code><\/li>\n<li><strong>Access key<\/strong>: <code>test<\/code><\/li>\n<li><strong>Secret key<\/strong>: <code>test<\/code><\/li>\n<li><strong>Region<\/strong>: <code>ap-southeast-2<\/code><\/li>\n<\/ul>\n<p>Make sure your client is configured to use the custom endpoint instead of the standard AWS endpoints (this is usually done in an \u201cS3 Compatible Storage\u201d as the <strong>Account Type<\/strong>).<\/p>\n<p>Once saved and connected:<\/p>\n<ul>\n<li>You should see the bucket <code>demo-bucket-localstack<\/code> in the bucket list.<\/li>\n<li>Opening the bucket lets you upload, delete, and browse objects, just as if you were talking to real S3.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This article shows how to run a local AWS\u2011like S3 environment with LocalStack in Docker, manage buckets with Terraform, and inspect everything visually using an S3 GUI client such as S3 Browser (or any S3\u2011compatible desktop app). 1. Overview of the setup You will end up with: LocalStack running via docker-compose.yml, exposing S3 on http:\/\/localhost:4566. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[94],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/2117"}],"collection":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2117"}],"version-history":[{"count":1,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/2117\/revisions"}],"predecessor-version":[{"id":2118,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/2117\/revisions\/2118"}],"wp:attachment":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2117"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2117"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2117"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}