Subscribe To Our NewsLetter
Share This Post:
Deploying a static React app efficiently requires a reliable and scalable hosting solution. AWS offers a powerful combination of services—S3 for storing static assets and CloudFront for fast, global content delivery. By leveraging Terraform, you can automate the setup process, ensuring consistency and ease of management.
In this guide, we'll walk you through the steps to set up an AWS CloudFront distribution and an S3 bucket for your React app, helping you optimize performance and user experience.
How To Set Up AWS CloudFront And An S3 Bucket Using Terraform
To set up AWS CloudFront and an S3 bucket for your static React app using Terraform, follow these essential steps:
Create an S3 Bucket
Set up an S3 bucket to store your static assets, including HTML, CSS, JavaScript, and images.
Upload Your React App
Sync the build directory of your React app with the S3 bucket to ensure your app files are correctly hosted.
Create a CloudFront Distribution
Configure AWS CloudFront to serve content from your S3 bucket, optimizing delivery speed and performance for your users.
Terraform Resources And Configuration
1. S3 Bucket Creation
Resource: aws_s3_bucket.element-dev
Purpose: Create an S3 bucket for the static website.
Configuration: Bucket Name: Set using the variable var.s3_bucketname.
Tags:
- Name: Labelled as elemare_website.
- Environment: Set as Dev to indicate the development environment.
# Create an S3 bucket
resource "aws_s3_bucket" "elemare-dev" {
bucket = var.s3_bucketname
tags = {
Name = "elemare_wbesite"
Environment = "Dev"
}
}
2. S3 Bucket Ownership Controls
Resource: aws_s3_bucket_ownership_controls.elemare-site
Purpose: Ensures that the bucket owner manages the bucket ownership.
Configuration
Rule: Sets object_ownership to BucketOwnerPreferred to grant ownership of new objects to the bucket owner, regardless of the object creator.
# Set ownership controls for the bucket
resource "aws_s3_bucket_ownership_controls" "elemare-site" {
bucket = aws_s3_bucket.elemare-dev.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}
3. S3 Bucket ACL (Access Control List)
Resource: aws_s3_bucket_acl.element-acl
Purpose: Configures the ACL of the S3 bucket.
Dependencies: This resource depends on the successful application of aws_s3_bucket_ownership_controls.elemare-site
Configuration:
ACL: Set to private, restricting access to the bucket.
# Set access control list (ACL) for the bucket
resource "aws_s3_bucket_acl" "elemare-acl" {
depends_on = [ aws_s3_bucket_ownership_controls.elemare-site ]
bucket = aws_s3_bucket.elemare-dev.id
acl = "private"
}
Static Website Hosting Configuration
Resource: aws_s3_bucket_website_configuration.elemare-web-config.
Purpose: Configures the S3 bucket to host a static website.
Configuration:
Index Document: Specifies index.html as the default page for the website.
Error Document: Specifies error.html as the page displayed in case of an error.
# Configure the bucket for static website hosting
resource "aws_s3_bucket_website_configuration" "elemare-web-config" {
bucket = aws_s3_bucket.elemare-dev.id
# Set the default page
index_document {
suffix = "index.html"
}
# Set the error page
error_document {
key = "error.html"
}
}
Terraform configuration for setting up an AWS CloudFront distribution to serve content from an S3 bucket named element-dev. The CloudFront distribution is configured for optimized content delivery with secure access to the S3 bucket.
1. Local Variables
Purpose: Defines local variables used in the Terraform configuration.
Configuration
s3_origin_id: A unique identifier for the S3 origin in the CloudFront distribution.
# Identifier for the S3 originlocals { s3_origin_id = "elemareS3origin"}
2. CloudFront Distribution
Resource: aws_cloudfront_distribution.s3_distribution
Purpose: We’re setting up a CloudFront distribution to make sure your content is delivered quickly and securely from the S3 bucket to your users.
Configuration:
domain_name: This points directly to the S3 bucket’s regional domain name.
origin_id: We’ll use the s3_origin_id local variable to keep everything organized.
s3_origin_config: We’ll configure the origin access identity (OAI) to ensure that only CloudFront can access the S3 bucket, adding an extra layer of security.
Cache Behavior
allowed_methods: We’re allowing GET, HEAD, and OPTIONS methods, covering the basics for content delivery.
cached_methods: We’ll cache GET and HEAD requests to speed up load times.
Forwarded_values:
query_string: Enabled, so any query strings are passed along to the origin.
cookies: All cookies are forwarded to the origin, maintaining session integrity.
function_association: We’ll associate a CloudFront function to manage how viewer requests are handled.
viewer_protocol_policy: All HTTP requests will be redirected to HTTPS, keeping everything secure.
TTL Settings:
min_ttl, default_ttl, max_ttl: All set to 0, ensuring the most up-to-date content is delivered.
Compression: Enabled, reducing file sizes for faster delivery and a better user experience.
Viewer Certificate: We’re using the default CloudFront SSL certificate for HTTPS, ensuring secure communication.
Price Class: We’re going with PriceClass_All, which includes all edge locations globally, so your content reaches users wherever they are.
Restrictions:
geo_restriction: No geographical restrictions are applied, meaning your content is accessible to everyone, everywhere.
Additional Settings:
http_version: We’re supporting HTTP/2 and HTTP/3 for faster performance and more efficient connections.
Web ACL: This setup doesn’t include a Web ACL, keeping things simple (no web_acl_id configured).
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = aws_s3_bucket.elemare-dev.bucket_regional_domain_name
origin_id = local.s3_origin_id
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.oai.cloudfront_access_identity_path
}
}
enabled = true
is_ipv6_enabled = true
comment = "CloudFront distribution for elemare S3 bucket"
default_root_object = "index.html"
default_cache_behavior {
allowed_methods = [ "GET", "HEAD" , "OPTIONS" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = local.s3_origin_id forwarded_values {
query_string = true
cookies {
forward = "all"
}
}
function_association {
event_type = "viewer-request"
function_arn = aws_cloudfront_function.dev.arn
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 0
max_ttl = 0
compress = true
}
tags = {
Environment = "development"
}
# Include all edge locations
price_class = "PriceClass_All"
# No geographical restrictions
restrictions {
geo_restriction {
restriction_type = "none"
}
}# Use the default CloudFront certificate
viewer_certificate {
cloudfront_default_certificate = true
}# Web ACL ID for additional security (Disabled)
web_acl_id = "" http_version = "http2and3"
}
The terraform.tfvars file is like the control center for your Terraform setup. It’s where you set the values for all the variables that your Terraform configuration relies on. This file is essential because it helps you manage environment-specific settings and credentials in one place, keeping everything organized and secure.
Understanding And Defining Variables In Terraform
1. AWS Credentials
Variable: aws_credentials
Purpose: Stores the path or name of the AWS credentials file used for authentication when deploying resources.
2. Cognito Pool Name
Variable: pool_name
Purpose: Specifies the name of the Amazon Cognito user pool to be created or used. This is essential for user authentication and management.
3. Cognito Client Name
Variable: client_name
Purpose: Defines the name of the Cognito app client, which interacts with the user pool for authentication purposes.
4. Cognito User Pool ID
Variable: USER_POOL_ID
Purpose: Contains the ID of an existing Cognito user pool, used to manage and authenticate users.
5. AWS Region
Variable: REGION
Purpose: Specifies the AWS region where the resources will be deployed. This is crucial for ensuring resources are created in the desired geographical location.
6. Cognito Client ID
Variable: CLIENT_ID
Purpose: Stores the ID of the Cognito app client, which is used by applications to interact with the Cognito user pool.
aws_credentials = ""
pool_name = ""
client_name = ""
USER_POOL_ID = ""
REGION = ""
CLIENT_ID = ""
This document outlines the variables defined in the Terraform configuration file. These variables allow for the dynamic configuration of your Terraform scripts, making it easy to manage and reuse across different environments.
# Define a variable for AWS credentials file path
variable "aws_credentials" {
description = "AWS credentials file"
type = string
sensitive = true # Mark as sensitive to prevent showing in logs
}# Define a variable for AWS region
variable "aws_region" {
description = "AWS region variable"
type = string
sensitive = true
default = "us-east-1" # Set default region
}# Define a variable for S3 bucket name
variable "s3_bucketname" {
description = "Name of S3 bucket"
type = string
default = "elemare-dev-site" # Set default bucket name
}variable "pool_name" {
description = "The name of the Cognito user pool"
type = string
}variable "client_name" {
description = "The name of the Cognito user pool client"
type = string
} variable "USER_POOL_ID" {
description = "Value of the MY_ENV_VAR environment variable"
type = string
}variable "REGION" {
description = "Value of the MY_ENV_VAR environment variable"
type = string
}variable "CLIENT_ID" {
description = "Value of the MY_ENV_VAR environment variable"
type = string
}
Let’s Wrap It Up!
Setting up AWS CloudFront and an S3 bucket using Terraform not only simplifies the deployment of your static React app but also ensures a highly efficient and scalable infrastructure. By following the steps outlined in this guide, you’ve automated the process of configuring and managing these AWS services, reducing the potential for errors and saving valuable time. With CloudFront handling content delivery and S3 securely storing your app’s assets, your users can enjoy a fast, reliable experience no matter where they are. As you continue to refine your Terraform scripts, you’ll find even more opportunities to enhance your cloud infrastructure, making your deployments smoother and more robust.
At LN Webworks, we’re committed to your success. Our expert team is here to provide personalized assistance. Contact us today to schedule your free consultation!
Share This Post:
Talk With Certified Experts Of LN Webworks!
Related Articles
August 16, 2024
How To Set Up WordPress With Docker
July 9, 2024
How To Create Custom Git Commands With Aliases
June 24, 2024