作成経緯
この続き。
参考サイトからcloudformationで作成している部分の要素をterraformに落とし込むため、確認を行う。
まずはs3バケット(静的サイト)から。
この記事はそのメモやまとめです。
すでに設定済みの項目がいくつかある。
試行錯誤しながらやったので、手順として不要かもしれない。あくまでメモ用。
s3バケット(静的サイト)
参考サイトのCFでは以下のような記載になっている。
今回は知識をつけるということもあり、ひと要素づつ分解して見ていく。
s3バケット(静的サイト)
# ------------------------------------------------------------------------------------ #
# S3
# ------------------------------------------------------------------------------------ #
# Static site bucket
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub ${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}
OwnershipControls:
Rules:
- ObjectOwnership: "BucketOwnerEnforced"
PublicAccessBlockConfiguration:
BlockPublicAcls: True
BlockPublicPolicy: True
IgnorePublicAcls: True
RestrictPublicBuckets: True
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: "AES256"
BucketKeyEnabled: false
LifecycleConfiguration:
Rules:
- Id: AbortIncompleteMultipartUpload
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 7
Status: "Enabled"
- Id: NoncurrentVersionExpiration
NoncurrentVersionExpiration:
NewerNoncurrentVersions: 3
NoncurrentDays: 1
Status: Enabled
# Bucket Policy for CloudFront
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3Bucket
PolicyDocument:
Statement:
- Action: s3:GetObject
Effect: Allow
Resource: !Sub arn:aws:s3:::${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}/*
Principal:
AWS: !Sub arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginAccessIdentity}
BucketName
こちらは名前のまま、バケット名を定義している
BucketName: !Sub ${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}
OwnershipControls
OwnershipControls:
Rules:
- ObjectOwnership: "BucketOwnerEnforced"
https://dev.classmethod.jp/articles/s3-bucket-owner-enforced/
https://dev.classmethod.jp/articles/s3-acl-error-from-202304/
バケットのすべてのオブジェクトのACLを『バケットを所有しているアカウント』のものとすることができるようです。現状はこれは書いておくべき項目のようです。
ACL(ネットワークアクセスコントロールリスト)についてですが、現在はバケットポリシーで十分であり、特殊な場合を除いてはACLは無効化することがAWSの公式より推奨されています。
(以下はバケット作成時の画面です)
つまりこの記述によってACL無効化設定を行っています。
terraformだとこんな感じの記述になるようです。
https://blog-benri-life.com/aws-terraform-s3-acl-disable/
PublicAccessBlockConfiguration
PublicAccessBlockConfiguration:
BlockPublicAcls: True
BlockPublicPolicy: True
IgnorePublicAcls: True
RestrictPublicBuckets: True
ブロックパブリックアクセスの設定です。
静的サイトとして公開するのになぜパブリックアクセスがブロックされるのか?と疑問に思ったのですが、あとの方でOrigin Access Identity(OAI)の設定をしているようでした。
簡単に言うとcloudfrontのみがs3の静的コンテンツのみにアクセスでき、ユーザーはcloudfront上からしかコンテンツにアクセスできない(s3へ直接ユーザーがコンテンツにアクセスできない)という設定です。
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html
オリジンアクセスコントロール (OAC) を作成して設定する前に、Amazon S3 バケットオリジンを持つ CloudFront ディストリビューションが必要です。このオリジンは、ウェブサイトエンドポイントとして設定されたバケットではなく、通常の S3 バケットである必要があります
とあるように、用意するのは通常のs3バケットでよく、通常のs3バケットはパブリックアクセスをブロックする設定が望ましいのでこのようにしているようです。
VersioningConfiguration
VersioningConfiguration:
Status: Enabled
バケットのバージョニングの設定です。
今回は有効になっていますが、静的コンテンツについてはgitで管理する、コストを掛けたくない自分には不要な設定かと思ったので、実際は無効化する予定です。
BucketEncryption
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: "AES256"
BucketKeyEnabled: false
暗号化の設定です。
AES256だとSSE-S3を利用するようです。
BucketKeyEnabledについてはSSE-KMSの場合のオプションなので、SSE-S3の場合は無効にします。
SSE-S3についてはこちら
LifecycleConfiguration
LifecycleConfiguration:
Rules:
- Id: AbortIncompleteMultipartUpload
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 7
Status: "Enabled"
- Id: NoncurrentVersionExpiration
NoncurrentVersionExpiration:
NewerNoncurrentVersions: 3
NoncurrentDays: 1
Status: Enabled
ライフサイクルの設定です。項目がいくつかあるのでそれぞれに付いて確認する。
LifecycleConfiguration:
Rules: #ライフサイクルルールであるという宣言
- Id: AbortIncompleteMultipartUpload #ルールのIDです
AbortIncompleteMultipartUpload: #不完全なマルチパートアップロードを削除する
DaysAfterInitiation: 7 #7日後
Status: "Enabled"
- Id: NoncurrentVersionExpiration
NoncurrentVersionExpiration: #いくつまでバージョニングするか
NewerNoncurrentVersions: 3 #3個のバージョニングを保持します
NoncurrentDays: 1 #3バージョン以下のバーションは1日後に削除される
Status: Enabled
BucketPolicy
バケットポリシーの設定です。
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3Bucket
PolicyDocument:
Statement:
- Action: s3:GetObject
Effect: Allow
Resource: !Sub arn:aws:s3:::${ProjectName}-${Environment}-${S3BucketName}-${AWS::AccountId}/*
Principal:
AWS: !Sub arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginAccessIdentity}
この部分でOAIを定義しているようです。ここではgetのみ許可している。
ここで問題が……
今までOrigin Access Identity(OAI)を利用する前提で書いていましたが、
現在はOrigin Access Control (OAC)という新機能が登場しており、OAIはレガシー扱いになっているようで、新規で作成する場合はOACを公式で推奨しているようです。
なので制作するサイトでもOACを利用したいと思います。
・セキュリティ – OAC は、短期間のクレデンシャル、頻繁なクレデンシャルのローテーション、およびリソースベースのポリシーのような強化されたセキュリティプラクティスで実装されています。これらは、ディストリビューションのセキュリティポスチャを強化し、混乱する代理のような攻撃に対してより良い保護を提供します。
・包括的な HTTP メソッドのサポート – OAC は GET、PUT、POST、PATCH、DELETE、OPTIONS、および HEAD をサポートしています。
・SSE-KMS – OAC は、SSE-KMS で暗号化された S3 オブジェクトのダウンロードとアップロードをサポートしています。
・すべての AWS リージョンでの S3 にアクセス – OAC は、既存のリージョンと将来のすべてのリージョンを含む、すべての AWS リージョンでの S3 へのアクセスをサポートしています。一方、OAI は既存の AWS リージョンと 2022 年 12 月までに開始されるリージョンでのみサポートされます。
https://aws.amazon.com/jp/blogs/news/amazon-cloudfront-introduces-origin-access-control-oac/
https://blog.serverworks.co.jp/cloudfront-oai-to-oac
https://dev.classmethod.jp/articles/amazon-cloudfront-origin-access-control/
https://qiita.com/hayao_k/items/8558042d52be4f29c6e6
ハマったところとか
意外と要素それぞれについて解説しているサイトがなかった。
英語の公式を見る→Deeplで翻訳が結構早かった。
次にやること
- cloudfront/cloudforntログ保存用s3バケットのcfファイルの分解
- 必要なAWSのリソースをterraformで作成
- HUGOでHPをいい感じに編集する
- GitHub Actionsの設定