Nowadays, hosting a static website is fairly easy, thanks to AWS S3 and infrastructure-as-code tools like Terraform. In this post, I will walk you through the entire process of building a static React application and hosting it on AWS S3 while managing our infrastructure with Terraform.
Prerequisites
Make sure you have the following set up:
- Node.js and npm: To create and build React applications.
- AWS Account: To host your static website in AWS S3.
- Terraform: For infrastructure management.
- AWS Cli: To interact with AWS resources.
Step 1: Build Static Application With React
First we create our react application using create react app.
npx create-react-app my-static-site
cd my-static-site
Once your application is ready, run it locally with
npm start
When your application is ready , build your static files:
npm run build
This command will create a build directory in your React project that will contain your static files.
Step 2: Set up Terraform
Lets set up our Terraform configuration to create s3 bucket and host our React static application.
Create a main.tf(by convention we call it main.tf you could name it anything you like) in your project directory.
provider "aws" {
region = "us-east-1" // any region you want your aws configured to
access_key = "your-aws-access-key" //if aws cli is configured then you dont need this
secret_key = "your-aws-secret-key" //if aws cli is configured then you dont need this
}
run this command in your console, this command will initialize the working directory and download required plugins.
terraform init
Now include the following commands in your main.tf:
for creating a S3 bucket.
resource "aws_s3_bucket" "example" {
bucket = "your-unique-s3-bucket-name"
}
Unblock your S3 bucket to allow public access. This is necessary for the next step, where we will create a bucket policy:
resource "aws_s3_bucket_public_access_block" "example" {
bucket = aws_s3_bucket.example.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
We now utilize the aws_iam_policy_document data source, which allows us to create IAM JSON policies. Notably, in the resources section, we specify both the bucket itself and "/*" to encompass all objects within that bucket. This distinction is important because our actions include both s3:ListBucket and s3:GetObject. The s3:GetObject action applies to individual objects, while the s3:ListBucket action pertains to the entire S3 bucket.
data "aws_iam_policy_document" "example" {
statement{
principals {
type = "AWS"
identifiers = ["*"]
}
effect = "Allow"
actions = [
"s3:GetObject",
"s3:ListBucket"
]
resources = [
aws_s3_bucket.example.arn ,
"${aws_s3_bucket.example.arn}/*"
]
}
}
Next, we create our bucket policy, utilizing the JSON policy generated by the aws_iam_policy_document data source from above step.
resource "aws_s3_bucket_policy" "example" {
bucket = aws_s3_bucket.example.id
policy = data.aws_iam_policy_document.example.json
}
Now above commands in your main.tf run this command in console, this will generate an execution plan and show you the changes that this script will bring about.
terraform plan
Now run
terraform apply
type yes to create the architecture
Now, we will upload the react static application that we created above to our AWS s3 bucket(run npm run build command before running below command).
aws s3 sync build s3://your-bucket-name
Once your file is uploaded, go to your main.tf and add these block
resource "aws_s3_bucket_website_configuration" "example" {
bucket = aws_s3_bucket.example.id
index_document {
suffix = "index.html"
}
}
This code will enable your bucket for static website hosting. If everything is set up correctly, you will see a link in the static website section under the permissions of your bucket.
It will look something like this
http://my-static-site-bucket.s3-website-us-east-1.amazonaws.com
Top comments (0)