Most of us know how AWS is growing and with it's growth, It is making developer's lives easier to develop and deploy live applications. Most of us definitely have a use case where we want to deploy a static website for product marketing or maybe for personal profile showcase or maybe because of client's requirement
AWS S3 provides a feature to host static websites (by static it means content is never dynamic) on S3 buckets and gives you an endpoint through which you can access the website. However, we need to consider the fact that we cannot make the site secure(with ssl, which is certainly a corner case because making a static site secure doesn't make sense to me at least) directly but indirectly it is definitely possible. This is where CloudFront comes into the picture and turns the table around for some developers because configuring the cloud front adds a bit of complexity.
Additionally, What if you have a case where you need to host multiple website. You need to go through the entire process multiple times.
If you are facing any issues let me know in the comments section.
Regards,
Quicktrixx👻
AWS S3 provides a feature to host static websites (by static it means content is never dynamic) on S3 buckets and gives you an endpoint through which you can access the website. However, we need to consider the fact that we cannot make the site secure(with ssl, which is certainly a corner case because making a static site secure doesn't make sense to me at least) directly but indirectly it is definitely possible. This is where CloudFront comes into the picture and turns the table around for some developers because configuring the cloud front adds a bit of complexity.
Additionally, What if you have a case where you need to host multiple website. You need to go through the entire process multiple times.
- Making an S3 bucket
- Uploading files to the bucket
- Configuring the static website
- Configuring cloud front
- Create a Domain name and map it to the CloudFront domain and create a record set. fuhhh 😓 -->You can skip this step if you don't want your site to be secured on SSL.
If you are going through the same feeling let's automate it with a tool called "Terraform".
main.tf
provider "aws"{
region = "us-east-1"
}
resource "aws_s3_bucket" "website_bucket" {
bucket = "${var.name_domain}.${var.root_domain}"
acl = "private"
website {
index_document = "index.html"
error_document = "error.html"
}
tags = {
Name = "${var.Customer}"
Environment = "${var.Environment}"
}
region = "us-east-1"
}
data "aws_s3_bucket" "get_s3_zone" {
bucket = "${var.name_domain}.${var.root_domain}"
depends_on = ["aws_s3_bucket.website_bucket"]
}
data "aws_route53_zone" "getZone" {
count = "${var.hostedZone == "yes" ? 1 : 0}"
name = "${var.root_domain}"
private_zone = false
}
resource "aws_route53_zone" "website_zone" {
count = "${var.hostedZone == "yes" ? 0 : 1}"
name = "${var.root_domain}"
tags = {
Name = "${var.Customer}"
Environment = "${var.Environment}"
}
}
data "aws_acm_certificate" "fetch_certificate_arn" {
domain = "${var.certificate}"
statuses = ["ISSUED"]
most_recent = true
}
resource "aws_cloudfront_distribution" "website_cloudfront" {
origin {
domain_name = "${aws_s3_bucket.website_bucket.website_endpoint}"
origin_id = "${var.Customer}_S3_origin"
custom_origin_config {
origin_protocol_policy = "http-only"
https_port = 443
http_port = 80
origin_ssl_protocols = ["TLSv1", "SSLv3"]
}
}
enabled = true
aliases = ["${var.name_domain}.${var.root_domain}"]
price_class = "PriceClass_200"
retain_on_delete = true
default_cache_behavior {
allowed_methods = [ "GET", "HEAD"]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "${var.Customer}_S3_origin"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
viewer_certificate {
acm_certificate_arn = "${data.aws_acm_certificate.fetch_certificate_arn.arn}"
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.1_2016"
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
depends_on = ["aws_s3_bucket.website_bucket"]
}
resource "aws_route53_record" "www"{
zone_id = "${var.hostedZone == "no" ? join("", aws_route53_zone.website_zone.*.zone_id) : join ("",data.aws_route53_zone.getZone.*.zone_id)}"
name = "${var.name_domain}.${var.root_domain}"
type = "A"
alias {
name = "${aws_cloudfront_distribution.website_cloudfront.domain_name}"
zone_id = "${aws_cloudfront_distribution.website_cloudfront.hosted_zone_id}"
evaluate_target_health = "false"
}
depends_on = [aws_route53_zone.website_zone]
}
output "website_endpoint" {
value = aws_s3_bucket.website_bucket.website_endpoint
}
inputs.tf
variable "hostedZone"{description = "'yes': if 'PUBLIC' hosted zone for the root domain is present , else 'no' NOTE: Make sure the hosted zone is public and not private. If the hosted zone is present but is private enter 'no'"}variable "root_domain"{description = "Root domain of the website eg. If Website is xyz.example.com, root_domain is example.com"}variable "name_domain"{description = "If Website is xyz.example.com, name_domain is xyz"}variable "Customer"{description = "Name of the customer"}variable "Environment"{description = "Customer's Environment"}variable "certificate"{description = "Enter the certificate to use eg. if you have the root domain as example.com enter '*.example.com' to use wildcard cert else enter whole domain of the website to use a custom cert"}
terraform.tfvars
Customer = "Quicktrixx"Environment = "prod"root_domain = "" #example: quicktrixx.com or quicktrixx.qaname_domain = "" #example:example, So if your whole domain is hello.example.com enter 'hello' in the name domain and 'example.com' in root domain
If you are facing any issues let me know in the comments section.
Regards,
Quicktrixx👻