Task

Locked Down by Default: S3 Bucket with Security Features

Terraform · 20 min · Practical

This configuration creates an S3 bucket and layers four security-focused resources on top of it: descriptive tags, a public access block, versioning, and server-side encryption — the baseline most teams expect from any production bucket.

Four Security Controls

TagsName · Key
Public Access BlockAll 4 flags true
VersioningDisabled
EncryptionSSE-S3 / AES256

The Full Configuration

main.tf
# Configure the AWS Provider
provider "aws" {
  region = "ap-south-1"
}

# Create an S3 Bucket
resource "aws_s3_bucket" "akshan" {
  bucket = "akshanmugananthan"

  # Bucket Tags
  tags = {
    Name = "terraform bucket"
    Key  = "trail"
  }
}

# Block Public Access
resource "aws_s3_bucket_public_access_block" "block_public" {
  bucket = aws_s3_bucket.akshan.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# Enable Bucket Versioning
resource "aws_s3_bucket_versioning" "bucket_version" {
  bucket = aws_s3_bucket.akshan.id
  versioning_configuration {
    status = "Disabled"
  }
}

# Enable Server-Side Encryption
resource "aws_s3_bucket_server_side_encryption_configuration" "encrypt" {
  bucket = aws_s3_bucket.akshan.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

Explanation

region = "ap-south-1"

Configures the AWS provider. Every resource in this file gets created in the Mumbai (ap-south-1) region.

main.tf
provider "aws" {
  region = "ap-south-1"
}

aws_s3_bucket.akshan

Creates an S3 bucket named akshanmugananthan. The resource name akshan is just a local label — it's how other resources in this file reference the bucket.

main.tf
resource "aws_s3_bucket" "akshan"

Organizing the Bucket

Tags help you find, filter, and cost-allocate AWS resources later. Neither tag here is required by AWS — they're purely organizational.

TagValue
Nameterraform bucket
Keytrail

aws_s3_bucket_public_access_block.block_public

Prevents the bucket from ever being made publicly accessible, regardless of what an ACL or bucket policy elsewhere might try to grant.

  • block_public_acls true — blocks new public ACLs from being applied to the bucket or its objects.
  • block_public_policy true — blocks any bucket policy that would grant public access.
  • ignore_public_acls true — ignores any public ACLs that already exist on the bucket.
  • restrict_public_buckets true — restricts access to the bucket even for policies that would otherwise allow it.

aws_s3_bucket_versioning.bucket_version

Controls object versioning, which protects against accidental deletion or overwriting by keeping every prior version of an object. This config currently sets it to "Disabled".

main.tf
status = "Enabled"

aws_s3_bucket_server_side_encryption_configuration.encrypt

Automatically encrypts every object uploaded to the bucket using AES256 — Amazon S3's own managed server-side encryption. No client-side changes are needed; objects are encrypted at rest by default.

Resource References

main.tf
aws_s3_bucket.akshan.id
  • aws_s3_bucket
  • ↓ resource type
  • akshan
  • ↓ resource name
  • .id
  • ↓ attribute
  • Bucket ID

All three sub-resources — public access block, versioning, and encryption — attach to the bucket the same way: by pointing their bucket argument at this reference.

Terraform Commands

  1. terraform init — initialize the project and download the AWS provider.
  2. terraform validate — check the configuration for errors.
  3. terraform fmt — format the code to standard style.
  4. terraform plan — preview exactly what will be created.
  5. terraform apply — create the bucket and all four security resources.
  6. terraform destroy — delete everything this configuration manages.
terminal
terminalEND TO END

$ terraform init
$ terraform validate
$ terraform fmt
$ terraform plan
$ terraform apply
# when no longer needed
$ terraform destroy