I am attempting to deploy a React application via Static S3 using AWS CDK. I have been at this for a few hours now, but cannot seem to pinpoint the issue. I included the script below, which has been a steady state of additions and subtractions in code to address various issues, the current of which is an access denied issue when trying to visit the site. The application runs just fine locally, but once available on S3, it cannot be viewed.
from aws_cdk import (
Stack, Tags, CfnOutput,
aws_iam as iam,
aws_s3 as s3,
aws_cloudfront as cloudfront,
aws_cloudfront_origins as cloudfront_origins,
aws_route53 as r53,
aws_route53_targets as route53_targets,
aws_certificatemanager as acm,
aws_s3_deployment as s3_deployment,
RemovalPolicy
)
from constructs import Construct
class CFS3StaticAppStack(Stack):
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
# S3 Bucket for hosting the website
site_bucket = s3.Bucket(self, "SiteBucket",
bucket_name="s3-static-app",
public_read_access=False,
website_index_document="index.html",
website_error_document="error.html",
removal_policy=RemovalPolicy.DESTROY,
block_public_access=s3.BlockPublicAccess.BLOCK_ALL
)
# CloudFront OAI
oai = cloudfront.OriginAccessIdentity(self, "OAI")
# Update the S3 bucket policy to allow access from CloudFront
site_bucket.add_to_resource_policy(iam.PolicyStatement(
actions=["s3:GetObject"],
resources=[site_bucket.bucket_arn + "/*"],
principals=[oai.grant_principal]
))
# Add CORS configuration
site_bucket.add_cors_rule(
allowed_methods=[s3.HttpMethods.GET],
allowed_origins=["*"],
allowed_headers=["*"]
)
# CloudFront distribution for the website
distribution = cloudfront.Distribution(self, "SiteDistribution",
default_behavior=cloudfront.BehaviorOptions(
origin=cloudfront_origins.S3Origin(site_bucket, origin_access_identity=oai),
viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS
),
default_root_object="index.html",
error_responses=[
cloudfront.ErrorResponse(
http_status=404, # Error code
response_page_path="/error.html",
response_http_status=404
)
]
)
# Deploy the React application to S3
s3_deployment.BucketDeployment(
self,
"ReactAppStaticWebsite",
sources=[s3_deployment.Source.asset("./client_react/dist")],
destination_bucket=site_bucket,
distribution=distribution,
distribution_paths=["/*"]
)
# Route53 alias record for the CloudFront distribution
zone = r53.HostedZone.from_lookup(self, "Zone", domain_name="mywebsite.com")
acm_cert = acm.Certificate.from_certificate_arn(
self,
"Cert",
"arn:aws:acm:region:account:certificate/your-certificate-id"
)
# A record
r53.ARecord(self, "SiteAliasRecord",
zone=zone,
target=r53.RecordTarget.from_alias(route53_targets.CloudFrontTarget(distribution)),
record_name="dev.mywebsite.com",
)
# Output CloudFront URL
CfnOutput(self, "DistributionDomainName", value=distribution.distribution_domain_name)
# Add tags to all resources in this stack
Tags.of(self).add("Project", "Blah")
Tags.of(self).add("Environment", "Blah")
Here is the error I see when I visit either the site on CloudFront or dev.mywebsite.com:
403 ERROR
The request could not be satisfied.
Bad request. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by cloudfront (CloudFront)
Request ID: xxxxxxxxxxxxxxxxxxxxx
2
Answers
Am I missing something? You have not allowed public access on the bucket? How than do you expect to access it publicly? Maybe that’s the issue.
Check if The certificate associate to Cloudfront have the good domain name?