
はじめに
こんにちは、クラウドエンジニアリング部の本橋です。
アーキテクチャの構成を学ぶことが多いのですが、ふと実際に環境を構築したくなりました。
せっかくなので汎用的に使えそうな構成(根拠はまったくない)を作りつつ細かいところの理解をできたらと思っています。
第2回
汎用的に使えそうなAWS構成 - 第2回 Route53/ACM 設定 - APC 技術ブログ
最終的なゴール
いきなりですが、以下の構成を目指して作ることを考えています。 (細かいところはほとんど考えておらず、最終的にどうなるかは詰められてません)

詳細を全く考えていないので、上記構成をさらに拡張したり、逆に縮小することがあるかと思いますが、ご承知おきください。 構成に変更があれば最後まで環境構築を完成させた後にこのページの全体像を修正する予定です。
今回やること
冒頭で示した図の内容をすべて実装するととても大変なので何回かに分けて実装します。 今回実装する範囲は以下になります。

terraformコード
今回最終的に動いたS3とCloud Frontについては以下gitで公開しています。 必要に応じて参照ください。
https://github.com/hsmto25519/aws_terraform/tree/main
CloudFrontを学習する
S3構築
S3については何度も利用したことがあるサービスなので、terraformで構築してしまいます。
resource "aws_s3_bucket" "s3_images" {
bucket = "s3-sample5-images1"
force_destroy = true
tags = var.tags
}
resource "aws_s3_bucket_public_access_block" "public_access_block" {
bucket = aws_s3_bucket.s3_images.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_server_side_encryption_configuration" "server_side_encryption_configuration" {
bucket = aws_s3_bucket.s3_images.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_website_configuration" "static_hosting" {
bucket = aws_s3_bucket.s3_images.id
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
}
resource "aws_s3_object" "index" {
key = "index.html"
bucket = aws_s3_bucket.s3_images.id
source = "../files/index.html"
content_type = "text/html"
}
data "aws_iam_policy_document" "s3_policy" {
statement {
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.s3_images.arn}/*"]
principals {
type = "AWS"
identifiers = [aws_cloudfront_origin_access_identity.oai.iam_arn]
}
}
}
resource "aws_s3_bucket_policy" "policy" {
bucket = aws_s3_bucket.s3_images.id
policy = data.aws_iam_policy_document.s3_policy.json
}
必要なところだけ補足します。 ①apply_server_side_encryption_by_default.sse_algorithm = "AES256" 今回Cloud Front側でOAIを利用するのですが、OAIを利用する場合、AES-256を指定する必要があります。 私は検証時、AWS KMSを指定していて長い間詰まりましたのでお気を付けください。
CloudFront ディストリビューションは、オリジンアクセスアイデンティティ (OAI) を使用する場合、AWS Key Management Service (AWS KMS) で暗号化されたオブジェクトをサポートしません。ディストリビューションを使用して提供する S3 オブジェクトからは、AWS KMS による暗号化を削除する必要があります。AWS KMS での暗号化を使用する代わりに、AES-256 を使用してオブジェクトを暗号化します。 repost.aws
ちなみに、KMSが原因で引っかかった場合比較的わかりやすい文言が表示されます(私は原因に気が付くのに時間がかかりましたが。。)。

②aws_s3_object.source 「../files/index.html」で今回公開するページを指定しています。 htmlで公開する場合は、content_typeを明示的に指定しないとうまくページが表示されないのでここも注意です。
CloudFront構築
本題です。 CloudFrontの作成にあたっては以下のページを参考にさせていただきました。ありがとうございます。 qiita.com
まずはCloudFrontのページに行きdistributionの作成をします。

- オリジン
- オリジンドメイン
- 作成したS3
- オリジンアクセス
- Origin access control settings (recommended)
- Legacy access identities選択
- 「はい、バケットポリシーを自動で編集します」を選択
- オリジンドメイン
※「 Legacy access identities」を選択してください。
画像の中ではOrigin access controlを選択していますが、これは新機能でした。今度試すことにします。

- デフォルトのキャッシュビヘイビア
- ビューワー
- HTTPS only
- Cache policy and origin request policy (recommended)
- CachingOptimized
- ビューワー

- 関数の関連付け - オプション
- 変更しない

- Web Application Firewall (WAF)
- Do not enable security protectionsを選択

- 設定
- 料金クラス
- 北米、欧州、アジア、中東、アフリカを使用
- 料金クラス
-> 作成

「新しいディストリビューションが正常に作成されました。」となったので待ちます。
数分後、ディストリビューションドメイン名をコピーしてブラウザでアクセスすると以下が表示されました。成功です。

terraform作成
CloudFrontへの理解が深まったところでterraform化します。 以下のページを参考にさせてもらいました。
上記ページを参考にしつつ公式サイトの設定パラメータを見ながら最終的に作成したのが冒頭の「terraformコード」の中で示したgit repositoryです。
作成の詳細は長くなってしまうため割愛します。
感想
思いのほかCloudFront→S3連携の部分で躓いてしまいました。
ただterraform化までできたため、次回以降の検証はやりやすくなりそうです。
今回CloudFront+S3を作ることができたので、次はRoute 53による名前解決の部分を実装しようと思ってます。
このページ内ではふれてないのですが、MFAユーザを使ってterraform実行する必要があったため、terraformを実行するまでに実は結構時間がかかりました。
備忘も兼ねて別の記事として出せたらいいなと思ってます。
今回は以上です!最後までお読みいただきありがとうございました。
おわりに
私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。
https://www.ap-com.co.jp/service/utilize-aws/
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。