Origin Access Control(OAC)

S3のオブジェクトをCloudFrontで配信する方法の1つ。
S3を非公開設定にしてCloudFrontからのみアクセスできるようにする。

設定方法

S3バケットの作成

S3バケットを作成する。
aws_s3_bucket_public_access_blockで各ブロック設定をonにする。

resource "aws_s3_bucket" "example" {
  bucket = "example-bucket"
}

resource "aws_s3_bucket_public_access_block" "example" {
  bucket = aws_s3_bucket.example.id

  # 非公開設定
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

applyするとS3のブロック設定は以下のようになる。

S3のブロック設定

CloudFront オリジンアクセスコントロールの作成

OACを作成する。

resource "aws_cloudfront_origin_access_control" "front" {
  name                              = aws_s3_bucket.example.bucket
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

nameは適宜わかりやすい名前をつける。上記の例ではバケット名を指定している。

origin_access_control_origin_typeにはs3を指定する。

applyするとオリジンアクセスコントロールの設定は以下のようになる。

CloudFront オリジンアクセスコントロールの設定

CloudFrontディストリビューションの作成

CloudFrontディストリビューションを作成する。

resource "aws_cloudfront_distribution" "example" {
  # (省略)

  origin {
    domain_name              = "${aws_s3_bucket.example.bucket}.s3.ap-northeast-1.amazonaws.com"
    origin_id                = "${aws_s3_bucket.example.bucket}.s3.ap-northeast-1.amazonaws.com"
    # OAC の設定
    origin_access_control_id = aws_cloudfront_origin_access_control.front.id
  }

  # (省略)
}

originorigin_access_control_idには先ほど作成したOACのIDを指定する。

applyするとCloudFrontディストリビューションの設定は以下のようになる。

CloudFrontディストリビューションの設定

上記設定はCloudFrontのディストリビューションのオリジン設定の編集画面で確認できる。

S3バケットポリシーの設定

S3バケット側にOACを受け入れるためのバケットポリシーを設定する。

resource "aws_s3_bucket_policy" "front_oac" {
  bucket = aws_s3_bucket.example.bucket
  policy = data.aws_iam_policy_document.example_oac.json
}

data "aws_iam_policy_document" "example_oac" {
  statement {
    principals {
      type        = "Service"
      identifiers = ["cloudfront.amazonaws.com"]
    }
    actions   = ["s3:GetObject"]
    resources = ["${aws_s3_bucket.example.arn}/*"]
    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values = [aws_cloudfront_distribution.example.arn]
    }
  }
}

バケット内のオブジェクトに対するGetObjectアクションをCloudFrontからのみ許可するように設定する。

principalにはcloudfront.amazonaws.comを指定する。

conditionにはaws:SourceArnを指定し、値には先ほど作成したCloudFrontディストリビューションのARNを指定する。