Terraform Cloud Project Bootcamp with Andrew Brown - Creating an S3 bucket and bucket name using Terraform Providers
Tags: terraform, aws, s3, providers
Published: 2023-11-22 07:05:06

Hi guys , in this piece we will now start creating resources with Terraform. In this post, we will outline how to create a resource that creates a random value that becomes the S3 bucket name.

This article is part of my Terraform journey with [Terraform Bootcamp](https://www.youtube.com/watch?v=TXjzwiHtGqc&t=5852s) by Andrew Brown and Andrew Bayko, together with Chris Williams(I am also using his resources that he published [here](https://www.freecodecamp.org/news/terraform-certified-associate-003-study-notes/#preparation-materials) and the beloved Shala Warner. I am also using some other resources from [Aaron Brooks](https://www.youtube.com/@mastermnd) so that I can better explain new terms. And a special shout out to [Gwen Leigh](https://medium.com/@gwenleigh/terraform-cloud-project-bootcamp-with-andrew-brown-complete-learning-journal-3640cebc74b5) for such a helpful outline that I used as a guide to create this series so that the documentation is easy to read!

As I learn more about Terraform, feel free to follow [Andrew Brown on Youtube](https://www.youtube.com/@ExamProChannel) and see their free (and paid) content . I Now let's jump in. 

## Table of Contents
- [Install and use the AWS Terraform provider](#install-and-use-the-aws-terraform-provider)
- [Create a bucket name using the random resource string](#create-a-bucket-name-using-the-random-resource-string)
   * [Creating the `main.tf` file](#creating-the-maintf-file)
   * [1. Required providers blocks](#1-required-providers-blocks)
   * [2. Configure the credentials](#2-configure-the-credentials)
   * [3. The resource `random_string` ](#2-the-resource-random_string)
   * [4. The resource `aws_s3_bucket` ](#3-the-resource-aws_s3_bucket)
   * [5. Gives the output ](#4-gives-the-output)
- [Resources](#resources)

## Install and use the AWS Terraform provider
To refresh our memory about providers, they are Direct interfaces to APIs for providers. Find more info about them from [here]()

We will create an AWS S3 bucket using Terraform. S3 is an object storage service from AWS that allows us to store items, referred to as objects in containers known as buckets in AWS terminology.

The "random" provider allows the use of randomness within Terraform configurations. This is a logical provider, which means that it works entirely within Terraform's logic, and doesn't interact with any other services.

## Create a bucket name using the random resource string
### Creating the `main.tf` file
Create a `main.tf` file(a module) and add the code below:
```tf
terraform {
  required_providers {
    random = {
      source = "hashicorp/random"
      version = "3.5.1"
    }
    aws = {
      source = "hashicorp/aws"
      version = "5.19.0"
    }
  }
}

provider "aws" {
  # Configuration options
}

provider "random" {
  # Configuration options
}

#https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string
resource "random_string" "bucket_name" {
  lower = true
  upper = false
  length           = 32
  special          = false
}

#Terraform AWS S3 
#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket
resource "aws_s3_bucket" "example" {
  #bUCKET NAMING RULES
  #https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
  bucket = random_string.bucket_name.result
}

output "random_bucket_name" {
  value = random_string.bucket_name.result
}
```

### 1. Required providers blocks
In the required providers block, we need to add to use the aws provider as we will be creating a resource S3 in AWS and we also have to add an _aws provider block random_string_ to create a random string for the bucket name. 
`
terraform {
  required_providers {
    random = {
      source = "hashicorp/random"
      version = "3.5.1"
    }
    aws = {
      source = "hashicorp/aws"
      version = "5.26.0"
    }
  }
}
`

### 2. Configure the credentials
We will now configure the credentials for the AWS provider within the `main.tf` file. 

`
provider "aws" {
  AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
  AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  AWS_DEFAULT_REGION=us-west-2
}
`
 Afterwards we can set the credentials as environment variables in the terminal.

> **Make sure to delete them before committing the file to VCS and let the provider look like the code block above.**

### 3. The resource `random_string` 
We are following the S3 bucket naming convention i.e making sure all letters are lowercase, have no special characters and have 32 characters.

Generates a random permutation of alphanumeric characters and optionally special characters.

This resource does use a cryptographic random number generator.
`
resource "random_string" "bucket_name" {
  lower = true
  upper = false
  length           = 32
  special          = false
}
`

### 4. The resource `aws_s3_bucket` 
A resource that creates the S3 bucket with the bucket name as the output of the random-string resource above.
`
resource "aws_s3_bucket" "example" {
   bucket = random_string.bucket_name.result
}
`

### 5. The output 
Gives the random string which is the S3 bucket name.
`
output "random_bucket_name" {
  value = random_string.bucket_name.result
}
`

+ Now run `terraform init` and get the out put below. The command will create 2 files: a `.terraform file` and a `terraform.lock.hcl`. 
```
Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/random versions matching "3.5.1"...
- Installing hashicorp/random v3.5.1...
- Installed hashicorp/random v3.5.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.
```

> **Whenever we make a change to the main.tf file, we need to make sure that we always run terraform init to add the new providers/resources to state file.**

+ `terraform.lock.hcl` is a package lock file that locks in the current version of terraform that we are using. 

+ Then run `terraform plan` creates a changeset, which shows the infrastructure that IaC plans to change. It should appear as below. If no issues show up, then run terraform apply.

```tf

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:

  # random_string.bucket_name will be created
  + resource "random_string" "bucket_name" {
      + id          = (known after apply)
      + length      = 16
      + lower       = true
      + min_lower   = 0
      + min_numeric = 0
      + min_special = 0
      + min_upper   = 0
      + number      = true
      + numeric     = true
      + result      = (known after apply)
      + special     = false
      + upper       = true
    }

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

Changes to Outputs:
  + random_bucket_name = (known after apply)

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

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

+ Now run `terraform apply` and enter `Yes` when prompted. It generates a `terraform.tfstate` file. (o use `terraform apply --auto-approve`

+ Now run `terraform destroy --auto-approve` to remove resources.

## Resources
1. [S3 bucket providers](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket)
2.  [S3 BUCKET NAMING RULES](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html)
3. [Configuring env vars in AWS](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)