Cloudflare の DNS を Terraform で管理してみた

2023/07/03に公開

はじめに

弊社では AWS を中心にシステム開発を行っており、DNS については Amazon Route 53 を利用しています。
今回は新たに Cloudflare の DNS を試すことにチャレンジしてみました。

AWS 上の環境構築作業は IaC を活用しており、CloudFormation や CDK を主に利用しています。
Cloudflare で IaC を行う場合は、Terraform を利用するのが一般的なようです。
そこで、Cloudflare の DNS のレコード設定を Terraform で管理し、動作するところまで試してみました。

Terraform で Cloudflare の DNS を管理する

前提

クライアント環境

クライアントには macOS を使用し Homebrew を利用してパッケージ管理をしております。
今回試した環境は以下の通りです。

  • macOS 13.2.1
  • Homebrew 4.0.26

Cloudflare

アカウント作成とドメイン登録

Cloudflare のアカウントを取得し、 Web サイト メニューの サイトを追加 からドメインを登録します。
追加したドメインの 概要 に表示されるゾーン ID をメモしておきます。

API トークン発行

Cloudflare の API トークンを発行します。
「マイ プロフィール」メニューの API トークン から トークンの作成 を選択します。

今回は DNS を編集したいので「ゾーン DNS を編集する」より テンプレートを使用する を選択し、「ゾーン リソース」は すべてのゾーン を包含しておきます。

その後、トークンを作成する で表示されるトークンを環境変数に保存します。

$ export CLOUDFLARE_API_TOKEN='xxxxxxxxx'

Terraform

インストール

まずは Terraform のバージョンマネージャーの tfenv をインストールしました。

$ brew install tfenv

利用できる Terraform のバージョンを確認します。

$ tfenv list-remote
1.5.2
1.5.1
1.5.0

2023/06/30 時点で最新バージョンの 1.5.2 を利用することにします。

$ tfenv install 1.5.2
$ tfenv use 1.5.2

これで terraform コマンドが利用できるようになりました。

$ terraform -v
Terraform v1.5.2
on darwin_arm64

プロバイダーの定義

今回は Cloudflare を利用するのでその定義を行います。
適当なディレクトリを準備してその中で provider.tf というファイルを作成し、以下の内容を記述します。

# provider.tf
terraform {
  required_providers {
    cloudflare = {
      source = "cloudflare/cloudflare"
      version = "~> 3.0"
    }
  }
}
provider "cloudflare" {}

初期化

terraform init コマンドを実行することで、プロバイダーのインストールやバージョンの確認を行います。

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding cloudflare/cloudflare versions matching "~> 3.0"...
- Installing cloudflare/cloudflare v3.35.0...
- Installed cloudflare/cloudflare v3.35.0 (self-signed, key ID C9999999999999)
<>
Terraform has been successfully initialized!
<>

successfully と表示されているので問題なく初期化できたようです。

DNS レコードファイル作成

records.tf というファイルを作成し、追加する DNS レコードを記述します。

今回は、dev というサブドメインに Amazon CloudFront の CNAME レコードを追加することにします。
ゾーン ID には、前述の Cloudflare のドメイン登録時にメモした値を利用します。

resource "cloudflare_record" "dev" {
  name    = "dev"                           # サブドメイン名
  proxied = true                            # Cloudflare のプロキシを利用するか
  ttl     = 1                               # TTL
  type    = "CNAME"                         # レコードタイプ
  value   = "xxxxx.cloudfront.net"          # CloudFront を想定した値
  zone_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # Cloudflare のゾーン ID
}

変更内容の確認

terraform plan コマンドを利用することにより、ドライランを行います。
1レコード追加されることが確認できました。

$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # cloudflare_record.dev will be created
  + resource "cloudflare_record" "dev" {
      + allow_overwrite = false
      + created_on      = (known after apply)
      + hostname        = (known after apply)
      + id              = (known after apply)
      + metadata        = (known after apply)
      + modified_on     = (known after apply)
      + name            = "dev"
      + proxiable       = (known after apply)
      + proxied         = true
      + ttl             = 1
      + type            = "CNAME"
      + value           = "xxxxxx.cloudfront.net"
      + zone_id         = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }

Plan: 1 to add, 0 to change, 0 to destroy.
<>

レコード追加の実行

terraform apply コマンドを利用することで、実際にレコード追加を行います。
Enter a value: と聞かれるので yes と入力することにより、DNS レコードが追加されました。

$ terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # cloudflare_record.dev will be created
  + resource "cloudflare_record" "dev" {
      + allow_overwrite = false
      + created_on      = (known after apply)
      + hostname        = (known after apply)
      + id              = (known after apply)
      + metadata        = (known after apply)
      + modified_on     = (known after apply)
      + name            = "dev"
      + proxiable       = (known after apply)
      + proxied         = true
      + ttl             = 1
      + type            = "CNAME"
      + value           = "xxxxxx.cloudfront.net"
      + zone_id         = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

cloudflare_record.dev: Creating...
cloudflare_record.dev: Creation complete after 1s [id=xxxxxxxxxxxxxxxxxx]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Cloudflare Terraforming

cf-terraforming は既存の Cloudflare リソースの terraforming を容易にするコマンドラインユーティリティです。
このツールを利用することで、既存の Cloudflare リソースを Terraform のコードとして出力することができます。
必須ではありませんが Cloudflare を Terraform で管理するときに、あわせて利用すると便利そうです。

$ brew tap cloudflare/cloudflare
$ brew install --cask cloudflare/cloudflare/cf-terraforming

さいごに

今回は、Cloudflare の DNS を Terraform で管理するところまで試してみました。
なお筆者は Terraform の経験が全くなかったため、まずは動作することまでを目標とし、その内容を記載しております。
ご指摘等がありましたらコメント頂けますと幸いです。

モリサワ Tech Blog

Discussion