diff --git a/hieradata/common.yaml b/hieradata/common.yaml index cc16e0e..dcc73a2 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -93,6 +93,9 @@ lookup_options: profiles::puppet::server::dns_alt_names: merge: strategy: deep + profiles::base::hosts::additional_hosts: + merge: + strategy: deep facts_path: '/opt/puppetlabs/facter/facts.d' diff --git a/hieradata/roles/infra/storage/consul.yaml b/hieradata/roles/infra/storage/consul.yaml index 08819e8..036e177 100644 --- a/hieradata/roles/infra/storage/consul.yaml +++ b/hieradata/roles/infra/storage/consul.yaml @@ -53,3 +53,9 @@ profiles::consul::prepared_query::rules: service_failover_n: 3 service_only_passing: true ttl: 10 + edgecache: + ensure: 'present' + service_name: 'edgecache' + service_failover_n: 3 + service_only_passing: true + ttl: 10 diff --git a/hieradata/roles/infra/storage/edgecache.yaml b/hieradata/roles/infra/storage/edgecache.yaml new file mode 100644 index 0000000..af26945 --- /dev/null +++ b/hieradata/roles/infra/storage/edgecache.yaml @@ -0,0 +1,76 @@ +--- +consul::services: + puppet: + service_name: 'edgecache' + tags: + - 'cache' + - 'edge' + address: "%{facts.networking.ip}" + port: 443 + checks: + - id: 'edgecache_https_check' + name: 'EdgeCache HTTPS Check' + http: "https://%{facts.networking.fqdn}" + method: 'GET' + tls_skip_verify: true + interval: '10s' + timeout: '1s' +profiles::consul::client::node_rules: + - resource: service + segment: edgecache + disposition: write + +# additional altnames +profiles::pki::vault::alt_names: + - edgecache.service.consul + - edgecache.query.consul + +profiles::edgecache::params::nginx_listen_mode: both +profiles::edgecache::params::nginx_cert_type: vault +profiles::edgecache::params::nginx_aliases: + - edgecache.service.consul + - edgecache.query.consul +profiles::edgecache::params::directories: + /data/edgecache: { owner: root, group: root } + /data/edgecache/pub: { owner: nginx, group: nginx } + /data/edgecache/pub/almalinux: { owner: nginx, group: nginx } + /data/edgecache/pub/debian: { owner: nginx, group: nginx } + /data/edgecache/pub/epel: { owner: nginx, group: nginx } + +profiles::edgecache::params::mirrors: + debian: + ensure: present + location: /debian + proxy: http://mirror.gsl.icu + debian_pool: + ensure: present + location: /debian/pool + proxy: http://mirror.gsl.icu + proxy_cache: cache + proxy_cache_valid: + - '200 302 1440h' + - '404 1m' + almalinux_repodata: + ensure: present + location: '~* ^/almalinux/.*/repodata/' + proxy: http://gsl-syd.mm.fcix.net + almalinux_data: + ensure: present + location: /almalinux + proxy: http://gsl-syd.mm.fcix.net + proxy_cache: cache + proxy_cache_valid: + - '200 302 1440h' + - '404 1m' + epel_repodata: + ensure: present + location: '~* ^/epel/.*/repodata/' + proxy: http://gsl-syd.mm.fcix.net + epel_data: + ensure: present + location: /epel + proxy: http://gsl-syd.mm.fcix.net + proxy_cache: cache + proxy_cache_valid: + - '200 302 1440h' + - '404 1m' diff --git a/site/profiles/manifests/edgecache/init.pp b/site/profiles/manifests/edgecache/init.pp new file mode 100644 index 0000000..1112530 --- /dev/null +++ b/site/profiles/manifests/edgecache/init.pp @@ -0,0 +1,12 @@ +# profiles::edgecache::init +class profiles::edgecache::init { + + if $facts['enc_role'] == 'roles::infra::storage::edgecache' { + + include profiles::edgecache::nginx + include profiles::edgecache::selinux + + Class['profiles::edgecache::nginx'] + -> Class['profiles::edgecache::selinux'] + } +} diff --git a/site/profiles/manifests/edgecache/nginx.pp b/site/profiles/manifests/edgecache/nginx.pp new file mode 100644 index 0000000..6849e22 --- /dev/null +++ b/site/profiles/manifests/edgecache/nginx.pp @@ -0,0 +1,119 @@ +# profiles::edgecache::nginx +class profiles::edgecache::nginx { + + include profiles::edgecache::params + + $data_root = $profiles::edgecache::params::data_root + $nginx_vhost = $profiles::edgecache::params::nginx_vhost + $nginx_aliases = $profiles::edgecache::params::nginx_aliases + $nginx_port = $profiles::edgecache::params::nginx_port + $nginx_ssl_port = $profiles::edgecache::params::nginx_ssl_port + $nginx_listen_mode = $profiles::edgecache::params::nginx_listen_mode + $nginx_cert_type = $profiles::edgecache::params::nginx_cert_type + + # select the certificates to use based on cert type + case $nginx_cert_type { + 'puppet': { + $selected_ssl_cert = "/etc/pki/tls/puppet/${facts['networking']['fqdn']}.crt" + $selected_ssl_key = "/etc/pki/tls/puppet/${facts['networking']['fqdn']}.key" + } + 'vault': { + $selected_ssl_cert = '/etc/pki/tls/vault/certificate.crt' + $selected_ssl_key = '/etc/pki/tls/vault/private.key' + } + default: { + # enum param prevents this ever being reached + } + } + + # set variables based on the listen_mode + case $nginx_listen_mode { + 'http': { + $enable_ssl = false + $ssl_cert = undef + $ssl_key = undef + $listen_port = $nginx_port + $listen_ssl_port = undef + $extras_hash = {} + } + 'https': { + $enable_ssl = true + $ssl_cert = $selected_ssl_cert + $ssl_key = $selected_ssl_key + $listen_port = $nginx_ssl_port + $listen_ssl_port = $nginx_ssl_port + $extras_hash = { + 'subscribe' => [File[$ssl_cert], File[$ssl_key]], + } + } + 'both': { + $enable_ssl = true + $ssl_cert = $selected_ssl_cert + $ssl_key = $selected_ssl_key + $listen_port = $nginx_port + $listen_ssl_port = $nginx_ssl_port + $extras_hash = { + 'subscribe' => [File[$ssl_cert], File[$ssl_key]], + } + } + default: { + # enum param prevents this ever being reached + } + } + + # set the server_names + $server_names = unique([$facts['networking']['fqdn'], $nginx_vhost] + $nginx_aliases) + + # define the default parameters for the nginx server + $defaults = { + 'listen_port' => $listen_port, + 'server_name' => $server_names, + 'use_default_location' => true, + 'access_log' => "/var/log/nginx/${nginx_vhost}_access.log", + 'error_log' => "/var/log/nginx/${nginx_vhost}_error.log", + 'www_root' => "${data_root}/pub", + 'autoindex' => 'on', + 'ssl' => $enable_ssl, + 'ssl_cert' => $ssl_cert, + 'ssl_key' => $ssl_key, + 'ssl_port' => $listen_ssl_port, + } + + # ensure the requires directories exist + $profiles::edgecache::params::directories.each |$name,$data| { + file { $name: + ensure => 'directory', + before => Class['nginx'], + mode => '0775', + * => $data, + } + } + + # merge the hashes conditionally + $nginx_parameters = merge($defaults, $extras_hash) + + # manage the nginx class + class { 'nginx': + proxy_cache_path => { + "${data_root}/cache" => 'cache:128m', + }, + proxy_cache_levels => '1:2', + proxy_cache_keys_zone => 'cache:128m', + proxy_cache_max_size => '30000m', + proxy_cache_inactive => '60d', + proxy_temp_path => "${data_root}/cache_tmp", + } + + # create the nginx vhost with the merged parameters + create_resources('nginx::resource::server', { $nginx_vhost => $nginx_parameters }) + + # create location mirrors + $profiles::edgecache::params::mirrors.each |$name, $data| { + nginx::resource::location { "${nginx_vhost}_${name}": + server => $nginx_vhost, + ssl => true, + ssl_only => false, + * => $data, + } + } +} diff --git a/site/profiles/manifests/edgecache/params.pp b/site/profiles/manifests/edgecache/params.pp new file mode 100644 index 0000000..0250e22 --- /dev/null +++ b/site/profiles/manifests/edgecache/params.pp @@ -0,0 +1,13 @@ +# profiles::edgecache::params +class profiles::edgecache::params ( + Stdlib::Absolutepath $data_root = '/data/edgecache', + Stdlib::Fqdn $nginx_vhost = $facts['networking']['fqdn'], + Array[Stdlib::Host] $nginx_aliases = [], + Stdlib::Port $nginx_port = 80, + Stdlib::Port $nginx_ssl_port = 443, + Enum['http','https','both'] $nginx_listen_mode = 'http', + Enum['puppet', 'vault'] $nginx_cert_type = 'vault', + Hash $directories = {}, + Hash $mirrors = {}, +){ +} diff --git a/site/profiles/manifests/edgecache/selinux.pp b/site/profiles/manifests/edgecache/selinux.pp new file mode 100644 index 0000000..c3b502b --- /dev/null +++ b/site/profiles/manifests/edgecache/selinux.pp @@ -0,0 +1,56 @@ +# profiles::edgecache::selinux +class profiles::edgecache::selinux { + + include profiles::edgecache::params + + $data_root = $profiles::edgecache::params::data_root + + if $::facts['os']['selinux']['config_mode'] == 'enforcing' { + + # set httpd_sys_content_t to all files under the www_root + selinux::fcontext { "${data_root}/pub": + ensure => 'present', + seltype => 'httpd_sys_content_t', + pathspec => "${data_root}/pub(/.*)?", + } + + # set httpd_sys_rw_content_t to all files under the cache_root + selinux::fcontext { "${data_root}/cache": + ensure => 'present', + seltype => 'httpd_sys_rw_content_t', + pathspec => "${data_root}/cache(/.*)?", + } + selinux::fcontext { "${data_root}/cache_tmp": + ensure => 'present', + seltype => 'httpd_sys_rw_content_t', + pathspec => "${data_root}/cache_tmp(/.*)?", + } + + # make sure we can connect to other hosts + selboolean { 'httpd_can_network_connect': + persistent => true, + value => 'on', + } + + exec { "restorecon_${data_root}/pub": + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'], + command => "restorecon -Rv ${data_root}/pub", + refreshonly => true, + subscribe => Selinux::Fcontext["${data_root}/pub"], + } + + exec { "restorecon_${data_root}/cache": + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'], + command => "restorecon -Rv ${data_root}/cache", + refreshonly => true, + subscribe => Selinux::Fcontext["${data_root}/cache"], + } + + exec { "restorecon_${data_root}/cache_tmp": + path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'], + command => "restorecon -Rv ${data_root}/cache_tmp", + refreshonly => true, + subscribe => Selinux::Fcontext["${data_root}/cache_tmp"], + } + } +} diff --git a/site/roles/manifests/infra/storage/edgecache.pp b/site/roles/manifests/infra/storage/edgecache.pp new file mode 100644 index 0000000..4ed8bf7 --- /dev/null +++ b/site/roles/manifests/infra/storage/edgecache.pp @@ -0,0 +1,7 @@ +# a role to deploy an edgecache +class roles::infra::storage::edgecache { + include profiles::defaults + include profiles::base + include profiles::base::datavol + include profiles::edgecache::init +}