Cloudflare のリソースを IaC 化する、たったひとつの冴えたやりかたで冴えない結果に終わった話
この記事は「BEMA Lab Advent Calendar 2024」の8日目の記事です。
はじめに
株式会社メンバーズ デプオプスリードカンパニーの松尾です。
こちらはアドベントカレンダー 8 日目の記事です。ちなみに 2024 年の 12 月 8 日は、国立天文台によれば土星食が見えるそうです。
土星食(2024年12月) | 国立天文台(NAOJ)
上弦直前の月が土星を隠す天体イベントだそうなので、観測できる地域の方はこの記事よりも空を見てみてください。
この記事の目的
対して目の前にある穴をどうにかしたいと思っているエンジニアの皆様、お待たせしました。
この記事では「Cloudflare にあるリソースを IaC 化する、たったひとつの冴えたやりかた」をご紹介します。
IaC とは Infrastructure as Code の略で、インフラをコードとして管理し自動化するために使用されます。
Infrastructure as Code とは - IaC の説明 - AWS
「Web UI で構築されたインフラがあるけれど、どこに何を設定してるのかが不明瞭…」
「設定内容をまとめた資料を用意したけれど、更新が滞っていてインフラの実態から離れてしまっている…」
こういった課題感がある方に、ぜひ読んでいただければと思います。
利用ツールなどの一覧
筆者が利用している端末は macOS ですが、Windows などをご利用の場合は記事の内容を適宜読み替えていただければ大丈夫です。
なお、この記事では OpenTofu を使用しています。OpenTofu は Terraform からフォークされたオープンソースのツールです。2023 年 8 月 10 日以降、Terraform のライセンスは FAQ サイトが必要なほど複雑な内容になってしまったため、対照的にどなたでも利用しやすい OpenTofu をこの記事では使用します。
- OpenTofu
・オープンソースの IaC ツール
・https://opentofu.org/docs/intro/ - cf-terraforming
・既存の Cloudflare リソースの IaC 化を手助けしてくれる公式ツール
- cf-vault
・Cloudflare の認証情報を安全に管理するためのツール
・GitHub - jacobbednarz/cf-vault: Manage your Cloudflare credentials, securely
- Cloudflare
・既存のリソースがある管理対象
・ここでは DNS レコードの管理を IaC 化することをゴールとします
各ツールはインストール済みであることを前提に内容を進めさせていただきます。
セッティング手順
認証情報を取得する
まずは IaC ツールで利用するための認証情報を取得しましょう。ここでは有効期間の短い API トークンを取得します。
Account Owned Tokens | Cloudflare Fundamentals docs
DNS の編集権限をアクセス許可に含めます。

概要の画面で表示される設定内容に問題がなければ、ガイドに従ってトークンを作成します。
cf-vault で認証情報を設定する
次に作成したトークンを使って cf-vault にプロファイルを作成し、環境変数に格納しましょう。
cf-vault の Getting started の手順を追います。
https://github.com/jacobbednarz/cf-vault/?tab=readme-ov-file#getting-started
![$ cf-vault add [your-profile-name]](https://images.microcms-assets.io/assets/0b7e26d405ac43a2bb794b29dd552427/6aaf802ed8ac4e72a6426db4da7524c6/image4.png?fm=webp)
![$ cf-vault exec [your-profile-name]](https://images.microcms-assets.io/assets/0b7e26d405ac43a2bb794b29dd552427/0c62cd4d74ae44549383c4d4c2d652e7/image6.png?fm=webp)
認証情報は問題なく設定できているようです。
Terraform Provider を設定する
続いて作成した任意のディレクトリで provider.tf を用意し、 tofu init を実行して Terraform Provider を設定します。
$ cat > provider.tf <<'EOF'
terraform {
required_providers {
cloudflare = {
source = "registry.terraform.io/cloudflare/cloudflare"
version = "~> 4"
}
}
}
EOF
※ OpenTofu をご利用の場合は registry.terraform.io/ が必須です
ゾーン ID を設定する
DNS のインポートを伴うため、cf-terraforming の実行前にゾーン ID を設定しておく必要があります。
Find zone and account IDs | Cloudflare Fundamentals docs
Cloudflare のドメインの概要画面で、右下の方に「API」という項目があります。ここからゾーン ID をコピーしてください。

コピーしたら、 CLOUDFLARE_ZONE_ID として環境変数に追加します。
リソースをインポート
冒頭で「たったひとつの冴えたやりかた」をご紹介すると書きましたが、これは既存の Cloudflare リソースの IaC 化を手助けしてくれる公式ツールが存在しているからです。
ここではその公式ツールである cf-terraforming を使用し、既存のリソースをインポートする手順をご紹介します。
リソースを tf ファイルにインポートする
以下のコマンドで importing_records.tf ファイルを作成しましょう。
Import Cloudflare resources - Terraform
$ cf-terraforming generate \
--resource-type "cloudflare_record" \
--zone $CLOUDFLARE_ZONE_ID > importing_records.tf
importing_records.tf を確認してみると、以下のような Terraform のリソースがインポートされています。
terraform
resource "cloudflare_record" "terraform_managed_resource_~~~~~~~~~~~~~~~~~~~~" {
content = "~~~~~.pages.dev"
name = "example.com"
proxied = true
ttl = 1
type = "CNAME"
zone_id = "~~~~~~~~~~~~~~~~~~~~~~"
}
リソースの ”状態” をインポート
こうして cf-terraforming generate を実行し、IaC 化は達成されました。と言いたいところですが、このインポートされたコードと実際のインフラの状態は一致していません。
plan コマンドを実行すると、add として表示されます。
Plan: 12 to add, 0 to change, 0 to destroy.
このギャップを埋めるため、実際のインフラの状態を .tfstate ファイルとしてインポートします。
リソースごとのコマンドを表示する
cf-terraforming import を実行することで、 .tfstate の作成に必要な terraform import コマンドを表示します。
Import Cloudflare resources - Terraform
$ cf-terraforming import \
--resource-type "cloudflare_record" \
--zone $CLOUDFLARE_ZONE_ID
前のコマンドを使いまわす際、出力をリダイレクトせず標準出力に戻すことをお忘れなく…。

import コマンドを実行する
先ほど表示されたコマンドを全て実行します。 tofu ユーザの方は alias を一時的に設定しておくと楽です。
実行後に改めて plan コマンドを実行すると change だけになっていることが確認できます。
Plan: 0 to add, 12 to change, 0 to destroy.
今回のオチ
せっかくなので apply も実行してみたところ、概ね Modifications complete したのですが、次のようなエラーも出力されました。
│ Error: failed to create DNS record: This record is managed by Email Routing. Disable Email Routing to modify/remove this record. (1046)
メール転送サービスとして使っている Email Routing が管理するレコードまでは操作できなかったようです。
個人的な事情で Email Routing を無効化することは難しいため、筆者の環境では完全に IaC 化することは諦めないといけないかもしれません。
おわりに
この記事では画面操作とおさらばし、IaC 化によってコードベースの管理による自動化を目指しました。
結果としては使用している DNS 以外のリソース「Email Routing」の制約によって IaC 化を阻まれましたが、移行時の雰囲気を掴むことはできたのではないでしょうか。
この記事があなたのエンジニアライフのお役に立てば幸いです。
この記事を書いた人
.jpg)
What is BEMA!?
Be Engineer, More Agile
Advent Calendar!
Advent Calendar 2024