8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

スターフェスティバルAdvent Calendar 2020

Day 24

Terraform + S3 + CloudFrontで静的サイトを簡単構築

Posted at

AWSで静的サイトを構築する時は基本的にS3の静的Webサイトホスティング + CloudFrontを使って構成すると思います。
このときGUIでやると少し手間なのでTerraformで一気に構築できる手順をまとめました。

構成

今回は最も単純な構成で下記を構築します。

S3

バケット名:test-static-web-site
静的Webサイトホスティング
インデックスドキュメント:index.html
エラードキュメント:index.html (実際はエラー用のページを用意するといいと思います)

CloudFront

ディストリビューション名:test-static-web-site-dst
基本的な構成でオリジンをS3バケットに向ける
OriginAccessIdentity を使ってS3バケットへのアクセス権限をバケットポリシーに設定
今回SSLはCloudFrontデフォルトのもの。独自ドメインを持っている場合はACMの証明書もTerraformで作成することで acm_certificate_arn で指定でき、簡単です。

Terraformを書く

実際のtfファイルで下記を作成します。

S3

s3.tf
# バケットの作成
resource "aws_s3_bucket" "test-static-web-site" {
    bucket = "test-static-web-site"
    acl    = "private"
    # バケットポリシーの指定
    policy = data.aws_iam_policy_document.test-static-web-site-bucket_policy.json

    versioning {
        enabled = true
    }
    
    website {
        index_document = "index.html"
        error_document = "index.html"
    }

}

# OriginTarget用の変数作成
locals {
    s3-origin-id-test-static-web-site = "s3-origin-id-test-static-web-site"
}

# バケットポリシー
data "aws_iam_policy_document" "test-static-web-site-bucket_policy" {
    statement {
        sid    = ""
        effect = "Allow"
        principals {
            type        = "AWS"
            # identifiersはCloudFrontのtfファイルからパス指定することでDistribution作成後にIDを調べてからでなくても指定できます
            identifiers = ["${aws_cloudfront_origin_access_identity.test-static-web-site-idntity.iam_arn}"]
        }

        actions = [
            "s3:GetObject"
        ]

        resources = [
            "arn:aws:s3:::test-static-web-site",
            "arn:aws:s3:::test-static-web-site/*"
        ]
    }
}

CloudFront

cloudfront.tf
# Distributionの作成
resource "aws_cloudfront_distribution" "test-static-web-site-dst" {
    # Originの作成。
    origin {
        domain_name = aws_s3_bucket.test-static-web-site.bucket_regional_domain_name
        origin_id   = local.s3-origin-id-test-static-web-site
        s3_origin_config {
            origin_access_identity = aws_cloudfront_origin_access_identity.test-static-web-site-idntity.cloudfront_access_identity_path
        }
    }

    enabled             = true
    # indexドキュメント
    default_root_object = "index.html"
    wait_for_deployment = true
    
    # 独自ドメインを使用する場合はaliasを指定することでドメインでのアクセスも可能です
    # aliases             = ["xxxxxx.com"]

    # SSL証明書。ACMを使用する場合はここで指定すると利用可能です
    viewer_certificate {
        acm_certificate_arn            = ""
        cloudfront_default_certificate = true
        ssl_support_method             = ""
    }
    
    # 404エラー時に返すファイル
    custom_error_response {
        error_code = "404"
        response_code = "200"
        response_page_path = "/index.html"
    }

    default_cache_behavior {
        allowed_methods  = ["GET", "HEAD"]
        cached_methods   = ["GET", "HEAD"]
        target_origin_id = local.s3-origin-id-test-static-web-site
        compress         = true
        viewer_protocol_policy = "allow-all"

        forwarded_values {
            query_string = false
            cookies {
                forward = "none"
            }
        }
    }

    restrictions {
        geo_restriction {
            restriction_type = "none"
        }
    }
}

# OriginAccessIdentityの作成
resource "aws_cloudfront_origin_access_identity" "test-static-web-site-idntity" {
    comment = "access-identity-test-static-web-site.s3.amazonaws.com"
}

実行

あとはTerraformを実行することでS3バケット、CloudFront Distributionが出来上がり、外からアクセス出来るようになります。

# 設定内容、更新内容を確認
$ terraform plan

# 問題なければ実行
$ terraform apply

今後同じような構成が増えた時はこの内容を使い回すことですぐに構築することができますね。

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?