-
Notifications
You must be signed in to change notification settings - Fork 937
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2439 from JunaidAnsari80/jdansariaws-feature-s3-c…
…loudfront-sap Jdansariaws feature s3 cloudfront sap
- Loading branch information
Showing
6 changed files
with
348 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Amazon S3 hosted website served by a CloudFront distribution restricted by CloudFront Origin Access Control (OAC) | ||
This project serves as a demonstration of how to leverage Amazon CloudFront and Amazon Simple Storage Service (S3) to host and deliver a static website efficiently and securely. | ||
|
||
Amazon S3 is an object storage service that provides a highly scalable, durable, and cost-effective way to store and retrieve data, including website files such as HTML, CSS, JavaScript, and other static assets. In this project, S3 is utilized as the origin, which means it hosts the static website content. | ||
|
||
Amazon CloudFront, on the other hand, is a content delivery network (CDN) service that caches and distributes the website content from multiple edge locations around the world. By integrating CloudFront with the S3-hosted website, the project showcases how to leverage CloudFront's caching and content distribution capabilities to improve website performance, reduce latency, and enhance the end-user experience. | ||
|
||
![Demo Project Solution Architecture Diagram](diagram.PNG) | ||
|
||
- Learn more about these patterns at https://serverlessland.com/patterns. | ||
- To learn more about submitting a pattern, read the [publishing guidelines page](https://github.com/aws-samples/serverless-patterns/blob/main/PUBLISHING.md). | ||
|
||
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. | ||
|
||
## Requirements | ||
|
||
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. | ||
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured | ||
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) | ||
* [Terraform Installed](https://www.terraform.io/) | ||
|
||
## Deployment Instructions | ||
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository: | ||
``` | ||
git clone https://github.com/aws-samples/serverless-patterns | ||
``` | ||
2. Change directory to the pattern directory: | ||
``` | ||
cd s3-cloudfront-spa | ||
``` | ||
3. Initilize terraform | ||
``` | ||
Run terraform init | ||
``` | ||
4. Create terrform plan | ||
``` | ||
Run terraform plan | ||
``` | ||
5. Create AWS resources | ||
``` | ||
Run terraform apply | ||
``` | ||
During the prompts: | ||
* Enter yes | ||
6. Copy your front end assests | ||
## Testing | ||
1. Go to AWS Console. | ||
2. Go to your hosting Amazon S3 bucket. | ||
3. Upload your front end content or Copy index.html from "s3-cloudfront-spa" pattern "test" folder for testing. | ||
4. Go to AWS Cloudfront. | ||
5. Go to Distributions. | ||
5. Select your distribution domain and browse it. e.g ***********.cloudfront.net/index.html. | ||
### Removing the resources | ||
1. To destory deployed resources | ||
``` | ||
Run terraform destroy | ||
``` | ||
---- | ||
Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
---- | ||
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
{ | ||
"title": "AWS CloudFront and Amazon S3 for Single Page Application Hosting", | ||
"description": "This project demonstrates hosting a Single-Page App using AWS CloudFront & S3, where CloudFront serves the SPA from an S3 bucket for static hosting.", | ||
"language": "Terraform", | ||
"level": "200", | ||
"framework": "Terraform", | ||
"introBox": { | ||
"headline": "How it works", | ||
"text": [ | ||
"Here's how hosting a static website using Amazon CloudFront and Amazon S3 works:", | ||
"- An Amazon S3 bucket is created and configured for static website hosting", | ||
"- A CloudFront web distribution is created, with the S3 bucket configured as the origin server. CloudFront acts as a content delivery network (CDN) for the website", | ||
"- When a user requests a file from the website, CloudFront first checks if the file is cached at one of its edge locations (data centers) closest to the user. If the file is cached, CloudFront serves it directly to the user.", | ||
"- If the requested file is not cached at an edge location, CloudFront fetches the file from the S3 bucket origin. It then caches the file at the edge location for subsequent requests", | ||
"- For subsequent requests, CloudFront serves the cached files from the nearest edge location to the user, providing low latency and fast content delivery.", | ||
"- When website files are updated in the S3 bucket, CloudFront automatically detects the changes and retrieves the updated files from the origin. Cache invalidation can also be manually triggered to force CloudFront to fetch the latest versions." | ||
] | ||
}, | ||
"gitHub": { | ||
"template": { | ||
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/s3-cloudfront-spa", | ||
"templateURL": "serverless-patterns/s3-cloudfront-spa", | ||
"projectFolder": "s3-cloudfront-spa", | ||
"templateFile": "template.tf" | ||
} | ||
}, | ||
"resources": { | ||
"bullets": [ | ||
{ | ||
"text": "Amazon S3 bucket to host the website", | ||
"link": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html" | ||
}, | ||
{ | ||
"text": "Amazon CloudFront uses Amazon S3 as the origin server to host and serve static websites.", | ||
"link": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started-cloudfront-overview.html" | ||
} | ||
] | ||
}, | ||
"deploy": { | ||
"text": [ | ||
"<code>terraform init</code>", | ||
"<code>terraform plan</code>", | ||
"<code>terraform apply</code>" | ||
] | ||
}, | ||
"testing": { | ||
"text": [ | ||
"Refer to README" | ||
] | ||
}, | ||
"cleanup": { | ||
"text": [ | ||
"<code>terraform destroy</code>" | ||
] | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Junaid Ansari", | ||
"image": "https://media.licdn.com/dms/image/v2/C4E03AQEekYWyjMINfg/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1659715539214?e=1728518400&v=beta&t=HVpwkCvJ_QdUYDW2YXbCabZDcWKWv3VpTBKmnCS5uVg", | ||
"bio": "Cloud Application Architect at AWS.", | ||
"linkedin": "junaid-ansari-2734a912" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
{ | ||
"title": "Amazon CloudFront and Amazon S3 for Single Page Application Hosting", | ||
"description": "This project hosts a Single-Page App using Amazon CloudFront & S3, where CloudFront serves the SPA from an S3 bucket for static hosting.", | ||
"language": "YAML", | ||
"level": "200", | ||
"framework": "Terraform", | ||
"introBox": { | ||
"headline": "How it works", | ||
"text": [ | ||
"Here's how hosting a static website using Amazon CloudFront and Amazon S3 works:", | ||
"- An Amazon S3 bucket is created and configured for static website hosting", | ||
"- A CloudFront web distribution is created, with the S3 bucket configured as the origin server. CloudFront acts as a content delivery network (CDN) for the website", | ||
"- When a user requests a file from the website, CloudFront first checks if the file is cached at one of its edge locations (data centers) closest to the user. If the file is cached, CloudFront serves it directly to the user.", | ||
"- If the requested file is not cached at an edge location, CloudFront fetches the file from the S3 bucket origin. It then caches the file at the edge location for subsequent requests", | ||
"- For subsequent requests, CloudFront serves the cached files from the nearest edge location to the user, providing low latency and fast content delivery.", | ||
"- When website files are updated in the S3 bucket, CloudFront automatically detects the changes and retrieves the updated files from the origin. Cache invalidation can also be manually triggered to force CloudFront to fetch the latest versions." | ||
] | ||
}, | ||
"gitHub": { | ||
"template": { | ||
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/s3-cloudfront-spa", | ||
"templateURL": "serverless-patterns/s3-cloudfront-spa", | ||
"projectFolder": "s3-cloudfront-spa", | ||
"templateFile": "template.tf" | ||
} | ||
}, | ||
"resources": { | ||
"bullets": [ | ||
{ | ||
"text": "Amazon S3 bucket to host the website", | ||
"link": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html" | ||
}, | ||
{ | ||
"text": "Amazon CloudFront uses Amazon S3 as the origin server to host and serve static websites.", | ||
"link": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started-cloudfront-overview.html" | ||
} | ||
] | ||
}, | ||
"deploy": { | ||
"text": [ | ||
"<code>terraform init</code>", | ||
"<code>terraform plan</code>", | ||
"<code>terraform apply</code>" | ||
] | ||
}, | ||
"testing": { | ||
"text": [ | ||
"Refer to README" | ||
] | ||
}, | ||
"cleanup": { | ||
"text": [ | ||
"<code>terraform destroy</code>" | ||
] | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Junaid Ansari", | ||
"image": "https://media.licdn.com/dms/image/v2/C4E03AQEekYWyjMINfg/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1659715539214?e=1728518400&v=beta&t=HVpwkCvJ_QdUYDW2YXbCabZDcWKWv3VpTBKmnCS5uVg", | ||
"bio": "Cloud Application Architect at AWS.", | ||
"linkedin": "junaid-ansari-2734a912" | ||
} | ||
], | ||
"patternArch": { | ||
"icon1": { | ||
"x": 20, | ||
"y": 50, | ||
"service": "cloudfront-edge", | ||
"label": "Amazon CloudFront distribution" | ||
}, | ||
"icon2": { | ||
"x": 80, | ||
"y": 50, | ||
"service": "s3", | ||
"label": "Amazon S3 bucket" | ||
}, | ||
"line1": { | ||
"from": "icon1", | ||
"to": "icon2", | ||
"label": "" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
terraform { | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = "~> 5.61" | ||
} | ||
} | ||
} | ||
|
||
provider "aws" { | ||
region = "eu-west-2" | ||
profile = "default" | ||
} | ||
|
||
data "aws_region" "current" { | ||
} | ||
|
||
data "aws_caller_identity" "current" { | ||
} | ||
|
||
resource "aws_cloudfront_origin_access_control" "spa_aoc" { | ||
name = "spa_aoc" | ||
description = "spa_aoc" | ||
origin_access_control_origin_type = "s3" | ||
signing_behavior = "always" | ||
signing_protocol = "sigv4" | ||
} | ||
|
||
resource "aws_cloudfront_distribution" "cf_distribution" { | ||
enabled = true | ||
default_root_object = "index.html" | ||
is_ipv6_enabled = true | ||
price_class = "PriceClass_All" | ||
|
||
restrictions { | ||
geo_restriction { | ||
restriction_type = "none" | ||
} | ||
} | ||
origin { | ||
domain_name = aws_s3_bucket.host.bucket_regional_domain_name | ||
origin_id = "spa_portal" | ||
origin_access_control_id = aws_cloudfront_origin_access_control.spa_aoc.id | ||
} | ||
|
||
default_cache_behavior { | ||
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] | ||
cached_methods = ["GET", "HEAD"] | ||
target_origin_id = "spa_portal" | ||
|
||
forwarded_values { | ||
query_string = false | ||
|
||
cookies { | ||
forward = "none" | ||
} | ||
} | ||
|
||
viewer_protocol_policy = "redirect-to-https" | ||
min_ttl = 0 | ||
default_ttl = 300 | ||
max_ttl = 1200 | ||
} | ||
|
||
viewer_certificate { | ||
cloudfront_default_certificate = true | ||
minimum_protocol_version = "TLSv1.2_2021" | ||
} | ||
} | ||
|
||
locals { | ||
s3_origin_id = "host-store" | ||
} | ||
|
||
resource "aws_s3_bucket" "host" { | ||
bucket = local.s3_origin_id | ||
} | ||
|
||
resource "aws_s3_bucket_public_access_block" "bucket_access_block" { | ||
bucket = aws_s3_bucket.host.id | ||
block_public_acls = true | ||
block_public_policy = true | ||
ignore_public_acls = true | ||
restrict_public_buckets = true | ||
} | ||
|
||
resource "aws_s3_bucket_ownership_controls" "host_ownership" { | ||
bucket = aws_s3_bucket.host.id | ||
rule { | ||
object_ownership = "BucketOwnerPreferred" | ||
} | ||
} | ||
|
||
resource "aws_s3_bucket_acl" "host_acl" { | ||
depends_on = [aws_s3_bucket_ownership_controls.host_ownership] | ||
|
||
bucket = aws_s3_bucket.host.id | ||
acl = "private" | ||
} | ||
|
||
|
||
resource "aws_s3_bucket_website_configuration" "website_configuration" { | ||
bucket = aws_s3_bucket.host.id | ||
|
||
index_document { | ||
suffix = "index.html" | ||
} | ||
|
||
error_document { | ||
key = "error.html" | ||
} | ||
} | ||
|
||
resource "aws_s3_bucket_policy" "host_policy" { | ||
bucket = aws_s3_bucket.host.id | ||
|
||
policy = jsonencode({ | ||
Statement = [ | ||
{ | ||
Action = "s3:GetObject" | ||
Effect = "Allow" | ||
Resource = "arn:aws:s3:::${aws_s3_bucket.host.bucket}/*" | ||
Principal = { | ||
Service = "cloudfront.amazonaws.com" | ||
}, | ||
Condition = { | ||
StringEquals = { | ||
"AWS:SourceArn" = "arn:aws:cloudfront::${data.aws_caller_identity.current.account_id}:distribution/${aws_cloudfront_distribution.cf_distribution.id}" | ||
} | ||
} | ||
} | ||
] | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<p>Welcome to SPA</p> |