- Published on
Hosting static website with AWS Cloudfront
- Authors
- Name
- Krzysztof Olszewski
How to host a static website with AWS services
I would like to show you step by step, how to use AWS services, to create website installation with automated manner.
https://github.com/deltacodepl/aws-cloudfront-acme-ovh
I'm using OVH as domain registar, so we have to configure ovh provider for Terraform. To get API login required keys, we have to specify, which part of the API we will be using, in our case its domain/* path. For better security we can restrict access to our API, to specific IP's.
AWS Certificate Manager
Project we want to host should be available under subdomain, so we put neccessary variables into work: domain_name = "example.com"
& cert_domain_name = "promo.example.com"
and generate certifiacate using ACM.
It's important to know, that w can create our certs only within us-east-1 AZ
resource "aws_acm_certificate" "website-cert" {
domain_name = var.domain_name
subject_alternative_names = [ var.cert_domain_name]
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
Because we have more than one domain, we have to create validation records in ovh service.
resource "ovh_domain_zone_record" "ovh_acm_record" {
for_each = {
for dvo in aws_acm_certificate.website-cert.domain_validation_options : dvo.domain_name => {
# name = trim(dvo.resource_record_name, ".")
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
zone = var.domain_name
# name of the record
subdomain = each.value.name
fieldtype = each.value.type
ttl = "60"
# value of the record
target = each.value.record
}
So we are using DNS validation method, and Terraform create for us two neccessary records, which can be seen at OVH web cloud settings panel.
Cloudfront
Our S3 bucket will be private, and only our cloudfront distrbution intstance will have access to it, in oposite to basic public accessible website buckets.
To setup this functionality we have to use Origin Access Identity:
resource "aws_cloudfront_origin_access_identity" "origin_access_identity" {
comment = "access-identity-${var.cert_domain_name}"
}
and we can define our cloudfront s3_distribution:
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
# Origin domain
# domain_name = aws_s3_bucket.s3_front_website_bucket.bucket_regional_domain_name
# FIXME: terraform return same result as for bucket_domain_name
domain_name = "${var.cert_domain_name}.s3.us-east-1.amazonaws.com"
origin_id = var.cert_domain_name
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.origin_access_identity.cloudfront_access_identity_path
}
}
# for CNAME setting
aliases = [var.cert_domain_name]
enabled = true
is_ipv6_enabled = true
comment = var.cert_domain_name
default_root_object = "index.html"
...
as you can see, there is an unsolved problem with Terraform behaviour, that wont let us configure properly domain name, so wh have to hardcode it domain_name = "${var.cert_domain_name}.s3.us-east-1.amazonaws.com"
.
Finishing
After running our playbook we can access website under generated by AWS *.cloudfront.net
domain name. We can simple create CNAME record in ovh dns zone settings and get fully working static website with ovh hosted custom domain.