Herokuでカスタムドメイン(ルートドメイン)を使うためにCloudFrontを設定する

Route53で取得したカスタムドメインをHerokuで使うためにCloudFrontの設定をしたのでブログに書いておく。

コード例は foo.herokuapp.com で動くアプリケーションを foo-example.com でアクセスできるようにする設定です。

AWS側の設定

  • CloudFrontで使うacmはvirginiaで作成
  • ttlは0にしてキャッシュしない
    • /assets/packs はキャッシュした方が良いけど、まだ未対応
locals {
  foo_domain    = "foo-example.com"
  foo_origin_id = "foo-heroku"
}

module "acm" {
  source  = "terraform-aws-modules/acm/aws"
  version = "2.12.0"

  providers = {
    aws = aws.virginia
  }

  domain_name = local.foo_domain
  zone_id     = aws_route53_zone.main.zone_id
}

resource "aws_cloudfront_distribution" "foo" {
  enabled         = true
  is_ipv6_enabled = true
  aliases         = [local.foo_domain]

  origin {
    domain_name = "foo.herokuapp.com"
    origin_id   = local.foo_origin_id

    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "https-only"
      origin_ssl_protocols   = ["TLSv1", "TLSv1.1", "TLSv1.2"]
    }
  }

  default_cache_behavior {
    target_origin_id       = local.foo_origin_id
    allowed_methods        = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
    cached_methods         = ["GET", "HEAD"]
    compress               = true
    default_ttl            = 0
    max_ttl                = 0
    viewer_protocol_policy = "redirect-to-https"

    forwarded_values {
      headers      = ["*"]
      query_string = true

      cookies {
        forward = "all"
      }
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    acm_certificate_arn      = module.acm.this_acm_certificate_arn
    minimum_protocol_version = "TLSv1.2_2019"
    ssl_support_method       = "sni-only"
  }
}

Heroku側の設定

カスタムドメインを登録しておく。

$ heroku domains:add foo-example.com