Skip to content

Demonstrating how to host a simple website using Terraform

License

Notifications You must be signed in to change notification settings

JoeHutchinson/HelloWebsite

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hello Website

This project demonstrates how to host a simple website using Terraform.

It's a simple example creating a VPC with public and private subnets, an internet gateway, and a load balancer to host a website on ECS Fargate.

Fargate vs Lambda is a often discussed topic, Fargate was chosen in this case under the assumtpion the website will see steady predictable load and that response times are important. Lambda is a better choice for sporadic traffic or where cold starts are not a concern.

API Gateway vs ALB, would use API Gateway if we were hosting using a Lambda function, and cared about caching request etc. For the purpose of this project ALB was chosen for it's simplicity.

VPC flow logs are in place, more for compliance and auditing than anything else.

VPC endpoints to ECS and ECR are in place, to ensure traffic doesn't leave the VPC when accessing these services.

Dependabot config in place to keep all the modules up to date. Pre-commit hooks in place to ensure code quality.

Installation

  1. Install and configure the required dependencies:
  1. Clone the repository:
git clone https://github.com/your-username/HelloWebsite.git
  1. Change into the project directory:
cd HelloWebsite

Usage

  1. Add your AWS access and secret keys to the ./variables/default.tfvars file:
access_key = "YOUR_ACCESS_KEY"
secret_key = "YOUR_SECRET_KEY"
  1. Deploy the website infrastructure in ascending order: e.g.
terraform -chdir=components\200-network\ init
terraform -chdir=components\200-network\ apply --var-file=.\..\variables\default.tfvars
terraform -chdir=components\300-app\ init
terraform -chdir=components\300-app\ apply --var-file=.\..\variables\default.tfvars
  1. Access the website by to the provided URL in the output service_address field of of the 300-app component. e.g.
curl ex-HelloWebsite-1825686964.eu-west-1.elb.amazonaws.com

Expected response:

StatusCode        : 200
StatusDescription : OK
Content           : {"message":"hello world!"}
RawContent        : HTTP/1.1 200 OK
                    Transfer-Encoding: chunked
                    Connection: keep-alive
                    Content-Type: application/json
                    Date: Mon, 10 Jun 2024 20:39:47 GMT

                    {"message":"hello world!"}
Forms             : {}
Headers           : {[Transfer-Encoding, chunked], [Connection, keep-alive], [Content-Type, application/json], [Date, Mon, 10 Jun 2024 20:39:47 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 26

Limitations / Future Improvements

There's many. But to list the main ones:

  1. Initialising the AWS provider with credentials is not the best idea, better to assume IAM role of the agent executing the Terraform commands
  2. Env tag should be based off the terraform workspace, as this project shouldn't have a CICD system I had to just have it passed in
  3. VPC should be using IPAM to avoid CIDR clash, in this example I only have one VPC so risk is limited, in production environment this would be required
  4. VPC should have infra and DB subnets, in this example I don't need a DB so I didn't create one, I also didn't require subnets without internet access
  5. ALB should have a WAF attached to it, to protect against common web attacks
  6. ALB should have a Route53 domain and SSL certificate attached to it, to allow for a custom domain
  7. If for a production system I'd build opinionated TF modules instead of using the AWS modules, this would allow for more control, improved readability and easier to maintain. I chose to use the AWS modules more out of curiosity to see how much they've improved in 4 years since I last used them, turns out not much, they try to cater to all use cases at the expense of readability/usability, better off creating your own.
  8. Outbound traffic proxied through security gateway to ensure no data exfiltration, specified via an AWS prefix list
  9. A CI/CD pipeline in place to deploy the infrastructure, this would allow for better testing and more frequent deployments
  10. A 400-monitoring component defining alerts and dashboards, to alert on any issues with the service
  11. A backup and restore system in place, to ensure data is not lost
  12. A disaster recovery plan in place, to ensure the system can be restored in the event of a disaster
  13. A security plan in place, to ensure the system is secure and compliant with industry standards

License

Apache 2 Licensed. See LICENSE for full details.

About

Demonstrating how to host a simple website using Terraform

Resources

License

Stars

Watchers

Forks

Packages

No packages published