在 Cloudflare 后台点几下就能建好一个 Pages 项目、绑好域名。想把这些配置变成可版本化、可复现的代码,就用 OpenTofu 来管理。本文只讲 Cloudflare 场景的具体写法,Provider、Resource、State 这些基础概念见 OpenTofu 入门。

目标

用 OpenTofu 声明式地管理三样东西:

  • 一个连接 GitHub 仓库的 Cloudflare Pages 项目(含构建命令、产物目录、环境变量)
  • 项目绑定的自定义域名
  • 指向 Pages 的 DNS 记录

准备

需要两个 Cloudflare 侧的标识和一个 API Token:

变量 从哪来
Account ID Cloudflare 后台任意页面右侧栏,或 Workers & Pages 概览页
Zone ID 域名的 Overview 页面右侧栏
API Token My Profile → API Tokens → Create Token,授予 Pages 编辑和 DNS 编辑权限

Token 属于机密,不要写进代码,用环境变量注入:

export TF_VAR_cloudflare_api_token="your-token-here"

Provider 配置

terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4"
    }
  }
}

variable "cloudflare_api_token" {
  type      = string
  sensitive = true
}

variable "account_id" {
  type = string
}

variable "zone_id" {
  type = string
}

provider "cloudflare" {
  api_token = var.cloudflare_api_token
}

Pages 项目

cloudflare_pages_project 对应后台的一个 Pages 项目,source 块声明连接哪个 GitHub 仓库,build_config 对应构建命令和产物目录,deployment_configs 里可以设环境变量(例如 HUGO_VERSION)。

resource "cloudflare_pages_project" "blog" {
  account_id        = var.account_id
  name              = "blog"
  production_branch = "main"

  source {
    type = "github"
    config {
      owner             = "wiloon"
      repo_name         = "blog"
      production_branch = "main"
    }
  }

  build_config {
    build_command   = "hugo --minify"
    destination_dir = "public"
  }

  deployment_configs {
    production {
      # keep Cloudflare's Hugo in sync with local
      environment_variables = {
        HUGO_VERSION = "0.159.1"
      }
    }
  }
}

自定义域名与 DNS 记录

cloudflare_pages_domain 把域名挂到 Pages 项目上,cloudflare_record 添加指向项目 pages.dev 子域的 CNAME 记录,proxied = true 让流量走 Cloudflare 的 CDN。

resource "cloudflare_pages_domain" "blog" {
  account_id   = var.account_id
  project_name = cloudflare_pages_project.blog.name
  domain       = "wiloon.com"
}

resource "cloudflare_record" "blog" {
  zone_id = var.zone_id
  name    = "@"
  type    = "CNAME"
  content = cloudflare_pages_project.blog.subdomain
  proxied = true
}

应用

tofu init
tofu plan
tofu apply

tofu plan 会列出将要创建的资源,确认无误后 tofu apply 执行。之后这套 Pages 配置就由 state 文件追踪,改配置改代码、重新 apply 即可,不用再回后台手点。

说明

Cloudflare Provider 的资源名和字段在不同大版本间会有调整(例如 v5 对部分资源做了重命名),实际使用时以所锁定版本的 官方文档 为准。上面的示例基于 v4。