feat: add haproxy profile

- add haproxy server class
- add haproxy profile to role
- add hiera data for region specific haproxy
- add selinux configuration
- add certlist management
- add default http and https frontends
- add default stats listener
This commit is contained in:
2024-01-05 22:47:37 +11:00
parent e15ebd4571
commit 2091f1ada3
15 changed files with 324 additions and 0 deletions
@@ -0,0 +1,19 @@
# profiles::haproxy::balancemember
define profiles::haproxy::balancemember (
String $service,
Array[Stdlib::Port] $ports,
Array $options = ['check'],
) {
$location_environment = "${facts['country']}-${facts['region']}-${facts['environment']}"
$balancemember_tag = "${service}_${location_environment}"
@@haproxy::balancermember { $balancemember_tag:
listening_service => $service,
ports => $ports,
server_names => $facts['networking']['hostname'],
ipaddresses => $facts['networking']['ip'],
options => $options,
tag => $balancemember_tag,
}
}
@@ -0,0 +1,18 @@
# profiles::haproxy::certlist
class profiles::haproxy::certlist (
Boolean $enabled = true,
Stdlib::Absolutepath $path = '/etc/haproxy/certificate.list',
Array[Stdlib::Absolutepath] $certificates = []
) {
if $enabled {
file { $path:
ensure => 'file',
owner => 'root',
group => 'root',
mode => '0600',
content => template('profiles/haproxy/certificate.list.erb')
}
}
}
@@ -0,0 +1,21 @@
# default http frontend
class profiles::haproxy::fe_http (
Stdlib::IP::Address $bind_addr = $facts['networking']['ip'],
Stdlib::Port $bind_port = 80,
Array $bind_opts = ['transparent'],
Array $acls = [],
Array $http_request = [],
) {
haproxy::frontend { 'fe_http':
description => 'Default HTTP Frontend',
bind => { "${bind_addr}:${bind_port}" => $bind_opts },
mode => 'http',
options => {
'acl' => $acls,
'http-request' => $http_request,
'use_backend' => [
'%[req.hdr(host),lower,map(/etc/haproxy/domains-to-backends.map,be_default)]',
],
},
}
}
@@ -0,0 +1,21 @@
# default https frontend
class profiles::haproxy::fe_https (
Stdlib::IP::Address $bind_addr = $facts['networking']['ip'],
Stdlib::Port $bind_port = 443,
Array $bind_opts = [],
Array $acls = [],
Array $http_request = [],
) {
haproxy::frontend { 'fe_https':
description => 'Default HTTPS Frontend',
bind => { "${bind_addr}:${bind_port}" => $bind_opts },
mode => 'http',
options => {
'acl' => $acls,
'http-request' => $http_request,
'use_backend' => [
'%[req.hdr(host),lower,map(/etc/haproxy/domains-to-backends.map,be_default)]',
],
},
}
}
@@ -0,0 +1,21 @@
# profiles::haproxy::listener
define profiles::haproxy::listener (
Boolean $bind = false,
Boolean $listen = false,
Enum['roundrobin', 'leastconn'] $balance = 'roundrobin',
Array $option = ['tcplog'],
Enum['tcp', 'http'] $mode = 'http',
Stdlib::Port $ports = 443,
) {
haproxy::listen { 'puppet00':
ipaddress => $facts['networking']['ip'],
ports => $ports,
mode => $mode,
options => {
'option' => $option,
'balance' => $balance,
},
}
}
@@ -0,0 +1,19 @@
# the default status listener
class profiles::haproxy::ls_stats (
Stdlib::IP::Address $bind_addr = $facts['networking']['ip'],
Stdlib::Port $bind_port = 9090,
Array $bind_opts = [],
String $user = 'admin',
String $pass = 'admin',
) {
haproxy::listen { 'stats':
bind => { "${bind_addr}:${bind_port}" => $bind_opts },
options => {
'mode' => 'http',
'stats' => [
'uri /',
"auth ${user}:${pass}",
],
},
}
}
@@ -0,0 +1,9 @@
# profiles::haproxy::mappings
class profiles::haproxy::mappings (
Array $list = []
) {
haproxy::mapfile { 'domains-to-backends':
ensure => 'present',
mappings => $list,
}
}
@@ -0,0 +1,32 @@
# profiles::haproxy::selinux
class profiles::haproxy::selinux (
Array[String] $sebooleans = [],
Array[Stdlib::Port] $ports = [],
) {
# manage enforcing mode
include profiles::selinux::setenforce
# manage selinux requirements for haproxy
if $::facts['os']['selinux']['config_mode'] == 'enforcing' {
# set context for ports
$ports.each |$port| {
selinux::port { "haproxy_port_${port}":
ensure => 'present',
seltype => 'http_port_t',
protocol => 'tcp',
port => $port,
}
}
# enable sebooleans
$sebooleans.each |$bool| {
selboolean { $bool:
value => on,
persistent => true,
}
}
}
}
+60
View File
@@ -0,0 +1,60 @@
# configure a haproxy server
class profiles::haproxy::server (
Hash $globals = {},
Hash $defaults = {},
){
# default global/defaults arrays
$global_options = {
'log' => "${facts['networking']['ip']} local0",
'chroot' => '/var/lib/haproxy',
'pidfile' => '/var/run/haproxy.pid',
'maxconn' => '4000',
'user' => 'haproxy',
'group' => 'haproxy',
'daemon' => '',
'stats' => 'socket /var/lib/haproxy/stats',
}
$default_options = {
'log' => 'global',
'stats' => 'enable',
'option' => ['redispatch'],
'retries' => '3',
'timeout' => [
'http-request 10s',
'queue 1m',
'connect 10s',
'client 1m',
'server 1m',
'check 10s',
],
'maxconn' => '8000',
}
# merge the default globals/defaults with those provided as params
$merged_global_options = merge($global_options, $globals)
$merged_default_options = merge($default_options, $defaults)
# manage selinux
include profiles::haproxy::selinux
# create the haproxy service/instance
class { 'haproxy':
global_options => $merged_global_options,
defaults_options => $merged_default_options,
require => Class['profiles::haproxy::selinux']
}
include profiles::haproxy::certlist # manage the certificate list file
include profiles::haproxy::mappings # manage the domain to backend mappings
include profiles::haproxy::ls_stats # default status listener
include profiles::haproxy::fe_http # default http frontend
include profiles::haproxy::fe_https # default https frontend
$backends = lookup('haproxy::backend').keys
$backends.each |$backend| {
$location_environment = "${facts['country']}-${facts['region']}-${facts['environment']}"
$tag = "${location_environment}_${backend}"
Haproxy::Balancermember <<| tag == $tag |>>
}
}
@@ -0,0 +1,3 @@
<% @certificates.each do |item| %>
<%= item %>
<% end %>
@@ -2,4 +2,5 @@
class roles::infra::halb::haproxy {
include profiles::defaults
include profiles::base
include profiles::haproxy::server
}