Skip to main content

Command Palette

Search for a command to run...

AWS S3 Bucket creation using Terraform

Published
5 min read

If you are following this series, make sure to check the previous blog: here.

Video for reference: Piyush Sachdeva.


Today, we’ll provision an S3 bucket using Terraform and walk through how Terraform manages state changes.

High-Level Overview

We will write a simple Terraform file for S3 bucket creation inside AWS.

We will write a new Terraform file inside our local system. Then configure the aws-cli with an IAM user with required authentication.

Some of the prerequisites:

  1. Terraform is installed on your device.

  2. Aws-cli installed on your system. Also configuration of IAM.

    1. Go to the IAM service in aws console.

    2. Create a new IAM user with S3 bucket authorisation.

    3. Then configure the access key and credentials in your local system using:

       aws configure
      
  3. If everything is done, open a new folder and create a new Terraform file.

S3 bucket creation

Refer to: Terraform S3 Bucket.

Open the folder that you created. Create a new Terraform file and name it whatever you want; naming the Terraform file doesn’t matter. Edit the file in VS Code, nano, Geany, Vim, or any preferred IDE you use.

Copy the code given below:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0" # locking the provider version to 6.x
    }
  }
}

provider "aws" {
  region = "us-east-1" # the service will run on us-east-1
}

Then, referring to the document, we can copy the required code for a private bucket from the official document.

resource "aws_s3_bucket" "example" {
  bucket = "my-tf-test-bucket"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}

I will change the bucker name to any string that will be unique. Something like your-name-numbers. Then, following the operations.

Updated Terraform code:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0" # locking the provider version to 6.x
    }
  }
}

provider "aws" {
  region = "us-east-1" # the service will run on us-east-1
}

# create a s3 bucket
resource "aws_s3_bucket" "first_s3_bucket" {
  bucket = "amal-s3-bucket-terraform30days" # name of the bucket, unique one

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}

terraform init

For initialising the current root as a Terraform folder. Output similar to:

   Code   git:(main)  terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 6.0"...
- Installing hashicorp/aws v6.22.1...
- Installed hashicorp/aws v6.22.1 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary

terraform plan

This will plan the resources for us. After planning, we will get an output like this:

   Code   git:(main)  terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_s3_bucket.first_s3_bucket will be created
  + resource "aws_s3_bucket" "first_s3_bucket" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      + arn                         = (known after apply)
      + bucket                      = "amal-s3-bucket"
      + bucket_domain_name          = (known after apply)
      + bucket_prefix               = (known after apply)
      + bucket_region               = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + policy                      = (known after apply)
      + region                      = "us-east-1"
      + request_payer               = (known after apply)
      + tags                        = {
          + "Environment" = "Dev"
          + "Name"        = "My bucket"
        }
      + tags_all                    = {
          + "Environment" = "Dev"
          + "Name"        = "My bucket"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + cors_rule (known after apply)

      + grant (known after apply)

      + lifecycle_rule (known after apply)

      + logging (known after apply)

      + object_lock_configuration (known after apply)

      + replication_configuration (known after apply)

      + server_side_encryption_configuration (known after apply)

      + versioning (known after apply)

      + website (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

terraform apply

Apply basically creates whatever we planned based on the state file. If the bucket exists, you will get a response like this:

aws_s3_bucket.first_s3_bucket: Creating...
╷
│ Error: creating S3 Bucket (amal-s3-bucket): operation error S3: CreateBucket, https response error StatusCode: 409, RequestID: MF081FQ5FYB4S39Q, HostID: nvl6xoklnwXyaU0SRG5TWOyLGUQNjs5xZrnkIK91a89fM02z1DJ7RHmbFpL96Y2vV8D8JjeugTc=, BucketAlreadyExists: 
│ 
│   with aws_s3_bucket.first_s3_bucket,
│   on main.tf line 15, in resource "aws_s3_bucket" "first_s3_bucket":
│   15: resource "aws_s3_bucket" "first_s3_bucket" {

So I renamed it to a unique name it got created successfully.

If we go into the bucket, we can also view the tags we give to that S3 bucket:

If I change the state of the file like:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

# create a s3 bucket
resource "aws_s3_bucket" "first_s3_bucket" {
  bucket = "amal-s3-bucket-terraform30days"

  tags = {
    Name        = "My bucket 2.0" # changed from "My bucket"
    Environment = "Dev"
  }
}

Applying the plan again.

I will get a response like:

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

If I go back into the AWS console, I can see the changes reflected.

terraform destory

This will delete the state file, and this also makes it reflect on my AWS account.

aws_s3_bucket.first_s3_bucket: Destroying... [id=amal-s3-bucket-terraform30days]
aws_s3_bucket.first_s3_bucket: Destruction complete after 2s

Back into our AWS account, we can see that the bucket has been deleted.

That’s it.


Arigato!

More from this blog

Code Companions

32 posts