So you want to create a static website and host it in AWS. You want SSL and a basic contact form protected by Google reCaptcha. Well, to make this all happen you need to configure the following AWS services: Route53, S3, CloudFront, AWS Certificate Manager, SNS, Lambda, API Gateway, and IAM. That's a bit overwhelming, just for a simple static website!
This project solves all of this by providing an AWS sam template that sets up all the necessary infrastructure for serverless web hosting on AWS, including a contact form protected by Google reCaptcha. There is also a GitHub actions workflow to setup continuous delivery. The stack deploys the following:
- S3 bucket to host the static web files
- CloudFront distribution so you can add an SSL/TLS certificate
- SSL/TLS certificate
- Route53 record in your hosted zone
- API gateway to broker the
- Lambda funtion to process contact form
- SNS Topic to send email from the contact form
- Edge lamda for better SEO
- IAM user with permissions to deploy from github actions
The website this stack will deploy is based on Start Bootstrap - Freelancer The cloudformation template uses the deploy-to-s3 app from the serverless application repository.
- AWS account
- Hosted zone in Route53
- GitHub account
- Setup reCaptcha v2 here: https://www.google.com/recaptcha/admin. Note both the client and server side site keys. See the recaptcha documentation for more details.
- AWS sam cli
- Setup a named profile for sam cli. Let's assume your named profile is called
sidney
. - Node.js v18
- Python v3.11
There are 2 resources that need to be deployed in us-east-1 region; 1) SSL/TLS Certificate, and 2) edge lambda for SEO. Everything else can be deployed in your region of choice. Therefore, if you want to deploy to any AWS region other than us-east-1, you need to deploy 2 stacks; one stack for the resources that need to be in us-east-1 and another stack in your chosen region. If your region of choice is us-east-1 you need only deploy one stack, and that's a wee bit simpler.
- run
./prepare.sh
to pull in the vendor code for the website - run
export AWS_PROFILE=sidney
- run
sam build
- run
sam deploy --guided --capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND
Leave the EdgeLambdaArn
and SSLCertificateArn
blank.
- run
./prepare.sh
to pull in the vendor code for the website - run
export AWS_PROFILE=sidney
- run
sam build -t template-east.yaml
- run
sam deploy -t template-east.yaml --guided
- Note the output values of
SSLCertificateArn
andEdgeLambdaArn
- run
sam build --use-container
- run
sam deploy --guided --capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND
, using the output values of the us-east-1 stack as parameters for this stack. - Refer to the Stack Parameters section below.
Parameter | Description |
---|---|
Stack Name | Name of the stack |
AWS Region | Region where stack will be deployed |
DomainName | Domain name of hosted zone |
HostedZoneId | HostedZoneId found in Route53 |
Subject | Subject of the email sent from web form |
ToEmailAddress | Email address where web form will send emails |
ReCaptchaClientSecret | Get this from reCaptcha |
ReCaptchaServerSecret | Get this from reCaptcha |
EdgeLambdaArn | Not needed if deploying 1 stack to us-east-1 |
SSLCertificateArn | Not needed if deploying 1 stack to us-east-1 |
Confirm changes before deploy [y/N]: | N |
Allow SAM CLI IAM role creation [Y/n]: | Y |
Disable rollback [y/N]: | N |
ContactUsFunction may not have authorization defined, Is this okay? [y/N]: | N, Don't worry, we have reCaptcha |
Save arguments to configuration file [Y/n]: | Y |
SAM configuration file [samconfig.toml]: | Y |
SAM configuration environment [default]: | Y |
Before you setup github actions, go grab the index.html from your S3 bucket and check it into git. During the deploy of the cloudformation template, the API gateway URL and google reCaptcha client key values were put into that file.
Look at the output of the cloudformation stack to find the IAMUser
. Then setup AWS programatic credentials for that user. AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, should be set as encrypted secrets on your github repo.
Look at the output of the cloudformation stack to find the CloudFrontDistributionId
and S3Bucket
. Edit .github/workflows/main.yml
with those values. Region too.
- run
cd web
- run
npm install
- run
gulp
- run
gulp dev
gulp
the default task that builds everythinggulp dev
browserSync opens the project in your default browser and live reloads when changes are madegulp css
compiles SCSS files into CSS and minifies the compiled CSSgulp js
minifies the themes JS filegulp vendor
copies dependencies from node_modules to the vendor directory
NOTE: Delete the web/node_modules directory or the deploy will fail due to too much crap.
When you delete the stack it will probably fail to delete. Don't worry. You need to do two things after the stack fails to delete:
- Empty the S3 bucket
- Wait for the edge lambda to undeploy now that your cloudfront distribution had been deleted. Maybe a couple of hours.
After that, try to delete the stack again. It should delete just fine.
The cloudFrontS3IndexHtml
lambda adds .html
to URLs that don't end in: .html,.css,.css.map,.js,.json,.gif,.jpg,.jpeg,.png,.svg,.ico,.woff,.ttf,.txt,.xml
. If you are getting 403 errors in your browser while navigating the site, you may need to edit cloudFrontS3IndexHtml/index.js to allow the file types you are seeing errors with.