Cloudflare Pulumi Provider 资源配置全解:用 @pulumi/cloudflare v6.x 管理 Workers、KV、D1、R2 与 Queues

Cloudflare Pulumi Provider 资源配置全解:用 @pulumi/cloudflare v6.x 管理 Workers、KV、D1、R2 与 Queues Cloudflare Pulumi Provider 资源配置全解用 pulumi/cloudflare v6.x 管理 Workers、KV、D1、R2 与 Queues【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills本文以 skills 仓库中 cloudflare-deploy 技能 的 Pulumi 资源配置参考 为主体系统讲解如何用 TypeScript 编写 Pulumi 程序以 IaC 方式程序化创建 Cloudflare Workers 及其绑定资源。读完本文你将掌握pulumi/cloudflarev6.x 下 WorkerScript、Workers KV、R2、D1、Queues、Pages、DNS、自定义域名、静态资源托管以及 v6.x 版本化部署的完整配置写法并理解 binding 名称匹配、依赖编排与常见排错要点可直接照搬到自己的部署项目中。一、配置之前认证与 Stack 基础configuration.md中的所有资源示例都依赖两个前置事实一个可用的 Cloudflare Provider 实例以及从 stack 配置中读取的accountId。这部分前置配置定义在配套的 pulumi/README.md 中是整个资源配置能够运行的前提。1. 认证方式推荐 API Token官方推荐使用 API Token 而非旧的 API Keyimport * as cloudflare from pulumi/cloudflare; // API Token推荐从 CLOUDFLARE_API_TOKEN 环境变量读取 const provider new cloudflare.Provider(cf, { apiToken: process.env.CLOUDFLARE_API_TOKEN }); // API Key旧式CLOUDFLARE_API_KEY CLOUDFLARE_EMAIL 环境变量 const provider new cloudflare.Provider(cf, { apiKey: process.env.CLOUDFLARE_API_KEY, email: process.env.CLOUDFLARE_EMAIL }); // API User Service KeyCLOUDFLARE_API_USER_SERVICE_KEY 环境变量 const provider new cloudflare.Provider(cf, { apiUserServiceKey: process.env.CLOUDFLARE_API_USER_SERVICE_KEY });2. Stack 配置accountId 与 apiToken 的存放位置在Pulumi.yaml中声明项目与运行时并把 token 交给 Pulumi 配置系统# Pulumi.yaml name: my-cloudflare-app runtime: nodejs config: cloudflare:apiToken: value: ${CLOUDFLARE_API_TOKEN}在每个环境的Pulumi.stack.yaml中存放账号 IDaccountId是绝大多数资源必填的属性# Pulumi.stack.yaml例如 Pulumi.prod.yaml config: cloudflare:accountId: abc123...在入口文件index.ts中通过pulumi.Config读取import * as pulumi from pulumi/pulumi; import * as cloudflare from pulumi/cloudflare; const accountId new pulumi.Config(cloudflare).require(accountId);3. 五项核心原则来自 pulumi/README.md 的 v6.x 使用原则贯穿本文所有示例使用 API Token 而非旧式 API Key将accountId存放在 stack 配置中让 binding 名称在代码与配置之间严格一致Worker 使用module: true声明 ES modules始终设置compatibilityDate锁定运行时行为。二、资源类型总览pulumi/cloudflarev6.x 中本文会涉及的常用资源类型来自 pulumi/README.md资源类型对应 Cloudflare 产品用途Provider——Provider 配置认证WorkerScriptWorkers部署 Worker 脚本WorkersKvNamespaceWorkers KV键值存储命名空间R2BucketR2对象存储桶D1DatabaseD1关系型 SQL 数据库QueueQueues消息队列PagesProjectPages全栈站点项目DnsRecordDNSDNS 记录WorkerRouteWorkers Routes基于 pattern 的路由WorkersDomainWorkers Custom Domains专属子域名关键公共属性accountId多数资源必填、zoneIdDNS/域名必填、name/title资源标识符、*Bindings将资源连接到 Worker 的绑定族。三、Workerscloudflare.WorkerScript 的完整配置WorkerScript是部署 Worker 的核心资源configuration.md给出的完整示例覆盖了从模块格式、兼容性配置到可观测性、Placement 与全部绑定类型import * as cloudflare from pulumi/cloudflare; import * as fs from fs; const worker new cloudflare.WorkerScript(my-worker, { accountId: accountId, name: my-worker, content: fs.readFileSync(./dist/worker.js, utf8), module: true, // ES modules compatibilityDate: 2025-01-01, compatibilityFlags: [nodejs_compat], // v6.x: Observability logpush: true, // 启用 Workers Logpush tailConsumers: [{service: log-consumer}], // 将日志流式转发给另一个 Worker // v6.x: Placement placement: {mode: smart}, // Smart Placement 优化延迟 // Bindings kvNamespaceBindings: [{name: MY_KV, namespaceId: kv.id}], r2BucketBindings: [{name: MY_BUCKET, bucketName: bucket.name}], d1DatabaseBindings: [{name: DB, databaseId: db.id}], queueBindings: [{name: MY_QUEUE, queue: queue.id}], serviceBindings: [{name: OTHER_SERVICE, service: other.name}], plainTextBindings: [{name: ENV_VAR, text: value}], secretTextBindings: [{name: API_KEY, text: secret}], // v6.x: Advanced bindings analyticsEngineBindings: [{name: ANALYTICS, dataset: my-dataset}], browserBinding: {name: BROWSER}, // Browser Rendering aiBinding: {name: AI}, // Workers AI hyperdriveBindings: [{name: HYPERDRIVE, id: hyperdriveConfig.id}], });关键参数逐项说明contentWorker 代码内容直接读取构建产物如./dist/worker.js。这里有一个重要前提——Pulumi 不会帮你打包/bundle 代码它只上传你提供的内容。这一点在 pulumi/gotchas.md 中有明确警告如果直接读取原始index.ts而非构建后的 JSWorker 会报Cannot use import statement outside a module。正确做法是先构建再部署详见下文实战编排小节。module: true声明 Worker 使用 ES modules 格式对应的compatibilityFlags: [nodejs_compat]开启 Node.js 兼容层便于使用node:*模块。compatibilityDate锁定 Worker 运行时的兼容性日期防止 Cloudflare 侧行为变更造成破坏是官方推荐必须设置的值。logpush/tailConsumersv6.x Observabilitylogpush: true启用 Workers Logpush 把日志推送到外部tailConsumers则把实时日志流式转发给另一个 Workerservice指向其名称适合日志消费/观测场景。placement: {mode: smart}v6.x开启 Smart Placement让 Worker 就近后端源站运行以优化延迟。绑定Bindings族连接 KV / R2 / D1 / Queue / Service / 环境变量 / 密钥 / Analytics Engine / Browser Rendering / Workers AI / Hyperdrive。绑定名称如MY_KV、API_KEY会注入 Worker 运行时的env对象中。绑定名称必须精确匹配gotchas.md 强调绑定名称区分大小写Pulumi 侧的name必须与 Worker 代码中env的引用完全一致否则运行时会报env.MY_KV is undefined// Pulumi 侧 kvNamespaceBindings: [{name: MY_KV, namespaceId: kv.id}]// Worker 代码侧 export default { async fetch(request, env) { await env.MY_KV.get(key); }}四、Workers KV命名空间与键值写入KV 由命名空间namespace与具体的键值value两层组成const kv new cloudflare.WorkersKvNamespace(my-kv, { accountId: accountId, title: my-kv-namespace, }); // 写入值 const kvValue new cloudflare.WorkersKvValue(config, { accountId: accountId, namespaceId: kv.id, key: config, value: JSON.stringify({foo: bar}), });注意 KV 命名空间的资源标识字段是title而非name创建后通过kv.id引用WorkersKvValue允许在 IaC 阶段就把初始化数据如配置 JSON写入命名空间适合会话、缓存、配置类数据。五、R2 Buckets对象存储const bucket new cloudflare.R2Bucket(my-bucket, { accountId: accountId, name: my-bucket, location: auto, // 或 wnam 等地域标识 });location: auto表示由 Cloudflare 自动选择存储地域需要固定地域时可按供应商文档指定如wnam西美等取值。创建后用bucket.name注入 Worker 的r2BucketBindings。六、D1 数据库与迁移编排创建 D1 数据库后Pulumi不会自动执行迁移。configuration.md给出的标准做法是结合pulumi/command的command.local.Command资源在数据库创建完成后用 wrangler CLI 执行 SQLconst db new cloudflare.D1Database(my-db, {accountId, name: my-database}); // 通过 wrangler 执行迁移 import * as command from pulumi/command; const migration new command.local.Command(d1-migration, { create: pulumi.interpolatewrangler d1 execute ${db.name} --file ./schema.sql, }, {dependsOn: [db]});dependsOn: [db]显式声明依赖确保数据库先创建、迁移后执行。同理如果 Worker 依赖迁移完成后的表结构应让 Worker 的d1DatabaseBindings所在资源dependsOn: [migration]详见 pulumi/api.md 的显式依赖示例。七、Queues生产者与消费者配置队列由Queue资源定义生产者通过queueBindings写入消费者通过queueConsumers订阅const queue new cloudflare.Queue(my-queue, {accountId, name: my-queue}); // Producer把消息写入队列 const producer new cloudflare.WorkerScript(producer, { accountId, name: producer, content: code, queueBindings: [{name: MY_QUEUE, queue: queue.id}], }); // Consumer异步消费 const consumer new cloudflare.WorkerScript(consumer, { accountId, name: consumer, content: code, queueConsumers: [{queue: queue.name, maxBatchSize: 10, maxRetries: 3}], });消费者侧可配置的关键参数maxBatchSize单批最大消息数示例为 10、maxRetries最大重试次数示例为 3在 patterns.md 的队列处理模式中还出现了maxWaitTimeMs: 5000最长批量等待时间。这一配置直接支撑API 接收请求 → 队列削峰 → Worker 异步处理的典型架构。八、Pages Projects全栈站点配置PagesProject支持 Git 源自动构建与生产环境配置注入const pages new cloudflare.PagesProject(my-site, { accountId, name: my-site, productionBranch: main, buildConfig: {buildCommand: npm run build, destinationDir: dist}, source: { type: github, config: {owner: my-org, repoName: my-repo, productionBranch: main}, }, deploymentConfigs: { production: { environmentVariables: {NODE_VERSION: 18}, kvNamespaces: {MY_KV: kv.id}, d1Databases: {DB: db.id}, }, }, });要点拆解buildConfig声明构建命令buildCommand与产物目录destinationDir对应 Pages 的构建配置source关联 GitHub 仓库type: github 仓库所有者的config配置后 Pages 支持 Git 触发自动部署deploymentConfigs.production为生产环境注入环境变量NODE_VERSION等以及把 KV、D1 等资源绑定到 Pages 运行时其中键如MY_KV、DB就是 Pages Functions 侧引用的绑定名。九、DNS RecordsZone 数据源与记录创建需要先通过cloudflare.getZone数据源查询目标域名对应的 zone再创建记录const zone cloudflare.getZone({name: example.com}); const record new cloudflare.DnsRecord(www, { zoneId: zone.then(z z.id), name: www, type: A, content: 192.0.2.1, ttl: 3600, proxied: true, });zoneId通过getZone数据源异步获取zone.then(z z.id)拿到 Output 值type/content/ttl记录类型、解析值、TTL秒3600 为 1 小时proxied: true开启 Cloudflare 代理橙色云朵流量先经过 Cloudflare 边缘。十、Workers Domains 与 Routes流量接入的两种方式把 Worker 暴露到域名有两种方式按需选择// 方式一Route基于 pattern 的路由作用于 Zone 内路径 const route new cloudflare.WorkerRoute(my-route, { zoneId: zoneId, pattern: example.com/api/*, scriptName: worker.name, }); // 方式二Domain专属子域名 const domain new cloudflare.WorkersDomain(my-domain, { accountId: accountId, hostname: api.example.com, service: worker.name, zoneId: zoneId, });WorkerRoute把某个域名下的路径模式example.com/api/*路由到指定 WorkerscriptName引用 Worker 的nameWorkersDomain为 Worker 分配专属子域名hostnameservice指定 Worker 名称需要accountId与zoneId同时提供。十一、Assets 静态资源配置v6.xv6.x 允许 Worker 直接托管本地静态资源目录无需单独的对象存储const worker new cloudflare.WorkerScript(app, { accountId: accountId, name: my-app, content: code, assets: { path: ./public, // 本地目录上传后由 Workers 直接托管 }, });assets.path指向本地静态目录如构建后的前端产物./publicCloudflare 会将其中文件作为 Worker 的静态资源上传并服务适合单仓库同时交付 API 与前端静态文件的场景。十二、v6.x 版本化部署三资源模式v6.x 引入了 Worker 版本化机制。configuration.md给出的高级模式由三个资源协作实现渐进式发布// 1. Worker作为版本的容器 const worker new cloudflare.Worker(api, { accountId: accountId, name: api-worker, }); // 2. Version不可变的代码 配置 const version new cloudflare.WorkerVersion(v1, { accountId: accountId, workerId: worker.id, content: fs.readFileSync(./dist/worker.js, utf8), compatibilityDate: 2025-01-01, compatibilityFlags: [nodejs_compat], // 注意Bindings 在 Deployment 层配置 }); // 3. Deployment版本 绑定 流量分配 const deployment new cloudflare.WorkersDeployment(prod, { accountId: accountId, workerId: worker.id, versionId: version.id, // Bindings 作用于 Deployment kvNamespaceBindings: [{name: MY_KV, namespaceId: kv.id}], });适用场景蓝绿部署blue-green、金丝雀发布canary、渐进式灰度gradual rollout。结合 patterns.md 的示例WorkersDeployment还可以通过versions数组按百分比切流// 渐进式发布10% 流量到 v290% 到 v1 const deployment new cloudflare.WorkersDeployment(canary, { accountId, workerId: worker.id, versions: [{versionId: v2.id, percentage: 10}, {versionId: v1.id, percentage: 90}], kvNamespaceBindings: [{name: MY_KV, namespaceId: kv.id}], });不适用场景简单的单版本部署——此时应直接使用WorkerScript自带自动版本管理是绝大多数应用的默认选择。gotchas.md 特别提醒如果创建了WorkerWorkerVersionWorkersDeployment但流量没有打到 Worker往往是三资源链路不完整导致简单场景务必回到WorkerScript。十三、实战编排一个完整全栈应用的资源依赖把以上资源串起来参考 patterns.md 的 Full-Stack 模式一个带 KV 缓存、D1 数据库、R2 对象存储的 API Worker 的完整编排如下const kv new cloudflare.WorkersKvNamespace(cache, {accountId, title: api-cache}); const db new cloudflare.D1Database(db, {accountId, name: app-database}); const bucket new cloudflare.R2Bucket(assets, {accountId, name: app-assets}); const apiWorker new cloudflare.WorkerScript(api, { accountId, name: api-worker, content: fs.readFileSync(./dist/api.js, utf8), module: true, kvNamespaceBindings: [{name: CACHE, namespaceId: kv.id}], d1DatabaseBindings: [{name: DB, databaseId: db.id}], r2BucketBindings: [{name: ASSETS, bucketName: bucket.name}], });这里的依赖是隐式的kv.id、db.id、bucket.name作为 Input 传入绑定后Pulumi 自动建立Worker 依赖这三个资源的关系详见 api.md 的隐式依赖说明无需手写dependsOn。另外两种与构建/部署强相关的编排模式先构建后部署解决 Pulumi 不打包的问题import * as command from pulumi/command; const build new command.local.Command(build, {create: npm run build, dir: ./worker}); const worker new cloudflare.WorkerScript(worker, { accountId, name: my-worker, content: build.stdout.apply(() fs.readFileSync(./worker/dist/index.js, utf8)), }, {dependsOn: [build]});内容版本强制刷新解决内容哈希未变导致误判无变更的问题const version Date.now().toString(); const worker new cloudflare.WorkerScript(worker, { accountId, name: my-worker, content: code, plainTextBindings: [{name: VERSION, text: version}], // 强制触发新部署 });gotchas.md 记录了此类问题的成因当代码仅有空白/注释级别的变化时内容哈希相同Pulumi 会误判no changes注入时间戳版本的plainTextBindings是推荐的规避手段。十四、配置相关的常见错误速查来自 pulumi/gotchas.md与本文配置内容直接相关的几类高频问题报错/现象根因解法Error: Missing required property accountId资源未提供 accountId在Pulumi.stack.yaml中添加cloudflare:accountIdenv.MY_KV is undefinedPulumi 绑定名与 Worker 代码不一致严格按大小写对齐绑定名Cannot use import statement outside a modulePulumi 直接上传了未构建的 TS 源码先npm run build再用command.local.Command驱动部署本地wrangler dev正常但pulumi up失败Pulumi 不读取wrangler.toml将 Pulumi 配置导出生成wrangler.toml保持单一事实源D1 建库后 schema 未生效Pulumi 只建库不跑迁移用command.local.CommanddependsOn执行wrangler d1 execute代码改了但 Pulumi 显示 no changes内容哈希未变注入VERSION时间戳绑定强制更新认证报错authentication error (10000)Token 权限不足授予Account.Workers Scripts:Edit、Account.Account Settings:Read等权限推荐的最佳实践归纳始终设置compatibilityDate构建先于部署绑定名大小写精确匹配迁移用dependsOn串行敏感信息通过pulumi config set --secret存入 stack 配置在 state 中加密存储见 api.md 的 Secrets 管理。十五、延伸阅读本技能入口与决策树cloudflare-deploy/SKILL.md我需要基础设施即代码分支指向本参考Pulumi 参考整体导读与认证/Stack 配置pulumi/README.md输出、依赖、导入与密钥管理pulumi/api.md多环境、组件化资源、队列与微服务架构模式pulumi/patterns.md排错与最佳实践pulumi/gotchas.md相关替代方案Terraform 参考 terraform/、CLI 部署参考 wrangler/、绑定体系 bindings/、Worker 运行时 workers/【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考