Search code examples
amazon-s3amazon-cloudfrontterraform-provider-aws

I keep getting error when viewing my second S3 Origin via Cloudfront, why?


So I have two s3 origins, I used different HTML contents so I can differentiate the buckets. To achieve this, I specified an origin group in my Terraform config, one each for my two buckets. Lastly, I configured a path pattern each /primary* and secondary/* However, when I add the paths to my cloudfront domain name, I get access denied. Also, when I visit my cloudfront domain name, only the first bucket HTML content pops up. Why is all this happening? Below is my cloudfront terraform config:

locals {
  origin_id_map = {
    "s3_origin_id_1" = "S3_Origin_Primary"
    "s3_origin_id_2" = "S3_Origin_Secondary"
  }
}

resource "aws_cloudfront_distribution" "s3_distribution" {
  origin_group {
    origin_id = "Origin_Group_S3"

    failover_criteria {
      status_codes = [403, 404, 500, 502]
    }

    member {
      origin_id = local.origin_id_map.s3_origin_id_1
    }

    member {
      origin_id = local.origin_id_map.s3_origin_id_2
    }
  }

  origin {
    domain_name = aws_s3_bucket.Primary_Bucket.bucket_regional_domain_name
    origin_id   = local.origin_id_map.s3_origin_id_1

    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.Primary_OAI.cloudfront_access_identity_path
    }
  }

  origin {
    domain_name = aws_s3_bucket.Secondary_Bucket.bucket_domain_name
    origin_id   = local.origin_id_map.s3_origin_id_2

    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.Secondary_OAI.cloudfront_access_identity_path
    }
  }

  default_cache_behavior {
    allowed_methods  = ["OPTIONS", "GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "Origin_Group_S3"
    viewer_protocol_policy = "https-only"

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }
  }

  enabled             = true
  is_ipv6_enabled     = true
  comment             = "S3 Distribution"
  default_root_object = "index.html"

  # Cache behavior with precedence 0
  ordered_cache_behavior {
    path_pattern     = "/primary/*"
    allowed_methods  = ["GET", "HEAD", "OPTIONS"]
    cached_methods   = ["GET", "HEAD", "OPTIONS"]
    target_origin_id = local.origin_id_map.s3_origin_id_1
    viewer_protocol_policy = "https-only"

    forwarded_values {
      query_string = false
      headers      = ["Origin"]

      cookies {
        forward = "none"
      }
    }
  }

  # Cache behavior with precedence 1
  ordered_cache_behavior {
    path_pattern     = "/secondary/*"
    allowed_methods  = ["GET", "HEAD", "OPTIONS"]
    cached_methods   = ["GET", "HEAD", "OPTIONS"]
    target_origin_id = local.origin_id_map.s3_origin_id_2
    viewer_protocol_policy = "https-only"

    forwarded_values {
      query_string = false
      headers      = ["Origin"]

      cookies {
        forward = "none"
      }
    }
  }
  
  price_class = "PriceClass_200"

  restrictions {
    geo_restriction {
      restriction_type = "whitelist"
      locations        = ["US", "NG"]
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }

  tags = {
    Environment = "production"
  }

}

Solution

  • In the ordered_cache_block, I made sure the target_origin_id attribute references the origin group. I also removed the leading slash on the file path. So it becomes secondary/*

    locals {
      origin_id_map = {
        "s3_origin_id_1" = "S3_Origin_Primary"
        "s3_origin_id_2" = "S3_Origin_Secondary"
      }
    }
    
    resource "aws_cloudfront_distribution" "s3_distribution" {
      origin_group {
        origin_id = "Origin_Group_S3"
    
        failover_criteria {
          status_codes = [403, 404, 500, 502]
        }
    
        member {
          origin_id = local.origin_id_map.s3_origin_id_1
        }
    
        member {
          origin_id = local.origin_id_map.s3_origin_id_2
        }
      }
    
      origin {
        domain_name = aws_s3_bucket.Primary_Bucket.bucket_regional_domain_name
        origin_id   = local.origin_id_map.s3_origin_id_1
    
        s3_origin_config {
          origin_access_identity = aws_cloudfront_origin_access_identity.Primary_OAI.cloudfront_access_identity_path
        }
      }
    
      origin {
        domain_name = aws_s3_bucket.Secondary_Bucket.bucket_domain_name
        origin_id   = local.origin_id_map.s3_origin_id_2
    
        s3_origin_config {
          origin_access_identity = aws_cloudfront_origin_access_identity.Secondary_OAI.cloudfront_access_identity_path
        }
      }
    
      default_cache_behavior {
        allowed_methods  = ["OPTIONS", "GET", "HEAD"]
        cached_methods   = ["GET", "HEAD"]
        target_origin_id = "Origin_Group_S3"
        viewer_protocol_policy = "https-only"
    
        forwarded_values {
          query_string = false
    
          cookies {
            forward = "none"
          }
        }
      }
    
      enabled             = true
      is_ipv6_enabled     = true
      comment             = "S3 Distribution"
      default_root_object = "index.html"
    
      # Cache behavior with precedence 0
      ordered_cache_behavior {
        path_pattern     = "primary/*"
        allowed_methods  = ["GET", "HEAD", "OPTIONS"]
        cached_methods   = ["GET", "HEAD", "OPTIONS"]
        target_origin_id = “Origin_Group_S3”
        viewer_protocol_policy = "https-only"
    
        forwarded_values {
          query_string = false
          headers      = ["Origin"]
    
          cookies {
            forward = "none"
          }
        }
      }
    
      # Cache behavior with precedence 1
      ordered_cache_behavior {
        path_pattern     = "secondary/*"
        allowed_methods  = ["GET", "HEAD", "OPTIONS"]
        cached_methods   = ["GET", "HEAD", "OPTIONS"]
        target_origin_id = “Origin_Group_S3”
        viewer_protocol_policy = "https-only"
    
        forwarded_values {
          query_string = false
          headers      = ["Origin"]
    
          cookies {
            forward = "none"
          }
        }
      }
      
      price_class = "PriceClass_200"
    
      restrictions {
        geo_restriction {
          restriction_type = "whitelist"
          locations        = ["US", "NG"]
        }
      }
    
      viewer_certificate {
        cloudfront_default_certificate = true
      }
    
      tags = {
        Environment = "production"
      }
    
    }