CloudfrontをTerraformで構築

## これは何

CFをTFで構築した時のメモです。あくまでメモなので、仮に参考にされる際には任意で設定を変更ください。
CFはそもそもそんなに構築したこともなく、忘れそうなのでメモ。
TFバージョンは0.12を想定。

## やってみた

```terraform
# CloudFrontの作成　
# オリジン=S3
resource "aws_cloudfront_distribution" "s3_distribution" {

  # 順序
  # CFのデフォルトのドメイン名ではなく、任意のドメインを使用したい場合。
  # その場合、任意のドメインのHosted zoneのAレコード=CFのデフォルトのドメイン　とする。
  # ACMで証明書を発行した場合、DNS検証として、CNAMEを該当のHosted zoneに追加する。
  # ここでは、使用するドメインを書く。
  aliases = ["使用するドメイン"]

  # Errorレスポンス
  custom_error_response {

    # CloudFrontがオリジンにクエリを実行してオブジェクトが更新されているかどうかを確認する前に、
    # HTTPエラーコードをCloudFrontキャッシュに保持する最小時間。
    error_caching_min_ttl = 360 #(任意)

    # 4xx か 5xxを記入。 
    error_code = 500

    # CFがカスタムエラーページとともにビューアに返すHTTPステータスコード。  
    response_code = 200

    # The path of the custom error page (for example,/custom_404.html).
    response_page_path = "/custom_404.html"
  }

  # キャッシュのデフォルト設定。
  default_cache_behavior {

    # CFが処理してAmazonS3バケットまたはカスタムオリジンに転送するHTTPメソッドを制御。
    allowed_methods = ["HEAD", "OPTIONS", "GET", "PUT", "POST", "DELETE", "PATCH"]

    # CFが指定されたHTTPメソッドを使用してリクエストへのレスポンスをキャッシュするかどうかを制御。
    cached_methods = ["HEAD", "OPTIONS", "GET"]

    # CFで、リクエストヘッダーにAccept-Encoding：gzip(高速化)を含むWebリクエストのコンテンツを自動的に圧縮するかどうか（デフォルト：false）。
    compress = true

    # Cache-Control or Expires がリクエストのヘッダーに無い時のデフォルトのTTL。
    # Cache-Control max-ageまたはExpiresヘッダーがない場合に、
    # CFが別のリクエストを転送する前に、オブジェクトがCloudFrontキャッシュにあるデフォルトの時間（秒単位）。1日=86400秒。
    default_ttl = 86400

    # CloudFrontが別のリクエストをオリジンに転送してオブジェクトが更新されているかどうかを判断する前に、
    # オブジェクトがCloudFrontキャッシュにある最大時間（秒単位）。 
    # Cache-Control max-age、Cache-Control s-maxage、およびExpiresヘッダーが存在する場合にのみ有効。  

    # デフォルトの1年を指定。
    max_ttl = 31536000

    # デフォルトの0sを指定。
    min_ttl = 0



    forwarded_values {

      # CloudFrontがこのキャッシュ動作に関連付けられているオリジンにクエリ文字列を転送するかどうか。
      query_string = false

      # CFがCookieを処理する方法を指定するCoo​​kie転送値（最大1つ）。
      cookies {
        # 全てを転送。
        forward = "all"
        # whitelistを設定する場合。
        # whitelisted_names = []
      }
    }

    # オリジン=S3より、リソース名記述。
    target_origin_id = aws_s3_bucket.リソース名.id

    # 署名付きURLを使用してプライベートコンテンツを提供するようにディストリビューションが設定されている場合は、アクティブな信頼できる署名者を記述。
    trusted_signers = []

    # allow-all、https-only、またはredirect-to-https
    viewer_protocol_policy = "redirect-to-https"
  }

  default_root_object = "index.html"

  # Origin Shieldを有効にするか
  enabled = true

  # http1.1 か http2  
  http_version = "http2"

  # アクセスログ設定。for example, myawslogbucket.s3.amazonaws.com.
  logging_config {
    bucket = S3バケットリソース名

    # Cookieもアクセスログに含めるかどうか。
    include_cookies = true

    # 保存時のPrefix
    prefix = "cloudfront/"
  }

  origin {
    domain_name = S3バケットリソース名
    origin_id   = S3バケットリソース名.id

    # Originにアクセスする際のIAM設定。
    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path
    }
  }

  restrictions {

    # 地理的制限
    geo_restriction {

      # none, whitelist, or blacklist
      restriction_type = "none"
      # locations        = [] 
    }
  }

  # SSL証明書の設定。
  viewer_certificate {

    # ACMで作成した証明書を使用するため無効。
    cloudfront_default_certificate = false

    # ARN
    acm_certificate_arn = ""

    # SSLの最小バージョン。
    minimum_protocol_version = "TLSv1.2_2019"

    # SNI(名前ベース)のSSL機能を使用する。
    ssl_support_method = "sni-only"
  }

  # WAFを使用する場合に設定が必要。今回は無効。
  # web_acl_id = ""
}

resource "aws_cloudfront_origin_access_identity" "名前" {
  comment = "適当"
}
```

## 総括

CFはデプロイに15分ほどかかることがあるので、もしお急ぎであれば把握しておくといいかもです。
それにしてもCF、設定項目が多いですね…これで全部ではないという…どこまで詳細に書くかで精度が変わりそう。


## 参考

```
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution
https://katsuya-place.com/terraform-cloudfront/
https://dev.classmethod.jp/articles/static-web-with-cf-s3-tf/
https://qiita.com/natsumisawa/items/404217208ab1c96d8719
```