☁️
TerraformでCloudFront + S3の構成を作る
はじめに
静的サイトジェネレータhugo
をcloudfront + s3の構成で利用したく、
その準備方法を調べたのでメモします。(hugoについてはこの記事で触れません)
Terraformを使用して環境を用意します。
環境
terraform 1.4.6
方針
- s3周辺リソースを作成する
- cloudfrontディストリビューションを作成する
の流れでtfファイルをつくっていきます。
使用するコード
長いため折りたたみます。
main.tf
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 = "xxxxxxxxxxxxxxxxxxxxx"
}
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
}
ポイント
s3の設定
s3の設定はここを意識すればOKです
- ウェブホスティングを有効化しない
-
Block public access
をすべて有効化 - ACLは
private
この後OACというs3へのアクセス制御を設定しますが、
そのおかげでs3をプライベートな環境に置くことが可能です。
cloudfrontディストリビューション
設定項目が多いですが、以下を参考に設定します。
非常にわかりやすい記事です、参考にさせていただきました。
今回作成するs3バケットをオリジンにするのを忘れずに行いましょう。
オリジンアクセスコントロール(OAC)を設定する
ざっくりいうとs3に安全にアクセス出来る仕組みだと思います。
昨年新しくリリースされました。
それ以前もOAIという仕組みがあったのですが、基本的にOACを使うのが推奨されているようです。
こちらもTerraformで設定します。
OACがs3バケットにアクセス出来るようにする
ということでs3のアクセスポリシーを設定します。
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]
}
}
}
要はソースがcloudfrontかどうかを見ているようです。
所感
- cloudfrontの設定項目が多いため、AWS/Terraformのドキュメントをよく参照すること
- はい、わたしも足りないので熟読します。
- セキュリティのため、OACを設定すること
参考
Discussion