Hosting Static Website On S3 Using Terraform
Tags: terraform, s3, website
Published: 2024-06-27 21:49:09

In this blog we'll dive into deploying a static website on AWS S3 using Terrafrom!
Important things to note:
1. Automating S3 Bucket Creation: Terraform will handle creating the S3 bucket where your website files will reside.

2.Effortless Website Upload: We’ll configure Terraform to skip manual uploads by referencing your website files locally.

3.Public Access for All: Terraform will configure the S3 bucket policy to grant public read access, ensuring anyone can access your website.

How it is working by using Terraform?
Terraform is an infrastructure as code (IaC) tool used to define and manage cloud resources means we don't need to specify anything using console just we specify what are the resources we are going to use. Terraform will offers pre-built configurations for the various services.Terraform script that automates the entire deployment process, saving you time and ensuring a secure and accessible website.

**Step 1: Setup the Terraform
Create a terraform.tf file to set up the terraform and provider.**

```
terraform {
  required_version = "1.7.4"
  required_providers {
    aws = {
        source = "hashicorp/aws"
        version = "5.40.0"
    }
  }
}

#Provider
provider "aws" {
  profile = "default"
  region = "ap-south-1"
}

```

In this code version is "1.7.4",you can mention your Terraform version.
Terraform block defines its configuration and required_providers section defines external provider.
A crucial element within provider "aws" block is the
[profile = "default"]setting. This tells Terraform to use the default profile configured in your AWS credentials.Region section tells us which region we are going to create the S3 bucket.

**Step 2: Configuration for S3 bucket
Create a bucket.tf file to store the terraform configuration related to the S3 bucket.**

```
# Create S3 Bucket
resource "aws_s3_bucket" "terraform-demo-43234" {
  bucket = "terraform-demo-43234"
}

# Upload file to S3
resource "aws_s3_object" "terraform_index" {
  bucket = aws_s3_bucket.terraform-demo-43234.id
  key = "index.html"
  source = "index.html"
  content_type = "text/html"
  etag = filemd5("index.html")
}

# S3 Web hosting
resource "aws_s3_bucket_website_configuration" "terraform_hosting" {
  bucket = aws_s3_bucket.terraform-demo-43234.id

  index_document {
    suffix = "index.html"
  }
}
```

Resource “aws_s3_bucket” “terraform-demo-43234” block creates a new S3 bucket named “terraform-demo-43234”. (Error:if you got a error like bucket already exist please mention any other unique name for the bucket)
Resource “aws_s3_object” “terraform_index” block upload a 
**index.html ** to the S3 bucket.It defines the bucket in the form "aws_s3_bucket.bucket_name.id".Source property tells Terraform where to find the "index.html" file on your local machine.
content_type tells the content format.The etag property plays a crucial role in ensuring data integrity during file uploads, particularly in Terraform with S3 buckets.
Resource “aws_s3_bucket_website_configuration” “terraform_hosting”) block configures the S3 bucket for website hosting.

**Step 3: Configuration for bucket Policy
Create a ‘policy.tf’ file to store the terraform configuration related to the bucket policy for public access.**

```
# S3 public access
resource "aws_s3_bucket_public_access_block" "terraform-demo" {
    bucket = aws_s3_bucket.terraform-demo-43234.id
  block_public_acls = false
  block_public_policy = false
}

# S3 public Read policy
resource "aws_s3_bucket_policy" "open_access" {
  bucket = aws_s3_bucket.terraform-demo-43234.id

  policy = jsonencode({
    Version = "2012-10-17"
    Id      = "Public_access"
    Statement = [
      {
        Sid = "IPAllow"
        Effect = "Allow"
        Principal = "*"
        Action = ["s3:GetObject"]
        Resource = "${aws_s3_bucket.terraform-demo-43234.arn}/*"
      },
    ]
  })
  depends_on = [ aws_s3_bucket_public_access_block.terraform-demo ]
}
```

This block temporarily disables S3’s default Block Public Access settings for this specific bucket. 
bucket = aws_s3_bucket.terraform-demo-43234.id: References the S3 bucket we created earlier.block_public_acls = false: Disables blocking of public access control lists (ACLs).block_public_policy = false: Disables blocking of public bucket policies.
policy = jsonencode({ ... }): Specifies the actual policy document in JSON format.

**Step 4: Configuration for Output variable
Create an ‘output.tf’ to print out the URL to access the website.**

```
# Website URL
output "website_url" {
  value = "http://${aws_s3_bucket.terraform-demo-43234.bucket}.s3-website.${aws_s3_bucket.terraform-demo-43234.region}.amazonaws.com"
}
```
Once you completed all this process.Open the command prompt or terminal & navigate to the folder where the terraform file is located.

**Step 5: Initialize Terraform**

```
terraform init
```
It downloads and installs any required provider plugins based on your configuration like hashicorp/aws provider.

**Step 6: Terraform Validate**

```
terraform validate
```
It performs a static analysis of your Terraform configuration files and validates the overall syntax of your Terraform code.

**Step 7: Terraform Plan**

```
terraform plan
```
It is used for reviewing the intended changes to your infrastructure before actually applying them.

**Step 8: Terraform Apply**

```
terraform apply

```
The Terraform apply command in Terraform is the one that actually executes the actions outlined in the plan generated by the Terraform plan. 

If it runs successfully then open the AWS console to verify the S3 bucket is created and to check the file is upload in the S3 bucket.
At last the output(url) will display in cmd prompt.Copy and paste the url in the google to see the uploaded file.

**Step 9: Destroy**

```
terraform destroy
```
The terraform destroy command in Terraform is used for deleting the s3 bucket and its objects.