Servers, vpcs, nics. Managing these resources in either a development or production environment can get tedious, repetitive, and exhausting.
Terraform is an Infrastructure-as-code tool used to manage, specify, and control various resources on various environments- cloud and whathaveyou.
Very briefly, we'll look at how to create and manage AWS s3 buckets all using Terraform.
NB: If you're not already familiar with AWS and s3 buckets, I advise getting some foundational knowledge on those. It's important to know how something works before considering automating it.
If you want me to put something together as regards that, let me know in the comments
With that out of the way, let's get to it!
Create a standard s3 bucket
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1" # Specify your region
}
# Create s3 bucket
resource "aws_s3_bucket" "testbucket" {
bucket = "my-new-bucket"
}
For more details on creating s3 buckets check the Documentation
Creating an s3 bucket is one thing. Making it available to the public (if necessary) is another thing. The rest of this article will be helpful to people trying to make their bucket or the objects in it public.
Making your bucket accessible
# Bucket ownership controls
resource "aws_s3_bucket_ownership_controls" "buck-owner" {
bucket = aws_s3_bucket.testbucket.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}
# Disable bucket default security
resource "aws_s3_bucket_public_access_block" "public-block" {
bucket = aws_s3_bucket.testbucket.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
resource "aws_s3_bucket_acl" "buk-acl" {
depends_on = [
aws_s3_bucket_ownership_controls.buck-owner,
aws_s3_bucket_public_access_block.public-block,
]
bucket = aws_s3_bucket.testbucket.id
acl = "public-read"
}
# Enable read access
resource "aws_s3_bucket_policy" "allow-public-access" {
bucket = aws_s3_bucket.testbucket.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = "*"
Action = [
"s3:GetObject",
"s3:PutObject"
]
Resource = [
"${aws_s3_bucket.store-ket.arn}/*"
]
}
]
})
}
Each stage of this section is highly important. To learn more about these configurations, refer to some of these resources:
Some additional configurations you can add to your s3 bucket include versioning & server-side encryption
Versioning
resource "aws_s3_bucket_versioning" "enable-versioning" {
bucket = aws_s3_bucket.testbucket.id
versioning_configuration {
status = "Enabled"
}
}
To read more: Documentation
Server-side encryption
There are different methods to enable server-side encryption but for simplicity's sake, we'll stick to one
resource "aws_s3_bucket_server_side_encryption_configuration" "encrypt-ket" {
bucket = aws_s3_bucket.testbucket.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
We've come to the end of this short tutorial. But as a bonus, in case you're wondering if you can upload files to the bucket directly from your code. Yes, you can!
Upload HTML file
resource "aws_s3_object" "upload" {
key = "index.html"
bucket = aws_s3_bucket.testbucket.id
source = "buk-list/index.html"
acl = "public-read"
server_side_encryption = "AES256"
content_type = "text/html"
}
Make sure the source
points to the location of the file you want to upload. I advise creating a folder in your project directory so the source looks like this ./folder/index.html
Thanks for joining me on this one. I hope you found this helpful. Leave your questions for me in the comments and I'll be sure to help out however I can!
Top comments (3)
Thanks for going through my article! If you have any questions or grey areas, be sure to leave a question for me here in the comments ;)
How do you upload files, let's say images to the s3 bucket directly from code.
Nice article btw.
Hi! Thanks for the review.
You can use
resource "aws_s3_object" "upload"
to upload content to your s3 bucketFor instance you have an image stored in the root of your project in maybe a folder called
image-folder
The
content_type
attribute would depend on the type of image you want to upload. For more MIME types, you can check out this linkYou're welcome!