Manage Turnstile widgets as code using Terraform for version control and automated deployments.
Before you begin, you must have:
- Terraform ↗ installed
- A Cloudflare API token with
Account:Turnstile:Edit permissions - (Optional) A
cf-terraformingtool for importing existing widgets
Create a main.tf file.
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
variable "cloudflare_api_token" {
description = "Cloudflare API Token"
type = string
sensitive = true
}
variable "account_id" {
description = "Cloudflare Account ID"
type = string
}resource "cloudflare_turnstile_widget" "login_form" {
account_id = var.account_id
name = "Login Form Widget"
domains = ["example.com", "www.example.com"]
mode = "managed"
region = "world"
}
resource "cloudflare_turnstile_widget" "api_protection" {
account_id = var.account_id
name = "API Protection"
domains = ["api.example.com"]
mode = "invisible"
region = "world"
}
# Output the sitekeys for use in your application
output "login_sitekey" {
value = cloudflare_turnstile_widget.login_form.sitekey
}
output "api_sitekey" {
value = cloudflare_turnstile_widget.api_protection.sitekey
}Create a .env file or set environment variables.
export TF_VAR_cloudflare_api_token="your-api-token"
export TF_VAR_account_id="your-account-id"terraform initterraform planterraform applyterraform planterraform applyterraform destroylocals {
environments = {
dev = {
domains = ["dev.example.com"]
mode = "managed"
}
staging = {
domains = ["staging.example.com"]
mode = "non_interactive"
}
prod = {
domains = ["example.com", "www.example.com"]
mode = "invisible"
}
}
}
resource "cloudflare_turnstile_widget" "app_widget" {
for_each = local.environments
account_id = var.account_id
name = "App Widget - ${each.key}"
domains = each.value.domains
mode = each.value.mode
region = "world"
}resource "cloudflare_turnstile_widget" "enterprise_widget" {
account_id = var.account_id
name = "Enterprise Form"
domains = ["enterprise.example.com"]
mode = "managed"
region = "world"
offlabel = true # Remove Cloudflare branding
bot_fight_mode = true # Enable bot fight mode
}Use cf-terraforming to import existing widgets.
go install github.com/cloudflare/cf-terraforming/cmd/cf-terraforming@latestcf-terraforming generate \
--resource-type cloudflare_turnstile_widget \
--account $ACCOUNT_IDterraform import cloudflare_turnstile_widget.existing_widget \
$ACCOUNT_ID/$WIDGET_SITEKEY