From 14e31473be826c5655f248b5dceb539e21d031ee Mon Sep 17 00:00:00 2001 From: Thomas Gauvin Date: Fri, 20 Feb 2026 13:59:50 -0800 Subject: [PATCH 1/4] add workers vpc terraform to docs --- .../index.mdx} | 1 + .../configuration/vpc-services/terraform.mdx | 196 ++++++++++++++++++ .../platform/infrastructure-as-code.mdx | 25 +++ 3 files changed, 222 insertions(+) rename src/content/docs/workers-vpc/configuration/{vpc-services.mdx => vpc-services/index.mdx} (97%) create mode 100644 src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx diff --git a/src/content/docs/workers-vpc/configuration/vpc-services.mdx b/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx similarity index 97% rename from src/content/docs/workers-vpc/configuration/vpc-services.mdx rename to src/content/docs/workers-vpc/configuration/vpc-services/index.mdx index 0d5e7cca73df2d9..f2a1c0585f15a46 100644 --- a/src/content/docs/workers-vpc/configuration/vpc-services.mdx +++ b/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx @@ -165,6 +165,7 @@ You can have multiple VPC service bindings: ## Next steps +- [Configure VPC Services with Terraform](/workers-vpc/configuration/vpc-services/terraform/) for managing VPC Services as infrastructure - Set up [Cloudflare Tunnel](/workers-vpc/configuration/tunnel/) for your environment - Learn about the [Service Binding API](/workers-vpc/api/) - Refer to [examples](/workers-vpc/examples/) of common use cases diff --git a/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx b/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx new file mode 100644 index 000000000000000..6e9ef1c50a39395 --- /dev/null +++ b/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx @@ -0,0 +1,196 @@ +--- +title: Configure with Terraform +pcx_content_type: concept +sidebar: + order: 2 +--- + +VPC Services can be managed as infrastructure using the [`cloudflare_connectivity_directory_service`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/connectivity_directory_service) resource in the [Cloudflare Terraform provider](/terraform/). + +This maps directly to the [connectivity directory](/api/resources/connectivity/subresources/directory/subresources/services/) — the underlying API that the dashboard and Wrangler CLI also use to create and manage VPC Services. The same [VPC Service configuration fields](/workers-vpc/configuration/vpc-services/#vpc-service-configuration) (type, host, ports, tunnel ID) apply regardless of how the service is created. + +:::note + +Requires Cloudflare Terraform provider v5.13.0 or later. + +::: + +## VPC Service resource + +The `cloudflare_connectivity_directory_service` resource creates a VPC Service in the connectivity directory. Each resource corresponds to one VPC Service entry that a Worker can bind to. + +### Hostname-based configuration + +When using a hostname, provide `host.hostname` with a `resolver_network` block. This parallels the hostname-based [JSON configuration example](/workers-vpc/configuration/vpc-services/#configuration-example). + +```tf +resource "cloudflare_connectivity_directory_service" "my_private_api" { + account_id = var.account_id + name = "my-private-api" + type = "http" + http_port = 80 + https_port = 443 + + host = { + hostname = "internal-api.example.com" + resolver_network = { + tunnel_id = var.tunnel_id + } + } +} +``` + +To use a custom DNS resolver within your private network, add `resolver_ips`: + +```tf +resource "cloudflare_connectivity_directory_service" "my_private_api" { + account_id = var.account_id + name = "my-private-api" + type = "http" + + host = { + hostname = "internal-api.example.com" + resolver_network = { + tunnel_id = var.tunnel_id + resolver_ips = ["10.0.0.53"] + } + } +} +``` + +### IP-based configuration + +When using IP addresses, provide `host.ipv4` and/or `host.ipv6` with a `network` block. This parallels the IP-based [JSON configuration example](/workers-vpc/configuration/vpc-services/#configuration-example). + +```tf +resource "cloudflare_connectivity_directory_service" "my_private_api" { + account_id = var.account_id + name = "my-private-api" + type = "http" + http_port = 8080 + https_port = 8443 + + host = { + ipv4 = "10.0.1.50" + ipv6 = "fe80::1" + network = { + tunnel_id = var.tunnel_id + } + } +} +``` + +### Port configuration + +Ports are optional and default to 80 (HTTP) and 443 (HTTPS). To enforce a single scheme, provide only one of `http_port` or `https_port`. Refer to [VPC Service configuration](/workers-vpc/configuration/vpc-services/#vpc-service-configuration) for how scheme enforcement and port behavior work. + +## Workers binding configuration + +Once a VPC Service exists, bind it to a Worker using the `vpc_service` binding type in the `bindings` array of a `cloudflare_worker_version` resource. This is equivalent to the [`vpc_services` array in Wrangler configuration](/workers-vpc/configuration/vpc-services/#workers-binding-configuration). + +```tf +resource "cloudflare_worker_version" "my_worker_version" { + account_id = var.account_id + worker_id = cloudflare_worker.my_worker.id + compatibility_date = "$today" + main_module = "worker.js" + + modules = [{ + name = "worker.js" + content_type = "application/javascript+module" + content_file = "build/worker.js" + }] + + bindings = [{ + type = "vpc_service" + name = "PRIVATE_API" + service_id = cloudflare_connectivity_directory_service.my_private_api.service_id + }] +} +``` + +Multiple VPC Service bindings can be added to the same Worker: + +```tf +bindings = [ + { + type = "vpc_service" + name = "PRIVATE_API" + service_id = cloudflare_connectivity_directory_service.api.service_id + }, + { + type = "vpc_service" + name = "PRIVATE_DATABASE" + service_id = cloudflare_connectivity_directory_service.database.service_id + } +] +``` + +The Worker code accesses each binding through `env.PRIVATE_API.fetch()` and `env.PRIVATE_DATABASE.fetch()`, as described in the [Workers Binding API](/workers-vpc/api/). + +For more details on managing Workers and bindings with Terraform, refer to [Workers Infrastructure as Code](/workers/platform/infrastructure-as-code/). + +## Data sources + +The Terraform provider includes data sources for reading existing VPC Services without managing their lifecycle. + +### Look up a single VPC Service + +```tf +data "cloudflare_connectivity_directory_service" "existing" { + account_id = var.account_id + service_id = "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e" +} +``` + +This is useful for binding to a VPC Service that is managed outside of your Terraform configuration (for example, created through the dashboard or Wrangler CLI). + +### List VPC Services + +```tf +data "cloudflare_connectivity_directory_services" "all_http" { + account_id = var.account_id + type = "http" +} +``` + +## Resource schema reference + +```tf +resource "cloudflare_connectivity_directory_service" "example" { + # Required + account_id = "your-account-id" # Account identifier + name = "my-private-api" # Human-readable name + type = "http" # Service type (only "http" supported) + + # Optional + http_port = 80 # HTTP port (default: 80) + https_port = 443 # HTTPS port (default: 443) + + host = { + # Use hostname OR ipv4/ipv6, not both + + # Option A: Hostname-based + hostname = "internal-api.example.com" + resolver_network = { + tunnel_id = "tunnel-uuid" # Required — Cloudflare Tunnel ID + resolver_ips = ["10.0.0.53"] # Optional — custom DNS resolver IPs + } + + # Option B: IP-based + # ipv4 = "10.0.1.50" # IPv4 address + # ipv6 = "fe80::1" # IPv6 address + # network = { + # tunnel_id = "tunnel-uuid" # Required — Cloudflare Tunnel ID + # } + } + + # Read-only (computed by the API) + # id — Terraform resource ID + # service_id — VPC Service ID (use this for Worker bindings) + # created_at — Creation timestamp + # updated_at — Last update timestamp +} +``` + +For the full schema, refer to the [Terraform registry documentation](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/connectivity_directory_service). diff --git a/src/content/docs/workers/platform/infrastructure-as-code.mdx b/src/content/docs/workers/platform/infrastructure-as-code.mdx index d840ecc2d57ac6a..b55c4f2b8d020a1 100644 --- a/src/content/docs/workers/platform/infrastructure-as-code.mdx +++ b/src/content/docs/workers/platform/infrastructure-as-code.mdx @@ -245,6 +245,26 @@ bindings = [{ - `name`: The binding name to access via `env.HYPERDRIVE` - `id`: The ID of your Hyperdrive configuration +### VPC Service Binding + +Bind to a [VPC Service](/workers-vpc/configuration/vpc-services/) for accessing resources in your private network: + +```tf +bindings = [{ + type = "vpc_service" + name = "PRIVATE_API" + service_id = "your-vpc-service-id" +}] +``` + +**Properties:** + +- `type`: `"vpc_service"` +- `name`: The binding name to access via `env.PRIVATE_API` +- `service_id`: The ID of your VPC Service (from `cloudflare_connectivity_directory_service` or the dashboard) + +You can create the VPC Service with Terraform using the `cloudflare_connectivity_directory_service` resource. For a full walkthrough, refer to [Manage VPC Services via API and Terraform](/workers-vpc/reference/manage-vpc-services/). + ### Analytics Engine Binding Bind to an [Analytics Engine](/analytics/analytics-engine/) dataset: @@ -346,6 +366,11 @@ resource "cloudflare_worker_version" "my_worker_version" { type = "secret_text" name = "API_KEY" text = var.api_key + }, + { + type = "vpc_service" + name = "PRIVATE_API" + service_id = var.vpc_service_id } ] } From 1fe039a913daa2e4041ed9d49141210180c43df8 Mon Sep 17 00:00:00 2001 From: "ask-bonk[bot]" Date: Sat, 21 Feb 2026 03:30:01 +0000 Subject: [PATCH 2/4] fix: broken link, code block langs, frontmatter, and unused imports --- .../configuration/vpc-services/index.mdx | 25 +++++++------------ .../configuration/vpc-services/terraform.mdx | 5 ++-- .../platform/infrastructure-as-code.mdx | 2 +- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx b/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx index f2a1c0585f15a46..684b5c0893fbd09 100644 --- a/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx +++ b/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx @@ -5,14 +5,7 @@ sidebar: order: 1 --- -import { - GlossaryTooltip, - Tabs, - TabItem, - Example, - Render, - WranglerConfig, -} from "~/components"; +import { Render, WranglerConfig } from "~/components"; VPC Services are the core building block of Workers VPC. They represent specific resources in your private network that Workers can access through Cloudflare Tunnel. @@ -69,7 +62,7 @@ If your origin service presents a certificate that is not issued by a publicly t The following is an example of a VPC Service for a service using custom HTTP and HTTPS ports, and both IPv4 and IPv6 addresses. These configurations represent the expected contract of the [REST API for creating a VPC Service](/api/resources/connectivity/subresources/directory/subresources/services/), a type of service within the broader connectivity directory. -```json +```jsonc { "type": "http", "name": "human-readable-name", @@ -83,15 +76,15 @@ The following is an example of a VPC Service for a service using custom HTTP and "ipv4": "10.0.0.1", "ipv6": "fe80::", "network": { - "tunnel_id": "0191dce4-9ab4-7fce-b660-8e5dec5172da" - } - } + "tunnel_id": "0191dce4-9ab4-7fce-b660-8e5dec5172da", + }, + }, } ``` The following is an example of a VPC Service for a service using custom HTTP and HTTPS ports as well, using a hostname. Note that since we are using a hostname, we must provide our service with a `resolver_network` that optionally has `resolver_ips`. -```json +```jsonc { "type": "http", "name": "human-readable-name", @@ -105,9 +98,9 @@ The following is an example of a VPC Service for a service using custom HTTP and "hostname": "example.com", "resolver_network": { "tunnel_id": "0191dce4-9ab4-7fce-b660-8e5dec5172da", - "resolver_ips": ["10.0.0.1"] // Optional - } - } + "resolver_ips": ["10.0.0.1"], // Optional + }, + }, } ``` diff --git a/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx b/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx index 6e9ef1c50a39395..1549ee2a6501cce 100644 --- a/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx +++ b/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx @@ -1,6 +1,7 @@ --- title: Configure with Terraform -pcx_content_type: concept +pcx_content_type: how-to +description: Learn how to manage VPC Services using the Cloudflare Terraform provider. sidebar: order: 2 --- @@ -92,7 +93,7 @@ Once a VPC Service exists, bind it to a Worker using the `vpc_service` binding t resource "cloudflare_worker_version" "my_worker_version" { account_id = var.account_id worker_id = cloudflare_worker.my_worker.id - compatibility_date = "$today" + compatibility_date = "2025-02-21" # Set this to today's date main_module = "worker.js" modules = [{ diff --git a/src/content/docs/workers/platform/infrastructure-as-code.mdx b/src/content/docs/workers/platform/infrastructure-as-code.mdx index b55c4f2b8d020a1..b429e646ad5f7c1 100644 --- a/src/content/docs/workers/platform/infrastructure-as-code.mdx +++ b/src/content/docs/workers/platform/infrastructure-as-code.mdx @@ -263,7 +263,7 @@ bindings = [{ - `name`: The binding name to access via `env.PRIVATE_API` - `service_id`: The ID of your VPC Service (from `cloudflare_connectivity_directory_service` or the dashboard) -You can create the VPC Service with Terraform using the `cloudflare_connectivity_directory_service` resource. For a full walkthrough, refer to [Manage VPC Services via API and Terraform](/workers-vpc/reference/manage-vpc-services/). +You can create the VPC Service with Terraform using the `cloudflare_connectivity_directory_service` resource. For a full walkthrough, refer to [Configure VPC Services with Terraform](/workers-vpc/configuration/vpc-services/terraform/). ### Analytics Engine Binding From 424162838c54e8a1164a3e547046901035b4280f Mon Sep 17 00:00:00 2001 From: "ask-bonk[bot]" Date: Mon, 23 Feb 2026 15:10:08 +0000 Subject: [PATCH 3/4] fix: pre-existing style issues (em dash, contraction, vague links, $today in tf block) --- .../docs/workers-vpc/configuration/vpc-services/index.mdx | 2 +- .../docs/workers/platform/infrastructure-as-code.mdx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx b/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx index 684b5c0893fbd09..8633fee384d1461 100644 --- a/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx +++ b/src/content/docs/workers-vpc/configuration/vpc-services/index.mdx @@ -29,7 +29,7 @@ A VPC Service consists of: - **Tunnel ID**: The Cloudflare Tunnel that provides network connectivity - **Hostname or IPv4/IPv6 addresses**: The hostname, or IPv4 and/or IPv6 addresses to use to route to your service from the tunnel in your private network - **Ports**: HTTP and/or HTTPS port configuration (optional, defaults to 80/443) -- **Resolver IPs**: Optionally, a specific resolver IP can be provided -- when not provided, `cloudflared` will direct DNS traffic to the currently configured default system resolver. +- **Resolver IPs**: Optionally, a specific resolver IP can be provided — when not provided, `cloudflared` will direct DNS traffic to the currently configured default system resolver. Requests are encrypted in flight until they reach your network via a tunnel, regardless of the scheme used in the URL provided to `fetch`. If the `http` scheme is used, a plaintext connection is established to the service from the tunnel. diff --git a/src/content/docs/workers/platform/infrastructure-as-code.mdx b/src/content/docs/workers/platform/infrastructure-as-code.mdx index b429e646ad5f7c1..c90f100b9e4077e 100644 --- a/src/content/docs/workers/platform/infrastructure-as-code.mdx +++ b/src/content/docs/workers/platform/infrastructure-as-code.mdx @@ -30,7 +30,7 @@ When using Wrangler for building and a different method for uploading, make sure ## Terraform -In this example, you need a local file named `my-script.mjs` with script content similar to the below examples. Learn more about the Cloudflare Terraform Provider [here](/terraform), and see an example with all the Workers script resource settings [here](https://github.com/cloudflare/terraform-provider-cloudflare/blob/main/examples/resources/cloudflare_workers_script/resource.tf). +In this example, you need a local file named `my-script.mjs` with script content similar to the below examples. Learn more about the [Cloudflare Terraform Provider](/terraform/), and refer to the [Workers script resource example](https://github.com/cloudflare/terraform-provider-cloudflare/blob/main/examples/resources/cloudflare_workers_script/resource.tf) for all available resource settings. ```tf variable "account_id" { @@ -48,7 +48,7 @@ resource "cloudflare_worker" "my_worker" { resource "cloudflare_worker_version" "my_worker_version" { account_id = var.account_id worker_id = cloudflare_worker.my_worker.id - compatibility_date = "$today" + compatibility_date = "2025-02-21" # Set this to today's date main_module = "my-script.mjs" modules = [ { @@ -71,7 +71,7 @@ resource "cloudflare_workers_deployment" "my_worker_deployment" { } ``` -Notice how you don't have to manage all of these resources in Terraform. For example, you could just the `cloudflare_worker` resource and seamlessly use Wrangler or your own deployment tools for Versions or Deployments. +Notice how you do not have to manage all of these resources in Terraform. For example, you could use just the `cloudflare_worker` resource and seamlessly use Wrangler or your own deployment tools for Versions or Deployments. ## Bindings in Terraform From c15f3d4fc88c0bdce8359793382e182b0d1cb8c5 Mon Sep 17 00:00:00 2001 From: Jun Lee Date: Mon, 23 Feb 2026 17:13:21 +0000 Subject: [PATCH 4/4] Redundant change to re-trigger compiles pipeline --- .../docs/workers-vpc/configuration/vpc-services/terraform.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx b/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx index 1549ee2a6501cce..e99014102681962 100644 --- a/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx +++ b/src/content/docs/workers-vpc/configuration/vpc-services/terraform.mdx @@ -11,9 +11,7 @@ VPC Services can be managed as infrastructure using the [`cloudflare_connectivit This maps directly to the [connectivity directory](/api/resources/connectivity/subresources/directory/subresources/services/) — the underlying API that the dashboard and Wrangler CLI also use to create and manage VPC Services. The same [VPC Service configuration fields](/workers-vpc/configuration/vpc-services/#vpc-service-configuration) (type, host, ports, tunnel ID) apply regardless of how the service is created. :::note - Requires Cloudflare Terraform provider v5.13.0 or later. - ::: ## VPC Service resource