概要
参考サイトのcloudformationの分解が完了したので、今回からterraformに落とし込みます。
まずs3バケット(静的)/s3バケット(CloudFrontログ保存用)/CloudFrontの3つです。
公式リファレンスと自分の記事をもとに作成します。
この記事はそのメモやまとめです。
すでに設定済みの項目がいくつかある。
試行錯誤しながらやったので、手順として不要かもしれない。あくまでメモ用。
ざっくりとした流れ
s3バケット(静的サイト) → s3バケット(CloudFrontログ保存用) → cloudfront → s3バケット(静的サイト)でOAC作成
の順でリソースの作成を行いました。
tfファイルを作成してすぐにterraformで
terraform init
terraform validate
terraform fmt
terraform plan
terraform apply
を実行してリソースの作成を行いました。
完成した資材
s3バケット(静的サイト)
resource "aws_s3_bucket" "s3_hugo" {
bucket = "hogehoge-hugo"
}
# オブジェクト所有者を「バケット所有者の強制」にすることでACLの無効化
resource "aws_s3_bucket_ownership_controls" "s3_hugo" {
bucket = aws_s3_bucket.s3_hugo.id
rule {
object_ownership = "BucketOwnerEnforced"
}
}
# パブリックアクセスをブロック
resource "aws_s3_bucket_public_access_block" "s3_hugo" {
bucket = aws_s3_bucket.s3_hugo.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# バージョニング設定
resource "aws_s3_bucket_versioning" "s3_hugo" {
bucket = aws_s3_bucket.s3_hugo.id
versioning_configuration {
status = "Disabled"
}
}
# s3側での暗号化
resource "aws_s3_bucket_server_side_encryption_configuration" "s3_hugo" {
bucket = aws_s3_bucket.s3_hugo.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
# lifecycleの設定
resource "aws_s3_bucket_lifecycle_configuration" "s3_hugo" {
bucket = aws_s3_bucket.s3_hugo.id
rule {
id = "purge-noncurrent-version"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 7
}
noncurrent_version_expiration {
newer_noncurrent_versions = 3
noncurrent_days = 1
}
}
}
# OAC バケットポリシー
resource "aws_s3_bucket_policy" "static_hosting" {
bucket = aws_s3_bucket.s3_hugo.id
policy = data.aws_iam_policy_document.bucket_static_hosting.json
}
data "aws_iam_policy_document" "bucket_static_hosting" {
version = "2012-10-17"
statement {
principals {
type = "Service"
identifiers = ["cloudfront.amazonaws.com"]
}
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.s3_hugo.arn}/*"]
condition {
test = "StringEquals"
variable = "aws:SourceArn"
values = [aws_cloudfront_distribution.hugo_distribution.arn]
}
}
}
s3バケット(CloudFrontログ保存用)
resource "aws_s3_bucket" "s3_cloudfront_log" {
bucket = "hogehoge-hugo-cloudfront-log"
}
# ACL有効
resource "aws_s3_bucket_ownership_controls" "s3_cloudfront_log" {
bucket = aws_s3_bucket.s3_cloudfront_log.id
rule {
object_ownership = "ObjectWriter"
}
}
# パブリックアクセスをブロック
resource "aws_s3_bucket_public_access_block" "s3_cloudfront_log" {
bucket = aws_s3_bucket.s3_cloudfront_log.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
# バージョニング設定
resource "aws_s3_bucket_versioning" "s3_cloudfront_log" {
bucket = aws_s3_bucket.s3_cloudfront_log.id
versioning_configuration {
status = "Enabled"
}
}
# s3側での暗号化
resource "aws_s3_bucket_server_side_encryption_configuration" "s3_cloudfront_log" {
bucket = aws_s3_bucket.s3_cloudfront_log.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
# lifecycleの設定
resource "aws_s3_bucket_lifecycle_configuration" "s3_cloudfront_log" {
bucket = aws_s3_bucket.s3_cloudfront_log.id
rule {
id = "cloudfront_log"
status = "Enabled"
expiration {
days = 1095
}
transition {
## オブジェクトが作成されてからSTANDARD_IAに移行するまでの日数。
days = 30
storage_class = "STANDARD_IA"
}
transition {
days = 90
storage_class = "GLACIER"
}
noncurrent_version_expiration {
noncurrent_days = 365
}
noncurrent_version_transition {
noncurrent_days = 30
storage_class = "STANDARD_IA"
}
noncurrent_version_transition {
noncurrent_days = 60
storage_class = "GLACIER"
}
abort_incomplete_multipart_upload {
days_after_initiation = "7"
}
}
}
CloudFront
# OACの設定を作成
resource "aws_cloudfront_origin_access_control" "hugo_oac" {
name = "hugo_oac"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
resource "aws_cloudfront_distribution" "hugo_distribution" {
origin {
domain_name = "hogehoge-hugo.s3.ap-northeast-1.amazonaws.com"
origin_id = "s3origin"
origin_access_control_id = aws_cloudfront_origin_access_control.hugo_oac.id
}
enabled = true
is_ipv6_enabled = false
http_version = "http2"
price_class = "PriceClass_200" # 価格クラスの設定。
default_root_object = "index.html"
wait_for_deployment = true # ディストリビューションのステータスが「InProgress」→「Deployed」に変わることを待つかどうかの設定。
aliases = ["hogehoge.com"]
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "s3origin"
compress = false
viewer_protocol_policy = "redirect-to-https"
cache_policy_id = "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" # CachingDisabled
#cache_policy_id = "658327ea-f89d-4fab-a63d-7e88639e58f6" # CachingOptimized
}
# ログの設定
logging_config {
include_cookies = false
bucket = "hogehoge-hugo-cloudfront-log.s3.ap-northeast-1.amazonaws.com" #ログ用のs3バケットを指定
prefix = "cloudfront/"
}
# 日本からのみアクセス可能
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = ["JP"] # アクセスを許可する国コードを追加
}
}
# SSL証明書の設定
viewer_certificate {
cloudfront_default_certificate = false
acm_certificate_arn = "証明書arn"
minimum_protocol_version = "TLSv1.2_2019"
ssl_support_method = "sni-only"
}
}
ハマったところとか
- 一番初めのplan実行した際に、これとは関係のないterraform資材がdestroyとして出てしまった。原因はbackendの変更し忘れ。
- cloudfrontログ保存用のs3はACLが有効が必要。
- 作成したcloudfrontに対してドメインでアクセスしても、エラーページが表示されず到達できない旨のエラーになる。cloudfrontとroute53のレコード設定がされていなかった。CloudFrontの
Distribution domain name
と自分が利用したいドメインをroute53でAレコードで登録することによって解決。
次にやること
- GitHub Actionsの設定
- HUGOでHPをいい感じに編集する
- テスト記事の投稿