Closed8

TerraformでCloudfront+S3の構成を作る

not75743not75743

s3

  • ウェブホスティングを有効化しない
  • Block public accessをすべて有効化
  • ACLはprivate
not75743not75743

Cloudfront

  • Origin domain:作成したS3バケットを指定
  • Origin access:「Origin access control settings」を指定
  • Origin access:Origin access control
    • Origin access control新規作成
    • 署名リクエストにチェック
  • WAFは無効
not75743not75743

s3側バケットポリシー設定

{
    "Version": "2012-10-17",
    "Statement": {
        "Sid": "AllowCloudFrontServicePrincipalReadOnly",
        "Effect": "Allow",
        "Principal": {
            "Service": "cloudfront.amazonaws.com"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::<S3 bucket name>/*",
        "Condition": {
            "StringEquals": {
                "AWS:SourceArn": "<CloudFront distribution ARN>"
            }
        }
    }
}

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html
https://aws.amazon.com/jp/blogs/news/amazon-cloudfront-introduces-origin-access-control-oac/

not75743not75743

Terraform化

s3+cloudfront
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.65.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
  default_tags {
    tags = {
      env       = "test"
      provision = "terraform"
    }
  }
}

locals {
  bucket_name = "xxxxxxxxxxxxxxxx"
}

resource "aws_s3_bucket" "hugo_bucket" {
  bucket = local.bucket_name
}

resource "aws_s3_object" "index" {
  bucket = aws_s3_bucket.hugo_bucket.id
  key    = "index.html"
  source = "./index.html"
}

resource "aws_s3_bucket_policy" "policy" {
  depends_on = [
    aws_s3_bucket.hugo_bucket,
  ]
  bucket = aws_s3_bucket.hugo_bucket.id
  policy = data.aws_iam_policy_document.policy_document.json
}

data "aws_iam_policy_document" "policy_document" {
  statement {
    principals {
      type        = "Service"
      identifiers = ["cloudfront.amazonaws.com"]
    }

    actions = [
      "s3:GetObject",
    ]

    resources = [
      aws_s3_bucket.hugo_bucket.arn,
      "${aws_s3_bucket.hugo_bucket.arn}/*",
    ]
    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = [aws_cloudfront_distribution.hugo_cfront.arn]
    }
  }
}

resource "aws_cloudfront_distribution" "hugo_cfront" {
  enabled = true
  default_root_object = "index.html"

  origin {
    origin_id                = aws_s3_bucket.hugo_bucket.id
    domain_name              = aws_s3_bucket.hugo_bucket.bucket_regional_domain_name
    origin_access_control_id = aws_cloudfront_origin_access_control.hugo_oac.id
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }

  default_cache_behavior {
    target_origin_id       = aws_s3_bucket.hugo_bucket.id
    viewer_protocol_policy = "redirect-to-https"
    cached_methods         = ["GET", "HEAD"]
    allowed_methods        = ["GET", "HEAD"]
    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }
}

resource "aws_cloudfront_origin_access_control" "hugo_oac" {
  name                              = aws_s3_bucket.hugo_bucket.bucket_domain_name
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

output "cfront_domain_name" {
  value = aws_cloudfront_distribution.hugo_cfront.domain_name
}

確認

とても参考にさせていただいた

https://zenn.dev/kou_pg_0131/articles/tf-cloudfront-oac
あとはドキュメント

持ち越し

  • あまり内容を理解できていないので確認する
  • https://<cloudfront_domain>ではhtmlファイルが確認出来たが、https://<cloudfront_domain>/index.htmlだとファイルがダウンロードされてしまう
このスクラップは2023/06/19にクローズされました