Last active
May 22, 2020 06:19
-
-
Save Integralist/979098ebd90a0820456c246c4224f770 to your computer and use it in GitHub Desktop.
[Fastly VCL Boilerplate for handling mutliple subdomains] #fastly #vcl #boilerplate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
###################################################################################### | |
# | |
# detailed blog post on fastly's implementation details: | |
# http://www.integralist.co.uk/posts/fastly-varnish/ | |
# | |
# fastly custom vcl boilerplate: | |
# https://docs.fastly.com/vcl/custom-vcl/creating-custom-vcl/#fastlys-vcl-boilerplate | |
# | |
# vcl_recv | |
# vcl_error | |
# vcl_hash | |
# vcl_pass | |
# vcl_miss | |
# vcl_hit | |
# vcl_fetch | |
# vcl_deliver | |
# | |
###################################################################################### | |
table deny_list { | |
"/bad-thing-1": "true", | |
"/bad-thing-2": "true", | |
} | |
sub set_backend { | |
set req.backend = F_httpbin; | |
if (req.http.Host == "example-stage.acme.com/") { | |
set req.backend = F_httpbin_stage; | |
} | |
} | |
sub vcl_recv { | |
#FASTLY recv | |
call set_backend; | |
# configure purges to require api authentication: | |
# https://docs.fastly.com/en/guides/authenticating-api-purge-requests | |
# | |
if (req.method == "FASTLYPURGE") { | |
set req.http.Fastly-Purge-Requires-Auth = "1"; | |
} | |
# force HTTP to HTTPS | |
# | |
# related: req.http.Fastly-SSL | |
# https://docs.fastly.com/en/guides/tls-termination | |
# | |
if (req.protocol != "https") { | |
error 601 "Force SSL"; | |
} | |
# fastly 'tables' are different to 'edge dictionaries': | |
# https://docs.fastly.com/en/guides/about-edge-dictionaries | |
# | |
if (table.lookup(deny_list, req.url.path)) { | |
error 600 "Not found"; | |
} | |
# don't bother doing a cache lookup for a request type that isn't cacheable | |
if (req.method !~ "(GET|HEAD|FASTLYPURGE)") { | |
return(pass); | |
} | |
if (req.restarts == 0) { | |
# nagios/monitoring cache bypass | |
# | |
if (req.url ~ "123") { | |
set req.http.X-Monitoring = "true"; | |
return(pass); | |
} | |
} | |
return(lookup); | |
} | |
sub vcl_error { | |
#FASTLY error | |
# fastly synthetic error responses: | |
# https://docs.fastly.com/en/guides/creating-error-pages-with-custom-responses | |
# | |
if (obj.status == 600) { | |
set obj.status = 404; | |
synthetic {" | |
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Error</title> | |
</head> | |
<body> | |
<h1>404 Not Found (varnish)</h1> | |
</body> | |
</html> | |
"}; | |
return(deliver); | |
} | |
# fastly HTTP to HTTPS 301 redirect: | |
# https://docs.fastly.com/en/guides/generating-http-redirects-at-the-edge | |
# | |
# example: | |
# curl -sD - http://example.acme.com/ | |
# curl -H Fastly-Debug:1 -sLD - -o /dev/null http://example.acme.com/?cachebust=$(uuidgen) | |
# | |
if (obj.status == 601 && obj.response == "Force SSL") { | |
set obj.status = 301; | |
set obj.response = "Moved Permanently"; | |
set obj.http.Location = "https://" req.http.host req.url; | |
synthetic {""}; | |
return (deliver); | |
} | |
} | |
sub vcl_hash { | |
#FASTLY hash | |
set req.hash += req.url; | |
set req.hash += req.http.host; | |
# call debug_info_hash; | |
return(hash); | |
} | |
sub vcl_pass { | |
#FASTLY pass | |
} | |
sub vcl_miss { | |
#FASTLY miss | |
return(fetch); | |
} | |
sub vcl_hit { | |
#FASTLY hit | |
} | |
sub vcl_fetch { | |
#FASTLY fetch | |
# fastly caching directive: | |
# https://docs.fastly.com/en/guides/cache-control-tutorial | |
# | |
# example: | |
# define stale behaviour if none provided by origin | |
# | |
if (beresp.http.Surrogate-Control !~ "(stale-while-revalidate|stale-if-error)") { | |
set beresp.stale_if_error = 31536000s; // 1 year | |
set beresp.stale_while_revalidate = 60s; // 1 minute | |
} | |
# fastly stale-if-error: | |
# https://docs.fastly.com/en/guides/serving-stale-content | |
# | |
if (beresp.status >= 500 && beresp.status < 600) { | |
if (stale.exists) { | |
return(deliver_stale); | |
} | |
} | |
# hit-for-pass: | |
# https://www.integralist.co.uk/posts/fastly-varnish/#hit-for-pass | |
# | |
if (beresp.http.Cache-Control ~ "private") { | |
return(pass); | |
} | |
# ensure we set our own default cache TTL if no caching directives found | |
if (beresp.cacheable && !beresp.http.Surrogate-Control:max-age && !beresp.http.Cache-Control:max-age) { | |
set beresp.ttl = 1h; # 1 hour | |
} | |
return(deliver); | |
} | |
sub vcl_deliver { | |
#FASTLY deliver | |
# fastly internal state information: | |
# https://docs.fastly.com/en/guides/useful-variables-to-log | |
# | |
set resp.http.Fastly-State = fastly_info.state; | |
if (req.http.X-Monitoring == "true") { | |
set resp.http.X-Monitoring = req.http.X-Monitoring; | |
} | |
return(deliver); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment