こんにちは。
技術課の山本です。
夏休みは北アルプスをお散歩していました。お気に入りの黒部五郎岳です。
以下の記事で、Amazon CloudFront の Origin Access Identity を Origin Access Control (OAC) に切り替える方法をご案内しました。
Terraform も Origin Access Control (OAC) に対応しましたので、本記事で紹介します。
AWS Provider 4.29.0 以降のバージョンがOACに対応しています。
具体的には、以下が可能になっています。
- Origin Access Control (OAC) を作成可能になった
- Origin Access Control (OAC) をCloudFront ディストリビューションのS3オリジンに紐づけることが可能になった
FEATURES:
New Resource: aws_cloudfront_origin_access_control (#26508)ENHANCEMENTS:
resource/aws_cloudfront_distribution: Add origin_access_control_id to the origin configuration block (#26510)
Origin Access Control (OAC) を作成するコード。
Origin Access Control (OAC) を作成します。
公式ドキュメント:cloudfront_origin_access_control
resource "aws_cloudfront_origin_access_control" "example" { name = "example" description = "example" origin_access_control_origin_type = "s3" signing_behavior = "always" signing_protocol = "sigv4" }
Origin Access Control (OAC) をCloudFront ディストリビューションのS3オリジンに紐づけるコード。
元々あったOrigin Access Identity をコメントアウトし、Origin Access Control (OAC) をCloudFront ディストリビューションのS3オリジンに紐づけます。
公式ドキュメント:cloudfront_distribution
resource "aws_cloudfront_distribution" "s3_distribution" { origin { domain_name = aws_s3_bucket.b.bucket_regional_domain_name origin_id = local.s3_origin_id # Origin Access Control (OAC) を紐づける。 origin_access_control_id = aws_cloudfront_origin_access_control.example.id # 元々あったOrigin Access Identity をコメントアウト #s3_origin_config { # origin_access_identity = aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path #} }
S3 のバケットポリシーを更新するコード。
CloudFront を更新している最中に、WEBサイトに接続しているユーザーが、Origin Access Identity で 引き続きS3 オリジンのコンテンツに接続できるようにします。
そのために、元々のポリシーを残しておきます。
1つ目の statement は Origin Access Control (OAC) 用に新規作成したものです。
2つ目の statement は Origin Access Identity 用に元々あったものです。
2つ目のステートメントは Origin Access Control (OAC) への切り替え後に削除します。
resource "aws_s3_bucket_policy" "example" { bucket = aws_s3_bucket.b.id policy = data.aws_iam_policy_document.example.json } data "aws_iam_policy_document" "example" { statement { principals { type = "Service" identifiers = ["cloudfront.amazonaws.com"] } actions = ["s3:GetObject"] resources = ["${aws_s3_bucket.b.arn}/*"] condition { test = "StringEquals" variable = "aws:SourceArn" values = [aws_cloudfront_distribution.s3_distribution.arn] } } statement { principals { type = "AWS" identifiers = [aws_cloudfront_origin_access_identity.example.iam_arn] } actions = ["s3:GetObject"] resources = ["${aws_s3_bucket.b.arn}/*"] } }
Origin Access Control (OAC) への切り替え。
Origin Access Control (OAC) への切り替えをしていきます。
terraform plan terraform apply
完了しました。
反映されています。
Origin Access Control (OAC)ができています。
Origin Access Control (OAC) がCloudFront ディストリビューションのS3オリジンに紐づいています。
S3のバケットポリシーも反映できています。
WEBサイトに正常にアクセスできることが確認できたら、S3 のバケットポリシーから、Origin Access Identity 用のステートメントを削除します。
Origin Access Identity 用のステートメントを削除したコードは以下です。削除箇所がわかりやすいようにコメントアウトしています。
data "aws_iam_policy_document" "example" { statement { principals { type = "Service" identifiers = ["cloudfront.amazonaws.com"] } actions = ["s3:GetObject"] resources = ["${aws_s3_bucket.b.arn}/*"] condition { test = "StringEquals" variable = "aws:SourceArn" values = [aws_cloudfront_distribution.s3_distribution.arn] } } #statement { # principals { # type = "AWS" # identifiers = [aws_cloudfront_origin_access_identity.example.iam_arn] # } # actions = ["s3:GetObject"] # resources = ["${aws_s3_bucket.b.arn}/*"] #} }
また、Origin Access Identity 自体も削除します。削除箇所がわかりやすいようにコメントアウトしています。
#resource "aws_cloudfront_origin_access_identity" "example" {}
環境に反映していきます。
terraform plan terraform apply
完了しました。
S3のバケットポリシーも反映できています。
WEBサイトに正常にアクセスできることを確認します。
以上で完了です。
サンプルコード
この記事を書くにあたり、検証したサンプルコードを記載します。
検証等にご利用ください。
概ね、以下の公式ドキュメントにあるサンプルを流用しています。
公式ドキュメント1:cloudfront_origin_access_control
公式ドキュメント2:cloudfront_distribution
resource "aws_s3_bucket" "b" { bucket = "mybucket-testtesttesttesttesttet" } resource "aws_s3_bucket_acl" "b_acl" { bucket = aws_s3_bucket.b.id acl = "private" } locals { s3_origin_id = "myS3Origin" } #resource "aws_cloudfront_origin_access_identity" "example" {} resource "aws_cloudfront_distribution" "s3_distribution" { origin { domain_name = aws_s3_bucket.b.bucket_regional_domain_name origin_id = local.s3_origin_id origin_access_control_id = aws_cloudfront_origin_access_control.example.id #s3_origin_config { # origin_access_identity = aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path #} } enabled = true is_ipv6_enabled = true comment = "Some comment" default_root_object = "index.html" default_cache_behavior { allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] cached_methods = ["GET", "HEAD"] target_origin_id = local.s3_origin_id forwarded_values { query_string = false cookies { forward = "none" } } viewer_protocol_policy = "allow-all" min_ttl = 0 default_ttl = 3600 max_ttl = 86400 } restrictions { geo_restriction { restriction_type = "whitelist" locations = ["JP","US", "CA", "GB", "DE"] } } price_class = "PriceClass_200" viewer_certificate { cloudfront_default_certificate = true } } resource "aws_cloudfront_origin_access_control" "example" { name = "example" description = "example" origin_access_control_origin_type = "s3" signing_behavior = "always" signing_protocol = "sigv4" } resource "aws_s3_bucket_policy" "example" { bucket = aws_s3_bucket.b.id policy = data.aws_iam_policy_document.example.json } data "aws_iam_policy_document" "example" { statement { principals { type = "Service" identifiers = ["cloudfront.amazonaws.com"] } actions = ["s3:GetObject"] resources = ["${aws_s3_bucket.b.arn}/*"] condition { test = "StringEquals" variable = "aws:SourceArn" values = [aws_cloudfront_distribution.s3_distribution.arn] } } #statement { # principals { # type = "AWS" # identifiers = [aws_cloudfront_origin_access_identity.example.iam_arn] # } # actions = ["s3:GetObject"] # resources = ["${aws_s3_bucket.b.arn}/*"] #} }
山本 哲也 (記事一覧)
カスタマーサクセス部のエンジニア。2024 Japan AWS Top Engineers に選んでもらいました。
今年の目標は Advanced Networking – Specialty と Machine Learning - Specialty を取得することです。
山を走るのが趣味です。今年の目標は 100 km と 100 mile を完走することです。 100 km は Gran Trail みなかみで完走しました。OSJ koumi 100 で 100 mile 砕け散りました。どこかで 100 mile やりたいです。
基本的にのんびりした性格です。座右の銘は「いつか着く」