Creating an S3 bucket with Terraform converts ad-hoc console clicks into repeatable, version-controlled infrastructure. The process starts with a provider definition, moves through init, plan and apply, and ends with verification in the AWS Management Console. Using the community terraform-aws-modules/s3-bucket module gives access to almost all features provided by the Terraform AWS provider, while manual resource blocks offer explicit control over versioning, logging and tagging.
Prerequisites and Initial Setup
Before any Terraform code runs, an active AWS account to access and utilize AWS services, including S3 is required. Credentials are configured with the AWS CLI.
aws configure
Provider definition establishes the cloud target. A provider file named provider.tf stores information about the cloud provider, version, and region for the s3 bucket.
terraform {
required_providers{
aws={
source = "hashicorp/aws"
version = "4.33.0"
}
}
}
provider "aws"{
region = "us-east-1"
}
The Terraform init command prepares the working directory for use with Terraform. It initialises the backend, any child module installation and any plugin installation.
terraform init
This is the first command we are going to run. It initializes the working directory and downloads the AWS provider.
Terraform Workflow for S3 Bucket Creation
The standard sequence of terraform init, plan, and apply is central to automating the creation and configuration of cloud resources.
- $ terraform init
- $ terraform plan
- $ terraform apply
The second command would be to run a Terraform plan. This command shows the bucket, public access block, and ownership controls that Terraform is about to create.
After initialization, run the following command to preview the changes Terraform will make to your infrastructure:
terraform plan
Review the output to ensure that Terraform will create the resources as expected. If everything looks good, you can proceed to the next step.
To create the S3 bucket, execute the following command:
terraform apply
Terraform will prompt you to confirm the execution of the plan. Type yes and press Enter. Terraform will then create the S3 bucket and output information about the resources created.
Step 6: Verify the S3 Bucket
Visit the AWS Management Console and navigate to the S3 service. You should see the newly created bucket with the name you specified in your Terraform configuration.
After the apply completes, you should see a new S3 bucket named spacelift-test1-s3 in your AWS account.
Benefits of this workflow include:
- Repeatable: Terraform configurations ensure your S3 buckets will be created consistently every time the Terraform apply command is run.
- Version-controlled: Terraform configurations allow you to track changes made to S3 buckets over time, providing an effective means for rolling back to previous versions of your configuration if necessary.
- Reusable: Terraform modules can be created to store common S3 bucket configurations. This saves both time and effort, as you won't need to write the same configuration repeatedly.
- State Management: Terraform maintains a state file that keeps track of the current state of the infrastructure, including AWS S3 buckets. This state file enables Terraform to understand the differences between the declared configuration and the actual infrastructure, facilitating updates and modifications.
Module Features and Supported Configurations
The Terraform module which creates S3 bucket on AWS with all or almost all features provided by Terraform AWS provider supports extensive S3 bucket configurations.
| Feature Category | Supported Capabilities |
|---|---|
| Hosting and Access | static web-site hosting |
| Logging and Access | access logging |
| Data Protection | versioning |
| Security and Controls | CORS |
| Lifecycle | lifecycle rules |
| Encryption | server-side encryption |
| Object Management | object locking |
| Replication | Cross-Region Replication (CRR) |
| Log Delivery Policies | ELB log delivery bucket policy |
| Log Delivery Policies | ALB/NLB log delivery bucket policy |
| Log Delivery Policies | WAF log delivery bucket policy |
| Public Access | Account-level Public Access Block |
| New S3 Types | S3 Directory Bucket |
| New S3 Types | S3 Table Bucket |
| New S3 Types | S3 Vectors |
S3 stands for Simple Storage Service. S3 buckets are cloud storage services by Amazon Web Service. It is used to store objects, It consists of data in any format like documents, images, videos, and application code. These are highly scalable.
Common Module Examples
Using the module reduces boilerplate for common patterns.
Basic private bucket with versioning and object ownership control:
module "s3_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
bucket = "my-s3-bucket"
acl = "private"
control_object_ownership = true
object_ownership = "ObjectWriter"
versioning = {
enabled = true
}
}
Log delivery bucket with force destroy enabled:
module "s3_bucket_for_logs" {
source = "terraform-aws-modules/s3-bucket/aws"
bucket = "my-s3-bucket-for-logs"
acl = "log-delivery-write"
force_destroy = true
control_object_ownership = true
object_ownership = "ObjectWriter"
attach_elb_log_delivery_policy = true
}
Log delivery bucket with both ELB and ALB/NLB policies:
module "s3_bucket_for_logs" {
source = "terraform-aws-modules/s3-bucket/aws"
bucket = "my-s3-bucket-for-logs"
force_destroy = true
control_object_ownership = true
object_ownership = "ObjectWriter"
attach_elb_log_delivery_policy = true
attach_lb_log_delivery_policy = true
}
WAF logs bucket example begins with source and bucket assignment:
module "s3_bucket_for_waf_logs" {
source = "terraform-aws-modules/s3-bucket/aws"
bucket =
The module supports:
- static web-site hosting
- access logging
- versioning
- CORS
- lifecycle rules
- server-side encryption
- object locking
- Cross-Region Replication (CRR)
- ELB log delivery bucket policy
- ALB/NLB log delivery bucket policy
- WAF log delivery bucket policy
- Account-level Public Access Block
- S3 Directory Bucket
- S3 Table Bucket
- S3 Vectors
Manual Resource Configuration
A minimal main.tf for a single bucket:
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-unique-bucket-name"
tags = {
Name = "MyS3Bucket"
Environment = "Production"
}
}
In this example, we have defined an AWS provider specifying the region and a basic S3 bucket resource. The configuration uses "us-east-1" as the preferred AWS region and "my-unique-bucket-name" as the name for the S3 bucket.
The bucket name should be unique, here the bucket name is "my-s3-test-bucket02"
Advanced Configurations
Versioning
Enabling versioning for your S3 bucket helps you manage and retain multiple versions of an object.
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-unique-bucket-name"
tags = {
Name = "MyS3Bucket"
Environment = "Production"
}
}
resource "aws_s3_bucket_versioning" "versioning_example" {
bucket = aws_s3_bucket.my_bucket.id
versioning_configuration {
status = "Enabled"
}
}
Logging
You can configure S3 bucket logging to record all requests made to your bucket
Uploading objects after creation:
In the previous step, we created an S3 bucket with Terraform. In this step, we will upload files to that bucket using the awss3object resource.
If you are working from older examples, you may still see awss3bucket_object, but that resource has been deprecated
Real-World Project Experience
Project Link: View Project
Author: Abdulrahman Abdulkadir
Email: [email protected]
In this project, I will demonstrate how to create S3 buckets using Terraform. The goal is to automate the provisioning of AWS S3 storage by writing Infrastructure as Code, ensuring consistency, repeatability, and easy management of bucket configurations such as versioning, access policies, and lifecycle rules.
Services I used were AWS S3 for storage and the AWS CLI for managing credentials and verifying resources. Key concepts I learnt include infrastructure as code, Terraform providers, resource blocks, state management, the sequence of terraform init, plan, and apply, as well as automating the creation and configuration of cloud resources, applying access controls, and uploading objects to S3 buckets in a repeatable and consistent way.
This project took me approximately 3 to 4 hours to complete. The most challenging part was correctly configuring AWS credentials and ensuring Terraform had the proper access to create and manage resources. It was most rewarding to see the S3 bucket and objects successfully deployed and managed automatically through Terraform, demonstrating the power of infrastructure as code.
I did this project today to gain hands-on experience with Terraform and understand how to automate the creation and management of AWS resources like S3 buckets
Best Practices and Verification
After apply, visit the AWS Management Console and navigate to the S3 service. You should see the newly created bucket with the name you specified in your Terraform configuration.
State management ensures differences between declared configuration and actual infrastructure are understood, facilitating updates and modifications.
Repeatable configurations ensure buckets are created consistently every time the Terraform apply command is run.
Version-controlled configurations allow tracking changes made to S3 buckets over time.
Reusable modules store common S3 bucket configurations.
Conclusion
Creating S3 buckets with Terraform moves S3 provisioning from manual console work to code-driven, auditable infrastructure. The Terraform AWS provider module offers a comprehensive set of features from static website hosting to S3 Vectors, with built-in support for log delivery policies and object ownership controls. Manual resource definitions remain useful for explicit versioning and tagging patterns.
The init, plan, apply cycle provides a safe preview and confirmation path, while state management tracks actual infrastructure. Practical experience shows the main friction points are credential configuration and proper access permissions, with rewards visible once buckets and objects deploy automatically.
Together, the module approach and manual resource patterns give teams both speed and precision for S3 automation across development and production environments.