📝

Cloudflare Registrarで購入したドメインをVercelへ繋げるためにterraformで行ったメモ

2024/02/12に公開

はじめに

とある知人のWebサイトを構築することになり「まぁせっかくCloudflareでドメイン購入したし、terraform勉強がてら構築してみよう」ということで構築を始めました。(今まで人任せにしていたので、コピペで構築したりしたことはあるものの、terraform初心者です)
Cloudflareのチュートリアルを参考にしつつ、少しカスタマイズが必要だったので、行った内容を残しておきたいと思います。

API Tokenを発行する

terraformからcloudflare上の構成を変更していくにあたり、APIを利用して行うようなのでまずはトークンを発行しましょう。[My Profile] > [API Tokens]から発行できます。

https://dash.cloudflare.com/profile/api-tokens

権限などの設定はこちらのように行いました。

もう少し範囲を絞れそうな感じはありつつも、zoneはAll zonesにしたり広めの設定を行っています🙏

各種権限について

設定した権限について少しだけ補足です。

DNS:Edit

zoneにまつわるDNS Recordの設定のため、こちらの権限が必要となっています。

Zone Settings:Edit

後述しますが、今回は SSL/TLS encryption mode を設定したかっただけなのでなんか権限の範囲が広そうですが、こちらの権限を設定しました。
他にも SSL and Certification というPermissionもそれっぽいなぁと思って試してみましたが、残念ながらそれでは動きませんでした。

tfファイルを作成する

本題のtfファイルを作成しましょう。

ほぼチュートリアル通りですが、1ファイルだとなんだか気持ち悪さを感じたので、その後ファイルを分割して私の場合は以下のようになりました。

├── README.md
├── example-com
│   ├── records.tf // DNSレコードに関するresourceの定義
│   ├── required_providers.tf // required_providersを定義
│   └── vars.tf // 各variableの設定
├── .envrc // direnvを使って環境変数を読み込ませているので設置
├── main.tf // moduleを定義

https://gist.github.com/kubio/5c2ff0328a05290ea81583830e248267

ひとまずこれで terraform play / applyを行うとDNSレコードへ追加されるはずです!

補足1. cloudflare api tokenについて

チュートリアル内でも説明がありますが、Cloudflare providerは特定の認証情報の読み込みを環境変数から行ってくれるので、環境変数で CLOUDFLARE_API_TOKENを設定しておくだけで大丈夫です。

補足2. cloudflare_recordへ設定する値について

いきなり以下の値を設定していますが、これは後述のVercel側でカスタムドメインを設定しようとした際に、レコードへの追加を指示される内容になります。

resource "cloudflare_record" "root" {
  zone_id = var.cloudflare_zone_id
  name    = "@"
  value   = "76.76.21.21"
  type    = "A"
  proxied = true
}

resource "cloudflare_record" "www" {
  zone_id = var.cloudflare_zone_id
  name    = "www"
  value   = "cname.vercel-dns.com"
  type    = "CNAME"
  proxied = true
}

ちなみに上記は行わず、Vercel上でドメインを追加だけを行った場合、以下のように表示されると思います。

補足3. SSL/TLS設定について

うっかりrecords.tfへ追加してしまいましたが、SSL/TLSの設定を行っている箇所が以下の部分です。

resource "cloudflare_zone_settings_override" "example-net-zone-settings" {
  zone_id = var.cloudflare_zone_id

  settings {
    tls_1_3                  = "on"
    min_tls_version          = "1.2"
    automatic_https_rewrites = "on"
    ssl                      = "full"
  }
}

デフォルトの設定は以下のようになっていました。

Vercelと繋ぐ際には SSL/TLS encryption modeをfullにする必要があるようです。
https://vercel.com/docs/integrations/cloudflare#set-cloudflare-ssl/tls-encryption-mode

画面上からポチポチすると簡単ですが、うっかり忘れそうですし、せっかくなのでこちらもterraformから設定しました。設定後の画面が以下です。

この後、 SSL/TLS RecommenderもONにしましたが、こちらは手動でONにしました。
(terraform上でどう設定するのか分からなかったので、ご存じの方はぜひ教えて頂けると 🙇‍♂)

SSL/TLS Recommenderについて
https://blog.cloudflare.com/ssl-tls-recommender

よりセキュアにするために行ったほうがよい設定をお知らせしてくれる、というところでしょうか🤔
設定後すぐにSSL/TLS encryption modeFull(strict)へ変更することをオススメされました。
(すまんな、vercelさんがそうしろって書いてるんだ。。)

ディレクトリ構成のベストプラクティスが分からない

がっつり構築したことが無いので悩みつつも、ドメインベースで管理できる方が便利そうだなぁと思ったので、こちらのページを参考に構築しました。

https://qiita.com/tumugin/items/420ff783be392198dc2a

利用するプラットフォームは増えない(増やさない)つもりなのですが、また増えた際には変わるかもしれません。
ルートに各プラットフォーム(GCP, AWS, CF)を設定している方もいらっしゃったし、Hashicorpの記事もあったので、運用しながら直していければなぁと思います。

vercel上でドメインを設定する

では購入したドメインとVercelのプロジェクトを紐づけましょう。(プロジェクトの初期設定やimportなどは割愛)
リポジトリと紐づいたプロジェクトの[Settings]>[Domains]を開き、自前のドメインを追加します。

なんだかモザイクだらけになってしまいましたが、オススメされているので一番上にチェックを入れました。(wwwへリダイレクトしているので、DNSレコードの設定によっては外したほうが良いかもしれません)

その後しばらく待つと検証も終わり、無事アクセスできるようになりました。

その他

途中のモザイクについて

ドメイン自体は見られても問題ないのですが、なんとなく作りかけをご覧頂くのも恥ずかしいので隠してます。
隠し忘れがあってもスルーして頂けると嬉しいです🙇‍♂

途中何度か失敗した

だいたい cloudflare_zone_settings_override でしたが、失敗した後はひとまず以下を実行していればどうにかなる範囲でした。

terraform state list
# resourceを確認
terraform state rm [resource]

direnvについて

便利ですね!!
https://github.com/direnv/direnv

おわりに

Cloudflareのチュートリアルがとても勉強になりました!
チュートリアルに沿って進めてみましたが、各resourceのドキュメントなどは読めていないので、読みつつ必要な設定が漏れてないか確認しないとなぁ。。

参考

構築にあたって以下を参考にしました。
大変参考になりました!ありがとうございました!!

https://developers.cloudflare.com/terraform/tutorial/

https://vercel.com/docs/integrations/cloudflare

https://qiita.com/tumugin/items/420ff783be392198dc2a

https://zenn.dev/keitakn/articles/add-cloudflare-domain-to-vercel

Discussion