DEV Community

Cover image for Terraform and s3 buckets?!
Fife Oluwabunmi
Fife Oluwabunmi

Posted on

Terraform and s3 buckets?!

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"

}

Enter fullscreen mode Exit fullscreen mode

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}/*"
        ]
      }
    ]
  })
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
thecolossus profile image
Fife Oluwabunmi

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 ;)

Collapse
 
codej profile image
Emmanuel Taiwo

How do you upload files, let's say images to the s3 bucket directly from code.
Nice article btw.

Collapse
 
thecolossus profile image
Fife Oluwabunmi

Hi! Thanks for the review.

You can use resource "aws_s3_object" "upload" to upload content to your s3 bucket

For instance you have an image stored in the root of your project in maybe a folder called image-folder

resource "aws_s3_object" "upload" {
  key                    = "my_image"
  bucket                 = aws_s3_bucket.testbucket.id
  source                 = "image-folder/my_image.png"
  acl                    = "public-read"
  server_side_encryption = "AES256"
  content_type           = "image/jpeg"
}
Enter fullscreen mode Exit fullscreen mode

The content_type attribute would depend on the type of image you want to upload. For more MIME types, you can check out this link

You're welcome!