Cloudflare のリソースを IaC 化する、たったひとつの冴えたやりかたで冴えない結果に終わった話

プロフィール画像

松尾 祐樹

2024年12月08日

リンクをコピーXでシェアするfacebookでシェアする

この記事は「BEMA Lab Advent Calendar 2024Open in new tab」の8日目の記事です。

はじめに

株式会社メンバーズ デプオプスリードカンパニーの松尾です。

こちらはアドベントカレンダー 8 日目の記事です。ちなみに 2024 年の 12 月 8 日は、国立天文台によれば土星食が見えるそうです。
土星食(2024年12月) | 国立天文台(NAOJ)Open in new tab

上弦直前の月が土星を隠す天体イベントだそうなので、観測できる地域の方はこの記事よりも空を見てみてください。

この記事の目的

対して目の前にある穴をどうにかしたいと思っているOpen in new tabエンジニアの皆様、お待たせしました。

この記事では「Cloudflare にあるリソースを IaC 化する、たったひとつの冴えたやりかた」をご紹介します。

IaC とは Infrastructure as Code の略で、インフラをコードとして管理し自動化するために使用されます。
Infrastructure as Code とは - IaC の説明 - AWSOpen in new tab

「Web UI で構築されたインフラがあるけれど、どこに何を設定してるのかが不明瞭…」
「設定内容をまとめた資料を用意したけれど、更新が滞っていてインフラの実態から離れてしまっている…」

こういった課題感がある方に、ぜひ読んでいただければと思います。

利用ツールなどの一覧

筆者が利用している端末は macOS ですが、Windows などをご利用の場合は記事の内容を適宜読み替えていただければ大丈夫です。

なお、この記事では OpenTofu を使用しています。OpenTofu は Terraform からフォークされたオープンソースのツールです。2023 年 8 月 10 日以降、Terraform のライセンスは FAQ サイトが必要なほど複雑な内容になってしまったため、対照的にどなたでも利用しやすい OpenTofu をこの記事では使用します。

HashiCorp Licensing FAQOpen in new tab

各ツールはインストール済みであることを前提に内容を進めさせていただきます。

セッティング手順

認証情報を取得する

まずは IaC ツールで利用するための認証情報を取得しましょう。ここでは有効期間の短い API トークンを取得します。

Account Owned Tokens | Cloudflare Fundamentals docsOpen in new tab

DNS の編集権限をアクセス許可に含めます。

概要の画面で表示される設定内容に問題がなければ、ガイドに従ってトークンを作成します。

cf-vault で認証情報を設定する

次に作成したトークンを使って cf-vault にプロファイルを作成し、環境変数に格納しましょう。
cf-vault の Getting started の手順を追います。

​​https://github.com/jacobbednarz/cf-vault/?tab=readme-ov-file#getting-startedOpen in new tab

$ cf-vault add [your-profile-name]
$ cf-vault add [your-profile-name]
$ cf-vault exec [your-profile-name]
$ cf-vault exec [your-profile-name]

認証情報は問題なく設定できているようです。

Terraform Provider を設定する

続いて作成した任意のディレクトリで provider.tf を用意し、 tofu init を実行して Terraform Provider を設定します。

1 – Initialize TerraformOpen in new tab

$ cat > provider.tf <<'EOF'
terraform {
  required_providers {
    cloudflare = {
      source = "registry.terraform.io/cloudflare/cloudflare"
      version = "~> 4"
    }
  }
}
EOF

※ OpenTofu をご利用の場合は registry.terraform.io/Open in new tab が必須です

ゾーン ID を設定する

DNS のインポートを伴うため、cf-terraforming の実行前にゾーン ID を設定しておく必要があります。

Find zone and account IDs | Cloudflare Fundamentals docsOpen in new tab

Cloudflare のドメインの概要画面で、右下の方に「API」という項目があります。ここからゾーン ID をコピーしてください。

コピーしたら、 CLOUDFLARE_ZONE_ID として環境変数に追加します。

リソースをインポート

冒頭で「たったひとつの冴えたやりかた」をご紹介すると書きましたが、これは既存の Cloudflare リソースの IaC 化を手助けしてくれる公式ツールが存在しているからです。

ここではその公式ツールである cf-terraforming を使用し、既存のリソースをインポートする手順をご紹介します。

リソースを tf ファイルにインポートする

以下のコマンドで importing_records.tf ファイルを作成しましょう。

Import Cloudflare resources - TerraformOpen in new tab

$ 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 - TerraformOpen in new tab

$ 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 化を阻まれましたが、移行時の雰囲気を掴むことはできたのではないでしょうか。

この記事があなたのエンジニアライフのお役に立てば幸いです。

この記事を書いた人

松尾 祐樹
松尾 祐樹
2023 年にメンバーズへ新卒入社。研修期間中は社内コミュニケーションツールのバックエンド開発を担い、常駐先では半年で 3 つの Web アプリケーションを構築した。一方、現場におけるインフラについての課題を感じ続けてきたため、デプオプスリードカンパニーへ異動。現在も試行錯誤しながら案件参画中。
ページトップへ戻る