cloudfront (terraform)

S3 frontend w/ origin access control (OAC)

modules/cloudfront/variables.tf

output "front_policy_text" {

  description = "Policy text for the 'frontend' S3 bucket to allow access from CloudFront"

  value       = data.aws_iam_policy_document.origin_access_control.json

}

modules/cloudfront/cloudfront.tf

data "aws_iam_policy_document" "origin_access_control" {

  policy_id = "PolicyForCloudFrontPrivateContent"

  statement {

    sid = "AllowCloudFrontServicePrincipal"

    principals {

      type        = "Service"

      identifiers = ["cloudfront.amazonaws.com"]

    }

    actions   = ["s3:GetObject"]

    resources = ["${var.bucket_front_arn}/*"]

    condition {

      test     = "StringEquals"

      variable = "AWS:SourceArn"

      values   = [aws_cloudfront_distribution.myapp.arn]

    }

  }

}


#CloudFront Origin Access Control, used with an Amazon S3 bucket as the origin

resource "aws_cloudfront_origin_access_control" "s3_front" {

  name                              = "Bucket ${var.bucket_front_id}"

  description                       = "S3 policy for the S3 bucket to be accessed by CloudFront"

  origin_access_control_origin_type = "s3"

  signing_behavior                  = "always"

  signing_protocol                  = "sigv4"

}


resource "aws_cloudfront_distribution" "myapp" {

  depends_on = [aws_api_gateway_deployment.deployment_myapp, var.bucket_front_id]


  origin { #S3

    domain_name = var.bucket_regional_domain_name

    origin_id   = "${var.bucket_front_id}-${var.env}"

    origin_path = ""

    origin_access_control_id = aws_cloudfront_origin_access_control.s3_front.id

  }


  origin { #API Gateway

     ...

  }


  ...

}


S3 frontend w/ origin access identity (OAI)

Remark: OAI is legacy, use AOC instead.

resource "aws_cloudfront_origin_access_identity" "web_distribution" {

  comment = "${var.env}-${var.ci} CloudFront origin access identity"

}


data "aws_iam_policy_document" "web_distribution" {

  statement {

    actions = ["s3:GetObject"]

    principals {

      type        = "AWS"

      identifiers = [aws_cloudfront_origin_access_identity.web_distribution.iam_arn]

    }

    resources = ["${var.bucket_frontend_arn}/*"]

  }

}


resource "aws_s3_bucket_policy" "web_distribution" {

  bucket = var.bucket_frontend_id

  policy = data.aws_iam_policy_document.web_distribution.json

}



resource "aws_cloudfront_distribution" "myapp" {

  depends_on = [aws_api_gateway_deployment.deployment_myapp, var.bucket_frontend]


  origin { #S3

    domain_name = var.bucket_regional_domain_name

    origin_id   = "${var.bucket_frontend}-${var.env}"

    origin_path = ""

    s3_origin_config {

      origin_access_identity = aws_cloudfront_origin_access_identity.web_distribution.cloudfront_access_identity_path

    }

  }


  origin { #API Gateway

     ...

  }


  ...

}


Lambda@Edge that intercepts 403 and 404 responses from origin S3 and redirects user to /index.html

See "Lambda@Edge sample (intercepts 403 and 404 responses from origin S3 and redirects user to /index.html)":

https://sites.google.com/site/pawneecity/terraform/lambda-terraform#h.e9vhp6dpmi88


WAF

See page 'waf (terraform)'.