… to S3 and CloudFront with Terraform

Terraforming CloudFront

Now that we have a bucket, we can create the CloudFront distribution to ensure it can handle production-level traffic. For now, we're going to be using the default CloudFront TLS certificate, and not adding any CNAMEs -- that will come in a later section.

With Terraform, this is again only a single resource, however it has an absurd amount of options. Complexity is unavoidable when dealing with AWS, unfortunately; not even Terraform can solve that.

resource "aws_cloudfront_distribution" "my-website" {
  enabled         = true
  is_ipv6_enabled = true

  origin {
    domain_name = "${aws_s3_bucket.my-website.bucket_domain_name}"
    origin_id   = "myWebsiteS3"

  restrictions {
    geo_restriction {
      restriction_type = "none"

  default_cache_behavior {
    target_origin_id = "myWebsiteS3"

    allowed_methods = ["GET", "HEAD"]
    cached_methods  = ["GET", "HEAD"]

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 7200
    max_ttl                = 86400

  viewer_certificate {
    cloudfront_default_certificate = true

There's a lot to take in, so let's break it down piece-by-piece.


Now let's create the distribution. All we need to do now is run the same command as before:

$ terraform apply

Terraform will complete quickly, but CloudFront's distribution creation is async and can take almost an hour to create a distribution, sometimes. Be patient; perhaps grab a coffee. Best to log into the AWS Console, go to CloudFront, and wait until your new distribution goes from "In Progress" to "Deployed".