How to Create an AWS S3 Bucket with Terraform

Creating an S3 bucket in Terraform is the aws_s3_bucket resource. Since AWS provider v4 the extra settings (versioning, encryption) moved to their own resources - here's the working setup and the errors that block apply.

DevOps Engineerterraformawss3

The basic bucket

resource "aws_s3_bucket" "analytics" {
  bucket = "my-company-analytics"   # globally unique name
}

That's the whole resource. bucket is the (globally unique) name. Run it with:

terraform init
terraform apply -auto-approve

"Unsupported argument" - the v4+ gotcha

Before AWS provider v4 you set versioning, server_side_encryption_configuration, etc. inside the bucket resource. In v4+ those are separate resources, so old-style arguments now error:

Error: Unsupported argument
  on main.tf: an argument named "versioning" is not expected here.

The fix is to break them out:

resource "aws_s3_bucket_versioning" "analytics" {
  bucket = aws_s3_bucket.analytics.id
  versioning_configuration { status = "Enabled" }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "analytics" {
  bucket = aws_s3_bucket.analytics.id
  rule {
    apply_server_side_encryption_by_default { sse_algorithm = "AES256" }
  }
}

(A plain typo - buckkket = "..." - produces the same "Unsupported argument" error; read the line number Terraform prints and fix that argument.)

Lock it down (you almost always want these)

resource "aws_s3_bucket_public_access_block" "analytics" {
  bucket                  = aws_s3_bucket.analytics.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

How to debug a failing apply

Common aws_s3_bucket errors

Run terraform plan after every change - the AWS provider validates most of these before any API call, so you catch them locally instead of mid-apply.

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

How do I create an S3 bucket in Terraform?

Use the aws_s3_bucket resource with a globally-unique bucket name, then terraform init and terraform apply. Versioning and encryption are now separate resources (aws_s3_bucket_versioning, aws_s3_bucket_server_side_encryption_configuration).

Why does Terraform say 'Unsupported argument' on aws_s3_bucket?

Since AWS provider v4, settings like versioning and encryption moved out of the bucket resource into their own resources - or it's a plain typo. Read the named argument + line number and either move it to its own resource or fix the typo.

How do I enable versioning on an S3 bucket in Terraform?

Add an aws_s3_bucket_versioning resource pointing at the bucket id, with versioning_configuration { status = "Enabled" }.

Keep learning

Fix the Nginx 502 Bad GatewayDevOps projectRecover a Crashed Linux ServiceDevOps projectCorrect a Postgres Port MismatchDevOps projectDevOps roadmapStep by step to hiredDevOps interview questionsSTAR answersAll DevOps projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →