diff --git a/files/varnish/synth_redirect.vcl b/files/varnish/synth_redirect.vcl new file mode 100644 index 0000000..adb8ff7 --- /dev/null +++ b/files/varnish/synth_redirect.vcl @@ -0,0 +1,19 @@ +# synth_redirect.vcl +# +# Redirect to the x-redir http header when receiving a synthesized code 850 +# +# Example use: +# sub vcl_recv { +# set req.http.x-redir = "https://" + req.http.host + req.url; +# return(synth(850, "Moved permanently")); +# } +# +# File managed by puppet. All modifications will be lost. + +sub vcl_synth { + if (resp.status == 850) { + set resp.http.Location = req.http.x-redir; + set resp.status = 302; + return (deliver); + } +} diff --git a/manifests/varnish.pp b/manifests/varnish.pp new file mode 100644 index 0000000..b4d3711 --- /dev/null +++ b/manifests/varnish.pp @@ -0,0 +1,60 @@ +# Varnish configuration + +class profile::varnish { + $includes_dir = '/etc/varnish/includes' + $includes_vcl_name = 'includes.vcl' + $includes_vcl = "/etc/varnish/${includes_vcl_name}" + + $http_port = hiera('varnish::http_port') + $backend_http_port = hiera('varnish::backend_http_port') + $hsts_max_age = hiera('varnish::hsts_max_age') + + $listen = hiera('varnish::listen') + $admin_listen = hiera('varnish::admin_listen') + $admin_port = hiera('varnish::admin_port') + $secret = hiera('varnish::secret') + $storage_type = hiera('varnish::storage_type') + $storage_size = hiera('varnish::storage_size') + $storage_file = hiera('varnish::storage_file') + + class {'::varnish': + addrepo => false, + listen => $listen, + admin_listen => $admin_listen, + admin_port => $admin_port, + secret => $secret, + storage_type => $storage_type, + storage_size => $storage_size, + storage_file => $storage_file, + } + + ::varnish::vcl {'/etc/varnish/default.vcl': + content => template('profile/varnish/default.vcl.erb'), + require => File['/etc/varnish/includes.vcl'], + } + + file {$includes_dir: + ensure => directory, + owner => 'root', + group => 'root', + mode => '0644', + require => Class['varnish::install'], + notify => Exec['vcl_reload'], + } + + concat {$includes_vcl: + ensure => present, + owner => 'root', + group => 'root', + mode => '0644', + ensure_newline => true, + require => Class['varnish::install'], + notify => Exec['vcl_reload'], + } + + concat::fragment {"${includes_vcl}:header": + target => $includes_vcl, + content => "# File managed with puppet (module profile::varnish)\n# All modifications will be lost\n\n", + order => '00', + } +} diff --git a/manifests/varnish/default_vcls.pp b/manifests/varnish/default_vcls.pp new file mode 100644 index 0000000..9db8f9c --- /dev/null +++ b/manifests/varnish/default_vcls.pp @@ -0,0 +1,13 @@ +# Default VCLs included with the varnish profile + +class profile::varnish::default_vcls { + ::profile::varnish::vcl_include {'backend_default': + order => '01', + content => template('profile/varnish/backend_default.vcl.erb'), + } + + ::profile::varnish::vcl_include {'synth_redirect': + order => '10', + content => file('profile/varnish/synth_redirect.vcl'), + } +} diff --git a/manifests/varnish/vcl_include.pp b/manifests/varnish/vcl_include.pp new file mode 100644 index 0000000..6efa7a0 --- /dev/null +++ b/manifests/varnish/vcl_include.pp @@ -0,0 +1,24 @@ +# Definition of vcl includes + +define profile::varnish::vcl_include ( + String $content, + String $basename = $title, + String $order = '01', +) { + $includes_dir = $::profile::varnish::includes_dir + $includes_vcl = $::profile::varnish::includes_vcl + + $vcl_path = "${::profile::varnish::includes_dir}/${order}_${basename}.vcl" + + ::varnish::vcl {$vcl_path: + content => $content, + require => File[$includes_dir], + } + + concat::fragment {"${includes_vcl}:${basename}": + target => $includes_vcl, + content => "include \"includes/${order}_${basename}.vcl\";", + order => $order, + require => ::Varnish::Vcl[$vcl_path], + } +} diff --git a/templates/varnish/backend_default.vcl.erb b/templates/varnish/backend_default.vcl.erb new file mode 100644 index 0000000..787d00d --- /dev/null +++ b/templates/varnish/backend_default.vcl.erb @@ -0,0 +1,10 @@ +# backend_default.vcl +# +# Default backend definition. +# +# File managed by puppet. All modifications will be lost. + +backend default { + .host = "::1"; + .port = "<%= scope['::profile::varnish::backend_http_port'] %>"; +} diff --git a/templates/varnish/default.vcl.erb b/templates/varnish/default.vcl.erb new file mode 100644 index 0000000..05f42a9 --- /dev/null +++ b/templates/varnish/default.vcl.erb @@ -0,0 +1,7 @@ +# Varnish configuration file +# File managed by puppet (module profile::varnish) +# All modifications will be lost. + +vcl 4.0; + +include "<%= @includes_vcl_name %>"; diff --git a/templates/varnish/vhost_redirect_https.vcl.erb b/templates/varnish/vhost_redirect_https.vcl.erb new file mode 100644 index 0000000..6bbefa6 --- /dev/null +++ b/templates/varnish/vhost_redirect_https.vcl.erb @@ -0,0 +1,27 @@ +# vhost_<%= @aliases[0] %>_redirect_https.vcl +# +# Redirect virtual host to https +# +# File managed by puppet. All modifications will be lost. + +import std; + +sub vcl_recv { + if (std.port(server.ip) != <%= scope['::profile::varnish::http_port'] %> && ( +<% @aliases.each do |alias| %> + req.http.host ~ "^(?i)<%= Regexp.escape(alias) %>$" || +<% end %> + false + )) { + set req.http.x-redir = "https://" + req.http.host + req.url; + return(synth(850, "Moved permanently")); + } +} + +<% if scope['::profile::varnish::hsts_max_age'] %> +sub vcl_deliver { + if (std.port(server.ip) != <%= scope['::profile::varnish::http_port'] %>) { + set resp.http.Strict-Transport-Security = "max-age=<%= scope['::profile::varnish::hsts_max_age'] %>;"; + } +} +<% end -%>