Creating S3 Buckets with Terraform in AWS

Infrastructure as Code has become the standard way to provision AWS S3 storage. Using Terraform to create an S3 bucket shifts the work from manual clicks in the AWS Management Console to declarative configuration that is repeatable, version-controlled and auditable. This article covers the practical path from prerequisites to advanced module features using only the patterns documented in the reference material.

The Terraform AWS provider treats an S3 bucket as a resource of type aws_s3_bucket. Inside the resource block the bucket field defines the name of the bucket. In the examples reviewed the bucket is named terraform-experiments and the guidance notes that while the bucket field is optional, it is considered a best practice to give resources descriptive names to help with organization and management. Before applying configuration the Terraform module must be initialized by running terraform init in the terminal. This command downloads the necessary provider plugins and sets up the backend for storing the state file.

Terraform is not limited to a specific cloud; rather, it uses provider plugins to facilitate infrastructure management across all major cloud providers. Additionally, there are community plugins available for other popular services, such as Cloudflare.

To see a preview of the resource that will be created, you can run the terraform plan command in the terminal. This will show you what changes Terraform will make to your infrastructure based on the configuration in your main.tf file.

Prerequisites and Core Benefits

Before diving into the hands-on process, ensure you have these necessary prerequisites in place:

  • AWS Account: An active AWS account to access and utilize AWS services, including S3

Additional prerequisites implied by the workflows include AWS CLI for managing credentials and verifying resources, and Terraform installed locally.

The benefits of creating an AWS S3 bucket using Terraform are documented as follows:

  • 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.

Highlights summarized from the reference material:

  • Infrastructure as Code: Terraform allows you to define S3 buckets declaratively, ensuring consistency and version control.
  • Automation: Using Terraform eliminates manual clicking in the AWS Console, reducing human error.
  • State Management: Terraform tracks the state of your bucket, making updates and deletions safer and more predictable.
  • Advanced Features: You can easily layer complex configurations like Versioning, Logging, and IAM policies directly within your Terraform code.

When working with applications hosted on the cloud, you’ll most likely need a data storage solution. Some of the storage options that can be set up in the cloud include object storage, block storage, and file storage. While they vary depending on the provider, they typically offer scalability, flexibility, and cost-effectiveness and can be easily set up with an IaC tool such as Terraform.

Basic Terraform Configuration

To get started, specify their desired properties, such as name, ACLs, and storage class, within a Terraform configuration file. Terraform will take care of creating the buckets in your AWS account.

A minimal declaration for a bucket with tags is shown in the reference:

hcl resource "aws_s3_bucket" "my_bucket" { bucket = "my-unique-bucket-name" tags = { Name = "MyS3Bucket" Environment = "Production" } }

Using the resource block, we've defined a new resource of type aws_s3_bucket. This tells Terraform that we want to create a new S3 bucket in our AWS account.

Inside the aws_s3_bucket block, we've specified the name of our bucket using the bucket field.

The typical workflow steps are:

  • Write the configuration file defining name, ACLs, and storage class.
  • Run terraform init to download provider plugins.
  • Run terraform plan to preview changes.
  • Run terraform apply and confirm with yes.
  • 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.

Congratulations! You've successfully created an AWS S3 bucket using Terraform. But this is just the beginning. Let's explore some additional configurations and best practices.

Advanced Configurations

Versioning
Enabling versioning for your S3 bucket helps you manage and retain multiple versions of an object. To enable versioning, modify your main.tf file:

```hcl
resource "awss3bucket" "my_bucket" {
bucket = "my-unique-bucket-name"
tags = {
Name = "MyS3Bucket"
Environment = "Production"
}
}

resource "awss3bucketversioning" "versioningexample" {
bucket = awss3bucket.mybucket.id
versioning
configuration {
status = "Enabled"
}
}
```

Logging
You can configure S3 bucket logging to record all requests made to your bucket.

By leveraging Terraform's capabilities, you can automate the provisioning of S3 buckets, streamline access control configurations, and optimize storage costs through lifecycle management.

We also examined common use cases such as uploading objects, provisioning ACLs, and configuring lifecycle rules.

Frequently Asked Questions

  • How do I create an S3 bucket using Terraform?
    To create an S3 bucket using Terraform, define a resource of type aws_s3_bucket in your main.tf file and specify the name of the bucket using the bucket field.
  • How can I upload a file to an S3 bucket using Terraform?
    To upload a file to an S3 bucket, create a new aws_s3_object resource in your Terraform configuration, specifying the target bucket, key, and source file path.
  • How do I configure Access Control Lists (ACLs) for an S3 bucket using Terraform?
    To configure ACLs, use the aws_s3_bucket_acl resource. Specify the desired ACL settings, such as making a file public or private, by modifying the acl field.
  • How do I implement lifecycle rules for an S3 bucket using Terraform?
    Use the aws_s3_bucket_lifecycle_configuration resource to define lifecycle rules. Specify actions like transitioning objects to another storage class or expiring objects after a certain number of days.

Terraform AWS Modules for S3 Buckets

The terraform-aws-modules/terraform-aws-s3-bucket repository provides a Terraform module which creates S3 bucket on AWS with all (or almost all) features provided by Terraform AWS provider.

Supported features include:

  • 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

Example usage for a private bucket with versioning:

hcl 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 } }

Example for a logs bucket with ELB log delivery policy:

hcl 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 }

A variant with both ELB and ALB/NLB log delivery:

hcl 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 }

The module also supports WAF log delivery:

hcl module "s3_bucket_for_waf_logs" { source = "terraform-aws-modules/s3-bucket/aws" bucket =

The module approach allows reusable, version-controlled definitions and eliminates repetition across environments.

Feature Category Examples from Module
Hosting static web-site hosting
Security server-side encryption, object locking, Account-level Public Access Block
Access Control CORS, ACL, object ownership control
Logging & Delivery access logging, ELB log delivery bucket policy, ALB/NLB log delivery bucket policy, WAF log delivery bucket policy
Data Management versioning, lifecycle rules, Cross-Region Replication
Modern S3 Types S3 Directory Bucket, S3 Table Bucket, S3 Vectors

Hands-On Project Perspective

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.

Conclusion

Creating an S3 bucket using Terraform moves bucket provisioning from manual console actions to declarative, auditable code. The basic aws_s3_bucket resource covers naming, tagging and storage class, while the terraform-aws-modules/s3-bucket/aws module adds comprehensive coverage for versioning, server-side encryption, object locking, CORS, lifecycle rules, access logging, replication, and specialized log delivery policies for ELB, ALB/NLB and WAF.

State management ensures Terraform understands drift and can safely update or destroy resources, and version control of .tf files supports collaboration and rollbacks. Prerequisites remain minimal: an active AWS account and valid credentials. The documented workflow of terraform init, terraform plan, terraform apply and console verification provides a repeatable path from code to running bucket.

As organizations adopt more S3 types such as S3 Directory Bucket, S3 Table Bucket and S3 Vectors, the module-based approach will continue to reduce boilerplate while preserving the benefits of repeatability, reusability and automated configuration of advanced features.

Sources

  1. Terraform AWS S3 Bucket Module
  2. How to create AWS S3 bucket using Terraform
  3. Using S3 with Terraform
  4. Terraform S3 Bucket Project

Related Posts