This template deploys a secure, scalable, and high-performance static website using an S3 bucket for hosting and a CloudFront distribution for content delivery. The S3 bucket is private and accessible only via CloudFront using an Origin Access Identity (OAI).
This template provides the core infrastructure for hosting a static website on AWS. It includes:
- An S3 Bucket (private, not public) for static content, accessible only via CloudFront OAI.
- A CloudFront Distribution to cache and serve your content globally, providing low-latency access to your users.
- A CloudFront Origin Access Identity (OAI) to ensure that your S3 content is only accessible through CloudFront.
- CloudWatch Alarms for monitoring the health of the CloudFront distribution (e.g., 4xx and 5xx error rates).
The infrastructure code is located in the infra/ directory and is managed by Terraform. Example static content is in the app/ directory.
First, navigate to the infra directory:
cd infraThen, you can initialize and deploy the infrastructure:
-
Initialize Terraform:
terraform init
-
Plan the deployment: Review the
variables.tffile for available parameters. You must provide at leastbucket_nameanddistribution_name. To ensure the S3 bucket name is globally unique, a random suffix will be automatically appended to the name you provide.terraform plan -var="bucket_name=my-static-site" -var="distribution_name=my-static-site"
-
Apply the configuration: Confirm the plan to deploy your infrastructure. The final bucket name will be shown in the output.
terraform apply -var="bucket_name=my-static-site" -var="distribution_name=my-static-site"
After the infrastructure is deployed, you can upload your website's files to the S3 bucket. The full, unique name of the bucket is available in the Terraform output bucket_id.
You can use the AWS CLI to sync your app folder to the S3 bucket:
aws s3 sync ../app s3://$(terraform output -raw bucket_id)Once the files are uploaded, your website will be available at the distribution_domain_name provided in the Terraform outputs.
bucket_id: The unique S3 bucket namebucket_arn: The ARN of the S3 bucketdistribution_domain_name: The CloudFront URL for your siteorigin_access_identity_id: The CloudFront OAI IDorigin_access_identity_iam_arn: The OAI IAM ARN (used in the S3 bucket policy)
- The S3 bucket is not public. Only CloudFront (via the OAI) can access objects in the bucket.
- The S3 bucket policy is automatically managed by Terraform and grants
s3:GetObjectonly to the OAI.
- Access Denied via CloudFront?
- Make sure you uploaded your files to the correct S3 bucket (
bucket_idoutput). - Ensure the CloudFront distribution is fully deployed (status: Deployed).
- Wait a few minutes for propagation after changes.
- The S3 bucket policy must reference the OAI IAM ARN (managed automatically by this template).
- If you change the OAI or bucket, re-apply Terraform.
- Make sure you uploaded your files to the correct S3 bucket (
This template is maintained by Senora.dev.