Terraform and OpenTofu
Manage your Varnish CDN services, certificates and purge tokens as code with the Varnish provider for OpenTofu and Terraform.
The Varnish provider lets you manage your CDN setup as code. You describe services, domains, origins, settings, certificates and purge tokens in configuration files, and OpenTofu or Terraform creates and updates them for you.
The provider is open source and available at github.com/varnish/terraform-provider-varnish.
What you can manage
| Resource | Description |
|---|---|
varnish_cdn_service | A CDN service with its domains, origins and settings |
varnish_cdn_certificate | An uploaded TLS certificate |
varnish_cdn_purge_token | A token that can only invalidate cached content |
varnish_org_user | A user in your organization, from invite to member |
| Data source | Description |
|---|---|
varnish_cdn_domain_dns | The DNS records a domain needs, and its verification status |
varnish_cdn_wizard_templates | The configuration templates available to your organization |
varnish_roles | The role names you can give to varnish_org_user |
Getting started with OpenTofu
Create an API access token
Create an API access token for your organization in the dashboard. The provider uses it for all requests. Treat it like a password.
Configure the provider
Create a main.tf file:
terraform {
required_providers {
varnish = {
source = "varnish/varnish"
version = "~> 0.1"
}
}
}
provider "varnish" {}
Set the token
Pass the token as an environment variable, so it never ends up in your files:
export VARNISH_ACCESS_TOKEN="<your-access-token>"
Initialize
tofu init
OpenTofu downloads the provider and verifies its signature.
Create a service
A service needs at least one domain and one origin:
resource "varnish_cdn_service" "web" {
domain {
fqdn = "www.example.com"
tls = true
}
origin {
name = "default"
host = "origin.example.com"
port = 443
enable_tls = true
is_default = true
}
}
# The DNS records to set at your DNS provider
data "varnish_cdn_domain_dns" "www" {
service_id = varnish_cdn_service.web.id
fqdn = "www.example.com"
}
output "dns" {
value = {
cname = data.varnish_cdn_domain_dns.www.expected_cname
txt = data.varnish_cdn_domain_dns.www.expected_txt
verified = data.varnish_cdn_domain_dns.www.verified
}
}
Review the changes and apply them:
tofu plan
tofu apply
The dns output shows the records your domain needs. Once they are in place, verified becomes true.
example.com, set subdomain, for example subdomain = "www". Wildcard domains such as *.example.com are supported too.Configure settings
The settings attribute holds the same configuration as the dashboard. The fields follow the configuration reference, written in snake_case:
resource "varnish_cdn_service" "web" {
# domain and origin blocks as above
settings = {
general = {
first_byte_timeout = "10s"
}
query_params = {
remove_query_parameters = { action = "sort" }
}
cookies = {
on_cookie = { action = "remove" }
}
security = {
https_redirect = true
hsts = true
}
# Apply settings only to matching requests
overrides = [
{
name = "cache-images-long"
extensions = ["jpg", "png", "webp"]
rules = [
{ string_id = "general.cacheableTTLOverride", value = jsonencode("7d") },
]
},
]
}
}
Only the settings you set are managed. Everything else keeps its current value, and changes made in the dashboard to those settings do not show up as a difference in your plan.
See the configuration pages for what each setting does. The full example lists every field with its allowed values.
Use your own certificate
By default, the CDN issues certificates for your domains. To use your own certificate, upload it and attach it to a domain:
resource "varnish_cdn_certificate" "example" {
name = "example-com"
certificate = file("cert.pem")
private_key = file("key.pem")
}
resource "varnish_cdn_service" "web" {
domain {
fqdn = "www.example.com"
tls = true
cert_id = varnish_cdn_certificate.example.id
}
# origin block as above
}
Create a purge token
Purge tokens let other systems invalidate cached content:
resource "varnish_cdn_purge_token" "ci" {
label = "ci-pipeline"
expire = "8760h" # one year
}
output "purge_token" {
value = varnish_cdn_purge_token.ci.access_token
sensitive = true
}
Read the token with tofu output -raw purge_token. It is only available for tokens created by OpenTofu or Terraform, not for imported ones.
Import existing services
To manage a service you already created in the dashboard, import it by its service ID:
import {
to = varnish_cdn_service.web
id = "42"
}
Then generate the configuration for it:
tofu plan -generate-config-out=generated.tf
Review generated.tf, then run tofu apply to finish the import.
Terraform: build locally
Until the provider is in the Terraform Registry, build it from source. You need Go installed.
Build and install the provider
git clone https://github.com/varnish/terraform-provider-varnish.git
cd terraform-provider-varnish
go install .
This puts the binary in $(go env GOPATH)/bin.
Point Terraform to the local build
Add this to ~/.terraformrc. Replace the path with the output of go env GOPATH, followed by /bin:
provider_installation {
dev_overrides {
"registry.terraform.io/varnish/varnish" = "/home/<user>/go/bin"
}
direct {}
}
Use it
Use the same main.tf as above. Skip terraform init, and run terraform plan and terraform apply directly. Terraform prints a warning that development overrides are in use. That is expected.
Remove the dev_overrides block once the provider is available in the Terraform Registry.
Reference
- Provider documentation: every resource and attribute
- Examples
- Report an issue