2026-05-11 16:22:50 +02:00
2026-05-11 10:15:44 +02:00
2026-01-13 14:56:46 +01:00
2026-01-13 14:56:46 +01:00
2026-05-11 16:22:50 +02:00

Terraform Fastly

POC / exploration of the Fastly Terraform provider for managing Fastly CDN services via Infrastructure as Code.

Table of Contents


Overview

This project demonstrates how to provision and manage a Fastly CDN service using Terraform and the official fastly/fastly provider (v8+).

It abstracts common CDN configuration patterns — backends, compression (gzip + brotli), HTTP/3, cache control, CORS, IP-based PURGE whitelisting, and domain management — into a reusable Terraform module.


Project Structure

terraform-fastly/
├── modules/
│   └── service-vcl/              # Reusable Fastly service module
│       ├── main.tf               # Resource definitions (service, ACL, domain)
│       ├── variables.tf          # Module input variables
│       └── provider.tf           # Provider requirements (fastly >= 8.0.0)
├── poc/                          # Proof-of-Concept / example deployment
│   ├── modules.tf                # Module invocation
│   └── variables.tf              # Example variable values
├── .gitignore
└── LICENSE

Module: service-vcl

The core module provisions a complete Fastly VCL service with:

Resource Purpose
fastly_service_vcl The Fastly service itself — backend, compression, HTTP/3, cache overrides, ACLs, and snippets
fastly_service_acl_entries IP whitelist for secure PURGE requests (conditional — only created when purge_allowed_ips is non-empty)
fastly_domain DNS domain binding for the service

POC: poc/

A working example that ties everything together with sensible defaults pointing to git.rznet.fr.


Prerequisites

  • Terraform ≥ 1.0
  • Fastly API Key — obtain from your Fastly account dashboard
  • Access to a backend origin server

Quick Start

# 1. Export your Fastly API key
export FASTLY_API_KEY="your_api_key_here"

# 2. Navigate to the POC directory
cd poc

# 3. Initialize, plan, and apply
terraform init
terraform plan
terraform apply

Architecture

                    ┌───────────────────────┐
                    │     Fastly CDN        │
                    │                       │
  Domain ──────────►│   ── HTTP/3 enabled   │
  (var.domain)      │   ── gzip + brotli    │
                    │   ── cache control    │
                    │   ── PURGE whitelist  │
                    │                       │
                    └──────┬────────────────┘
                           │ SSL (var.backend_ssl)
                           ▼
                    ┌──────────────────────┐
                    │  Backend Origin      │
                    │  (var.backend)       │
                    │  :443                │
                    └──────────────────────┘

Key flows:

  1. Request handling — Client hits the Fastly domain → service evaluates VCL → cache lookup → fetch from backend if miss.
  2. PURGE requests — A dynamic VCL snippet intercepts PURGE requests and only allows them from IPs in the purge_ip_whitelist ACL. Non-whitelisted IPs receive a 403 Forbidden.
  3. Compression — Static assets matching configured extensions and content types are gzip-compressed. Brotli is enabled by default.

Usage

Basic

Simply supply a domain and backend:

module "fastly" {
  source      = "../modules/service-vcl"
  domain      = "cdn.example.com"
  backend     = "origin.example.com"
}

With PURGE Whitelist

module "fastly" {
  source            = "../modules/service-vcl"
  domain            = "cdn.example.com"
  backend           = "origin.example.com"
  purge_allowed_ips = ["203.0.113.0/24", "198.51.100.5"]
}

With Full Configuration

module "fastly" {
  source                      = "../modules/service-vcl"
  domain                      = "cdn.example.com"
  backend                     = "origin.example.com"
  backend_cert_hostname       = "origin.example.com"
  backend_port                = 443
  backend_ssl                 = true
  backend_ssl_check           = true

  http3                       = true
  enable_brotli               = true
  enable_image_optimization   = false

  default_ttl                 = 3600
  stale_ttl                   = 86400
  cache_override              = true

  gzip_extensions             = ["css", "js", "html", "json"]
  gzip_content_types          = ["text/html", "text/css", "application/json"]

  allowed_cors_domains        = ["https://example.com"]

  enable_logging              = false
  enable_waf                  = false

  force_destroy               = true
  purge_allowed_ips           = ["10.0.0.1"]
}

Variables Reference

Module: modules/service-vcl/variables.tf

Variable Type Default Description
domain string "" Fastly domain / service name
backend string "" Backend origin address
backend_port number 443 Backend port
backend_ssl bool true Enable SSL to backend
backend_ssl_check bool true Check backend SSL certificate
backend_cert_hostname string "" Hostname for SSL certificate validation
http3 bool true Enable HTTP/3 (QUIC)
default_ttl number 3600 Default cache TTL in seconds
stale_ttl number 86400 Stale-while-revalidate TTL in seconds
cache_override bool true Enable cache override
gzip_extensions list see below File extensions to gzip compress
gzip_content_types list see below MIME types to gzip compress
enable_brotli bool true Enable Brotli compression
enable_image_optimization bool false Enable Fastly image optimization
enable_logging bool false Enable logging
log_format string "%h %l %u %t \"%r\" %>s %b" Log format string
enable_waf bool false Enable Web Application Firewall
allowed_cors_domains list(string) [] Allowed CORS origins
purge_allowed_ips list(string) [] IPs/CIDRs allowed to send PURGE requests

Default gzip extensions: css, js, html, htm, txt, json, xml, woff, woff2

Default gzip content types: text/html, text/plain, text/css, application/javascript, application/json, application/xml, application/x-javascript, text/javascript, text/xml, application/rss+xml, image/svg+xml, application/wasm, font/woff2


Features

Feature Status Notes
Backend with SSL/TLS Configurable port, cert hostname, SNI
Gzip Compression Configurable extensions + content types
Brotli Compression Enabled by default
HTTP/3 (QUIC) Enabled by default
Cache TTL / Stale-While-Revalidate Configurable defaults
CORS Whitelist of allowed domains
Image Optimization Toggle on/off
Domain Management Automatic domain binding
PURGE IP Whitelist Dynamic ACL + VCL snippet
Logging Configurable format
WAF Integration Toggle on/off

License

This project is licensed under the MIT License. See the LICENSE file for more information.

S
Description
POC/exploration of Fastly tf provider
Readme MIT
47 KiB
Languages
HCL 100%