diff --git a/Puppetfile b/Puppetfile
index c197bde..f29fb47 100644
--- a/Puppetfile
+++ b/Puppetfile
@@ -7,14 +7,17 @@ mod 'puppetlabs-inifile', '6.0.0'
mod 'puppetlabs-concat', '9.0.0'
mod 'puppetlabs-vcsrepo', '6.1.0'
mod 'puppetlabs-yumrepo_core', '2.0.0'
-mod 'puppetlabs-apt', '9.1.0'
-mod 'puppetlabs-lvm', '2.0.3'
+mod 'puppetlabs-apt', '9.4.0'
+mod 'puppetlabs-lvm', '2.1.0'
mod 'puppetlabs-puppetdb', '7.13.0'
mod 'puppetlabs-postgresql', '9.1.0'
mod 'puppetlabs-firewall', '6.0.0'
mod 'puppetlabs-accounts', '8.1.0'
mod 'puppetlabs-mysql', '15.0.0'
mod 'puppetlabs-xinetd', '3.4.1'
+mod 'puppetlabs-haproxy', '8.0.0'
+mod 'puppetlabs-java', '10.1.2'
+mod 'puppetlabs-reboot', '5.0.0'
# puppet
mod 'puppet-python', '7.0.0'
@@ -27,13 +30,23 @@ mod 'puppet-nginx', '5.0.0'
mod 'puppet-selinux', '4.1.0'
mod 'puppet-prometheus', '13.4.0'
mod 'puppet-grafana', '13.1.0'
+mod 'puppet-consul', '8.0.0'
+mod 'puppet-vault', '4.1.0'
+mod 'puppet-dhcp', '6.1.0'
+mod 'puppet-keepalived', '3.6.0'
+mod 'puppet-extlib', '7.0.0'
# other
mod 'ghoneycutt-puppet', '3.3.0'
mod 'saz-sudo', '8.0.0'
+mod 'ghoneycutt-timezone', '4.0.0'
mod 'dalen-puppetdbquery', '3.0.1'
mod 'markt-galera', '3.1.0'
+mod 'kogitoapp-minio', '1.1.4'
+mod 'broadinstitute-certs', '3.0.1'
+mod 'stm-file_capability', '6.0.0'
+mod 'h0tw1r3-gitea', '3.2.0'
mod 'bind',
- :git => 'https://git.unkin.net/unkinben/puppet-bind.git',
+ :git => 'https://git.service.au-syd1.consul/unkinben/puppet-bind.git',
:tag => '1.0'
diff --git a/doc/vault/setup.md b/doc/vault/setup.md
new file mode 100644
index 0000000..1ec2ca2
--- /dev/null
+++ b/doc/vault/setup.md
@@ -0,0 +1,48 @@
+# root ca
+ vault secrets enable -path=pki_root pki
+
+ vault write -field=certificate pki_root/root/generate/internal \
+ common_name="unkin.net" \
+ issuer_name="unkinroot-2024" \
+ ttl=87600h > unkinroot_2024_ca.crt
+
+ vault read pki_root/issuer/$(vault list -format=json pki_root/issuers/ | jq -r '.[]') | tail -n 6
+
+ vault write pki_root/roles/2024-servers allow_any_name=true
+
+ vault write pki_root/config/urls \
+ issuing_certificates="$VAULT_ADDR/v1/pki_root/ca" \
+ crl_distribution_points="$VAULT_ADDR/v1/pki_root/crl"
+
+# intermediate
+ vault secrets enable -path=pki_int pki
+ vault secrets tune -max-lease-ttl=43800h pki_int
+
+ vault write -format=json pki_int/intermediate/generate/internal \
+ common_name="unkin.net Intermediate Authority" \
+ issuer_name="unkin-dot-net-intermediate" \
+ | jq -r '.data.csr' > pki_intermediate.csr
+
+ vault write -format=json pki_root/root/sign-intermediate \
+ issuer_ref="unkinroot-2024" \
+ csr=@pki_intermediate.csr \
+ format=pem_bundle ttl="43800h" \
+ | jq -r '.data.certificate' > intermediate.cert.pem
+
+ vault write pki_int/intermediate/set-signed certificate=@intermediate.cert.pem
+
+# create role
+ vault write pki_int/roles/unkin-dot-net \
+ issuer_ref="$(vault read -field=default pki_int/config/issuers)" \
+ allowed_domains="unkin.net" \
+ allow_subdomains=true \
+ max_ttl="2160h"
+
+# test generating a domain cert
+ vault write pki_int/issue/unkin-dot-net common_name="test.unkin.net" ttl="24h"
+ vault write pki_int/issue/unkin-dot-net common_name="test.main.unkin.net" ttl="24h"
+ vault write pki_int/issue/unkin-dot-net common_name="*.test.main.unkin.net" ttl="24h"
+
+
+# remove expired certificates
+ vault write pki_int/tidy tidy_cert_store=true tidy_revoked_certs=true
diff --git a/environment.conf b/environment.conf
index 19e7e87..0368a47 100644
--- a/environment.conf
+++ b/environment.conf
@@ -1,3 +1,3 @@
manifest = manifests/site.pp
-modulepath = external_modules:site
+modulepath = external_modules:modules:site
config_version = '/usr/bin/grep signature /etc/puppetlabs/code/environments/$environment/.g10k-deploy.json | /usr/bin/cut -d \" -f 4'
diff --git a/hiera.yaml b/hiera.yaml
index 3097474..d46d2ee 100644
--- a/hiera.yaml
+++ b/hiera.yaml
@@ -7,14 +7,29 @@ hierarchy:
- name: Consolidated Data
paths:
- "nodes/%{trusted.certname}.yaml"
+ - "country/%{::country}/region/%{::region}/%{::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.eyaml"
+ - "country/%{::country}/region/%{::region}/%{::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.yaml"
+ - "country/%{::country}/region/%{::region}/%{::enc_role_tier1}/%{::enc_role_tier2}.eyaml"
+ - "country/%{::country}/region/%{::region}/%{::enc_role_tier1}/%{::enc_role_tier2}.yaml"
+ - "country/%{::country}/region/%{::region}/%{::enc_role_tier1}.eyaml"
+ - "country/%{::country}/region/%{::region}/%{::enc_role_tier1}.yaml"
+ - "country/%{::country}/roles/%{::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.eyaml"
+ - "country/%{::country}/roles/%{::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.yaml"
+ - "country/%{::country}/roles/%{::enc_role_tier1}/%{::enc_role_tier2}.eyaml"
+ - "country/%{::country}/roles/%{::enc_role_tier1}/%{::enc_role_tier2}.yaml"
+ - "country/%{::country}/roles/%{::enc_role_tier1}.eyaml"
+ - "country/%{::country}/roles/%{::enc_role_tier1}.yaml"
+ - "country/%{::country}/region/%{::region}.eyaml"
+ - "country/%{::country}/region/%{::region}.yaml"
+ - "country/%{::country}.eyaml"
+ - "country/%{::country}.yaml"
+ - "roles/%{::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.eyaml"
+ - "roles/%{::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.yaml"
+ - "roles/%{::enc_role_tier1}/%{::enc_role_tier2}.eyaml"
+ - "roles/%{::enc_role_tier1}/%{::enc_role_tier2}.yaml"
- "roles/%{::enc_role_tier1}.eyaml"
- "roles/%{::enc_role_tier1}.yaml"
- - "roles/${::enc_role_tier1}/%{::enc_role_tier2}.eyaml"
- - "roles/${::enc_role_tier1}/%{::enc_role_tier2}.yaml"
- - "roles/${::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.eyaml"
- - "roles/${::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.yaml"
- - "%{::enc_role_path}.eyaml"
- - "%{::enc_role_path}.yaml"
+ - "virtual/%{facts.virtual}.yaml"
- "os/%{facts.os.name}/%{facts.os.name}%{facts.os.release.major}.yaml"
- "os/%{facts.os.name}/all_releases.yaml"
- "common.eyaml"
diff --git a/hieradata/common.eyaml b/hieradata/common.eyaml
new file mode 100644
index 0000000..a0d629d
--- /dev/null
+++ b/hieradata/common.eyaml
@@ -0,0 +1,8 @@
+---
+profiles::accounts::sysadmin::password: ENC[PKCS7,MIIBqQYJKoZIhvcNAQcDoIIBmjCCAZYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAoS7GyofFaXBNTWU+GtSiz4eCX/9j/sh3fDDRgOgNv1qpcQ87ZlTTenbHo9lxeURxKQ2HVVt7IsrBo/SC/WgipAKnliRkkIvo7nfAs+i+kEE8wakjAs0DcB4mhqtIZRuBkLG2Nay//DcG6cltVkbKEEKmKLMkDFZgTWreOZal8nDljpVe1S8QwtwP4/6hKTef5xsOnrisxuffWTXvwYJhj/VXrjdoH7EhtHGLybzEalglkVHEGft/WrrD/0bwJpmR0RegWI4HTsSvGiHgvf5DZJx8fXPZNPnicGtlfA9ccQPuVo17bY4Qf/WIc1A8Ssv4kHSbNIYJKRymI3UFb0Z4wzBsBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBBxDLb6pCGbittkcX6asd/gEBmMcUNupDjSECq5H09YA70eVwWWe0fBqxTxrr2cXCXtRKFvOk8SJmL0xHAWodaLN9+krTWHJcWbAK8JXEPC7rn]
+profiles::accounts::root::password: ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAM79PRxeAZHrDcSm4eSFqU94/LjuSbdUmJWivX/Pa8GumoW2e/PT9nGHW3p98zHthMgCglk52PECQ+TBKjxr+9dTyNK5ePG6ZJEqSHNRqsPGm+kfQj/hlTmq8vOBaFM5GapD1iTHs5JFbGngI56swKBEVXW9+Z37BjQb2xJuyLsu5Bo/tA0BaOKuCtjq1a6E38bOX+nJ+YF1uZgV9ofAEh1YvkcTmnEWYXFRPWd7AaNcWn03V2pfhGqxc+xydak620I47P+FE+qIY72+aQ6tmLU3X9vyA1HLF2Tv572l4a2i+YIk6nAgQdi+hQKznqNL9M9YV+s1AcmcKLT7cfLrjsjA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCMWrdCWBQgtW3NOEpERwP+gBA3KDiqe4pQq6DwRfsEXQNZ]
+profiles::consul::client::secret_id_salt: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAS7pNFRX4onccFaR87zB/eFFORuF22j6xqjyeAqqjgEduYhkt6w5kkz+YfUoHUesU0Q6F2p6HrCSZ8yAsx5M25NCiud9P4hIpjKmOZ4zCNO7uhATh4AQDYw3BrdRwfO+c6jOl5wOiNLCfDBJ0sFT3akCvcuPS1xIoRJq4Gyn+uCbOsMbvSl25ld2xKt1/cqs8gc1d8mkpjwWto7t+qZSUFMCehTbehH3G4a3Q5rvfBoNwv42Wbs676BDcCurDaAzHNqE7pDbOWhGuVOBl+q+BU0Ri/CRkGcTViN9fr8Dc9SveVC6EPsMbw+05/8/NlfzQse3KAwQ34nR9tR2PQw5qEzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBB7LywscQtF7cG2nomfEsu9gDDVqJBFP1jAX2eGZ2crYS5gnBcsRwhc0HNo2/WWdhZprMW+vEJOOGXDelI53NxA3o0=]
+profiles::consul::token::node_editor::secret_id: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAO8IIF2r18dFf0bVKEwjJUe1TmXHH0AIzsQHxkHwV7d37kvH1cY9rYw0TtdHn7GTxvotJG7GZbWvbunpBs1g2p2RPADiM6TMhbO8mJ0tAWLnMk7bQ221xu8Pc7KceqWmU17dmgNhVCohyfwJNqbA756TlHVgxGA0LtNrKoLOmgKGXAL1VYZoKEQnWq7xOpO+z3e1UfjoO6CvX/Od2hGYfUkHdro8mwRw4GFKzU7XeKFdAMUGpn5rVmY3xe+1ARXwGFaSrTHzk2n85pvwhPRlQ+OwqzyT19Qo2FNeAO6RoCRIFTtqbsjTWPUlseHIhw4Q5bHO1I0Mrlm5IHDESw/22IzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCEe9wD72qxnpeq5nCi/d7BgDCP29sDFObkFTabt2uZ/nF9MT1g+QOrrdFKgnG6ThnwH1hwpZPsSVgIs+yRQH8laB4=]
+profiles::consul::server::acl_tokens_initial_management: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAi1UH7AZirJ1PdxWy+KEgS5ufm0wbn2xy9rkg14hKYpcVjBa4pOZpSLMGMiiUpBIqBytDMZM4ezYa/luktpkBImJbM/TE16beGtsacQGA+9eZk2Tihs9GR2qbAQiu5lLITiDlwNnf0GeWdqHM8CTeD68DczQF320d9U14/k6pG/7z+w/MGLcjsQoSuOFTm42JVn1BI46t1CYSCHMXQc/9Tfs+FzI+vumohI8DxAYBIuyzU5HBX/MntAsvD/yixMJS1pZL9WwgqZJC/wK34rVRB39DpxWf/WROrI+WLuSJwr7WBjaeF9Ju+89WKCgsI53EWhFTj8GgDZm/jqPoE478NjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAoACRzJdQKNYXZv6cghFIIgDAzB81DMcuY815nb8POtZpiA06jT/068AoZmSctHoFK/zW9tY229N5r1Tb+WHElqLk=]
+profiles::consul::server::acl_tokens_default: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAh4Ag95xgkIZHL0gP9OLnZauih0dB1/2l9Jzw8mP3OiIv7fw23otHYONlS3Emtj7oxW8MKcZGKDCzwCT6T2p+V5wx1n15wr2J+FmL24VbclJwrMPQ4AdgP359B9h21uoyo7Zdy7RuuvLfkU1fWXbs3SeWbi2HJs1Ed1/oI1jzr3OgwMbVtbyzd1VuAXeZ9bHQG3IA8z+w/k5m61th0HTyHjw7eldQulbohDuwv545z9axHEoHKCRT2a3ZwBufV2ST6Dm3g9GERzXE9Adp9DQC5adqM74wfsujOMLK2QFJSSIOj2uCs1CpEnrNrQ8zjP3fudM2z3l7KdSHZazEamCSxTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBY/Tn9tzEKYc5dxnzP2rP7gDBWKgVP3lf2T4Q0WPQt3ns0E6RUSO6OtBegb/5qDyohY2nsDeJTnMKOYzYt/J1PhnY=]
+profiles::consul::server::acl_tokens_replication: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAEzTIxbaAR/TZYnC671aBhiahsfwf3ieyeSHpD5hQm40sMEF/fXlEDijq9i2ykPikm94074j1Uo4HNzv/V9GTf0NSC/64t61jJ/Ya3QKa5f/36+DcRj3lcETsSIyhWwmU+E+zkY8I2r68MtXAuvSoMSMZdpgWSkPx/3FFgZlrsg//bzDu69jS9cx4UK582N3A6QN4Uy/qwYtJcm+2iTQlqqgGRWGqnSgTirxhegxPbJGWTDoAEpAL4/DyF5/hqcUn6mgoSfAsHF3loPHOqN30lG+9o0THWJ9B8Gf4W/1X2UWA/avmUnqBnumGoz0p7AYdNgpW+qLl2rk4lyGYa4kvQjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBD9KSLH3Pn/1EIzgVJM+8VOgDDpKWzHfSVsfUMyTD0XIRPGclTdmxqCnsdhKNqmUfSjkYIf2nI9rQtSK6n42TYuO4k=]
diff --git a/hieradata/common.yaml b/hieradata/common.yaml
index 79f8edb..eda0ea1 100644
--- a/hieradata/common.yaml
+++ b/hieradata/common.yaml
@@ -1,13 +1,121 @@
---
lookup_options:
- profiles::packages::base::add:
+ hiera_classes:
merge:
strategy: deep
- profiles::packages::base::remove:
+ profiles::packages::install:
+ merge:
+ strategy: deep
+ profiles::packages::install_exclude:
+ merge:
+ strategy: deep
+ profiles::packages::remove:
+ merge:
+ strategy: deep
+ profiles::packages::remove_exclude:
+ merge:
+ strategy: deep
+ profiles::pki::vault::alt_names:
+ merge:
+ strategy: deep
+ profiles::pki::vault::ip_sans:
+ merge:
+ strategy: deep
+ profiles::yum::global::managed_repos:
+ merge:
+ strategy: deep
+ profiles::haproxy::server::defaults:
+ merge:
+ strategy: deep
+ profiles::haproxy::server::globals:
+ merge:
+ strategy: deep
+ profiles::haproxy::server::frontends:
+ merge:
+ strategy: deep
+ profiles::haproxy::server::backends:
+ merge:
+ strategy: deep
+ profiles::haproxy::server::mappings:
+ merge:
+ strategy: deep
+ profiles::haproxy::server::listeners:
+ merge:
+ strategy: deep
+ haproxy::backend:
+ merge:
+ strategy: deep
+ sudo::configs:
+ merge:
+ strategy: deep
+ profiles::base::groups::local:
+ merge:
+ strategy: deep
+ profiles::dns::resolver::zones:
+ merge:
+ strategy: deep
+ profiles::dns::resolver::acls:
+ merge:
+ strategy: deep
+ profiles::dns::resolver::views:
+ merge:
+ strategy: deep
+ profiles::dns::resolver::keys:
+ merge:
+ strategy: deep
+ profiles::dns::master::zones:
+ merge:
+ strategy: deep
+ profiles::dns::master::acls:
+ merge:
+ strategy: deep
+ profiles::dns::master::views:
+ merge:
+ strategy: deep
+ profiles::dns::master::keys:
+ merge:
+ strategy: deep
+ consul::services:
+ merge:
+ strategy: deep
+ consul::watch:
+ merge:
+ strategy: deep
+ consul::check:
+ merge:
+ strategy: deep
+ profiles::consul::client::node_rules:
+ merge:
+ strategy: deep
+ profiles::consul::prepared_query::rules:
+ merge:
+ strategy: deep
+ profiles::puppet::server::dns_alt_names:
+ merge:
+ strategy: deep
+ profiles::puppet::client::dns_alt_names:
+ merge:
+ strategy: deep
+ profiles::base::hosts::additional_hosts:
+ merge:
+ strategy: deep
+ postgresql_config_entries:
+ merge:
+ strategy: deep
+ profiles::yum::global::repos:
+ merge:
+ strategy: deep
+ profiles::nginx::simpleproxy::nginx_aliases:
merge:
strategy: deep
+facts_path: '/opt/puppetlabs/facter/facts.d'
+
+hiera_classes:
+ - timezone
+
profiles::ntp::client::ntp_role: 'roles::infra::ntp::server'
+profiles::ntp::client::use_ntp: 'region'
profiles::ntp::client::peers:
- 0.pool.ntp.org
- 1.pool.ntp.org
@@ -19,20 +127,36 @@ profiles::base::puppet_servers:
profiles::dns::master::basedir: '/var/named/sources'
profiles::dns::base::ns_role: 'roles::infra::dns::resolver'
+profiles::dns::base::use_ns: 'region'
+profiles::consul::server::members_role: roles::infra::storage::consul
+profiles::consul::token::node_editor::accessor_id: '024e27bd-c5bb-41e7-a578-b766509e11bc'
+profiles::consul::client::members_lookup: true
+profiles::consul::client::members_role: roles::infra::storage::consul
+profiles::consul::client::node_rules:
+ - resource: node
+ segment: "%{facts.networking.hostname}"
+ disposition: write
+ - resource: node
+ segment: "%{facts.networking.fqdn}"
+ disposition: write
+ - resource: node
+ segment: ''
+ disposition: read
-profiles::packages::base::add:
+profiles::packages::install:
- bash-completion
- bzip2
- ccze
- curl
- dstat
+ - expect
- gzip
+ - git
- htop
- inotify-tools
- iotop
- jq
- lz4
- - lzo
- mtr
- ncdu
- neovim
@@ -40,6 +164,7 @@ profiles::packages::base::add:
- pbzip2
- pigz
- pv
+ - python3.11
- rsync
- screen
- socat
@@ -47,14 +172,14 @@ profiles::packages::base::add:
- sysstat
- tmux
- traceroute
+ - unzip
- vim
- vnstat
- wget
- - xz
- zsh
- zstd
-profiles::packages::base::remove:
+profiles::packages::remove:
- iwl100-firmware
- iwl1000-firmware
- iwl105-firmware
@@ -73,15 +198,36 @@ profiles::packages::base::remove:
profiles::base::scripts::scripts:
puppet: puppetwrapper.py
+profiles::puppet::client::server: 'puppet.query.consul'
+profiles::puppet::client::ca_server: 'puppetca.query.consul'
profiles::puppet::client::environment: 'develop'
profiles::puppet::client::runinterval: 1800
profiles::puppet::client::runtimeout: 3600
profiles::puppet::client::show_diff: true
profiles::puppet::client::usecacheonfailure: false
+profiles::puppet::client::dns_alt_names:
+ - "%{trusted.certname}"
+
+# puppetdb
+puppetdbapi: puppetdbapi.query.consul
+puppetdbsql: puppetdbsql.service.au-syd1.consul
prometheus::node_exporter::export_scrape_job: true
prometheus::systemd_exporter::export_scrape_job: true
+profiles::base::groups::local:
+ admins:
+ ensure: present
+ gid: 10000
+ allowdupe: false
+ forcelocal: true
+
+sudo::configs:
+ admins:
+ priority: 10
+ content: |
+ %admins ALL=(ALL) NOPASSWD: ALL
+
profiles::accounts::sysadmin::sshkeys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZ8SRLlPiDylBpdWR9LpvPg4fDVD+DZst4yRPFwMMhta4mnB1H9XuvZkptDhXywWQ7QIcqa2WbhCen0OQJCtwn3s7EYtacmF5MxmwBYocPoK2AArGuh6NA9rwTdLrPdzhZ+gwe88PAzRLNzjm0ZBR+mA9saMbPJdqpKp0AWeAM8QofRQAWuCzQg9i0Pn1KDMvVDRHCZof4pVlHSTyHNektq4ifovn0zhKC8jD/cYu95mc5ftBbORexpGiQWwQ3HZw1IBe0ZETB1qPIPwsoJpt3suvMrL6T2//fcIIUE3TcyJKb/yhztja4TZs5jT8370G/vhlT70He0YPxqHub8ZfBv0khlkY93VBWYpNGJwM1fVqlw7XbfBNdOuJivJac8eW317ZdiDnKkBTxapThpPG3et9ib1HoPGKRsd/fICzNz16h2R3tddSdihTFL+bmTCa6Lo+5t5uRuFjQvhSLSgO2/gRAprc3scYOB4pY/lxOFfq3pU2VvSJtRgLNEYMUYKk= ben@unkin.net
@@ -97,7 +243,6 @@ profiles::base::hosts::additional_hosts:
hostname: prodinf01n04.main.unkin.net
aliases:
- prodinf01n04
- - puppetdb
- ip: 198.18.17.5
hostname: prodinf01n05.main.unkin.net
aliases:
diff --git a/hieradata/country/au/region/drw1.yaml b/hieradata/country/au/region/drw1.yaml
new file mode 100644
index 0000000..703d863
--- /dev/null
+++ b/hieradata/country/au/region/drw1.yaml
@@ -0,0 +1,2 @@
+---
+timezone::timezone: 'Australia/Darwin'
diff --git a/hieradata/country/au/region/drw1/infra/dns/resolver.yaml b/hieradata/country/au/region/drw1/infra/dns/resolver.yaml
new file mode 100644
index 0000000..157667c
--- /dev/null
+++ b/hieradata/country/au/region/drw1/infra/dns/resolver.yaml
@@ -0,0 +1,52 @@
+---
+profiles::dns::resolver::zones:
+ main.unkin.net-forward:
+ domain: 'main.unkin.net'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.17.23
+ - 198.18.17.24
+ forward: 'only'
+ 13.18.198.in-addr.arpa-forward:
+ domain: '13.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.17.23
+ - 198.18.17.24
+ forward: 'only'
+ 14.18.198.in-addr.arpa-forward:
+ domain: '14.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.17.23
+ - 198.18.17.24
+ forward: 'only'
+ 15.18.198.in-addr.arpa-forward:
+ domain: '15.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.17.23
+ - 198.18.17.24
+ forward: 'only'
+ 16.18.198.in-addr.arpa-forward:
+ domain: '16.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.17.23
+ - 198.18.17.24
+ forward: 'only'
+ 17.18.198.in-addr.arpa-forward:
+ domain: '17.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.17.23
+ - 198.18.17.24
+ forward: 'only'
+ consul-forward:
+ domain: 'consul'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.17.34
+ - 198.18.17.35
+ - 198.18.17.36
+ forward: 'only'
diff --git a/hieradata/country/au/region/drw1/infra/halb/haproxy.yaml b/hieradata/country/au/region/drw1/infra/halb/haproxy.yaml
new file mode 100644
index 0000000..2ac28f7
--- /dev/null
+++ b/hieradata/country/au/region/drw1/infra/halb/haproxy.yaml
@@ -0,0 +1,65 @@
+---
+# mappings
+profiles::haproxy::mappings:
+ fe_http:
+ ensure: present
+ mappings:
+ - 'puppetboard.main.unkin.net be_puppetboard'
+ - 'puppetdbapi.main.unkin.net be_puppetdbapi'
+ fe_https:
+ ensure: present
+ mappings:
+ - 'puppetboard.main.unkin.net be_puppetboard'
+ - 'puppetdbapi.main.unkin.net be_puppetdbapi'
+
+profiles::haproxy::frontends:
+ fe_http:
+ options:
+ use_backend:
+ - "%[req.hdr(host),lower,map(/etc/haproxy/fe_http.map,be_default)]"
+ fe_https:
+ options:
+ use_backend:
+ - "%[req.hdr(host),lower,map(/etc/haproxy/fe_https.map,be_default)]"
+
+profiles::haproxy::backends:
+ be_puppetboard:
+ description: Backend for Puppetboard
+ collect_exported: false # handled in custom function
+ options:
+ balance: roundrobin
+ option:
+ - httpchk GET /
+ - forwardfor
+ cookie: SRVNAME insert
+ http-request:
+ - set-header X-Forwarded-Port %[dst_port]
+ - add-header X-Forwarded-Proto https if { dst_port 443 }
+ redirect: 'scheme https if !{ ssl_fc }'
+ be_puppetdbapi:
+ description: Backend for the PuppetDB API
+ collect_exported: false # handled in custom function
+ options:
+ balance: roundrobin
+ option:
+ - httpchk GET /
+ - forwardfor
+ cookie: SRVNAME insert
+ http-request:
+ - set-header X-Forwarded-Port %[dst_port]
+ - add-header X-Forwarded-Proto https if { dst_port 443 }
+ redirect: 'scheme https if !{ ssl_fc }'
+
+profiles::haproxy::certlist::enabled: true
+profiles::haproxy::certlist::certificates:
+ - /etc/pki/tls/vault/certificate.pem
+
+# additional altnames
+profiles::pki::vault::alt_names:
+ - puppetboard.main.unkin.net
+ - puppetdbapi.main.unkin.net
+
+# additional cnames
+profiles::haproxy::dns::cnames:
+ - puppetboard.main.unkin.net
+ - puppetdbapi.main.unkin.net
diff --git a/hieradata/country/au/region/drw1/infra/puppet/master.eyaml b/hieradata/country/au/region/drw1/infra/puppet/master.eyaml
new file mode 100644
index 0000000..1dea3a5
--- /dev/null
+++ b/hieradata/country/au/region/drw1/infra/puppet/master.eyaml
@@ -0,0 +1,3 @@
+---
+certmanager::vault_token: ENC[PKCS7,MIIBygYJKoZIhvcNAQcDoIIBuzCCAbcCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAWh7bsttz/JCBo/CPoCgA2doo3jO6jT6NsOoE3/06W2IW+Ij6KHKYILMkG3tS4NAegMI48QR9n++4Xa7u+97w1HO4ENpfLrkuKUcWUFCxxb2OdWhxucIlt3Ay/2+tofOSvqiRKeEISBtOK//Q1a4Iu5GwEP+lvDQ5rcoS0dryNie/okXaLratWOsmctJ6LFuUw5siCcFyUzfvr2ROsB14YoF989np+X1dJqBWxcLmbVNKx766GrRhb1WGeF0qxounCmWEKGt0zY4Zk27KNFlFu7XByDWZoSCVCMvkQaRKhvdNA39Y9vscZJGPGFhz+qKPoeqwUidz0IY51CaFSXewmzCBjAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQC+e2iOlFLlr9inVU8nEVWIBgqb0u/ICsLtxZqOpN9OIFWl+4hVrvTo24JzTc1jMSCONeL4Ab7jtTMbsweE9zUf6XlwhHLXfxfg7FL3WBsOWCUBXIAh338cZCXUGX7m0Qvtgg3VTEbTNDJhZle8Sjo6Gl]
+certmanager::role_id: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAJuE+uzgQaBRUXBCigckEo1j+UxxbiUGrzdf/B9K7XPdVxZh6TzYLpBgNnyaT6vLo0boX4uRD/By0gT5R/2qcXD6d/j+fh517Ctk4d2uO64f0vH3PzyyOBalsNtcCdPiV3q/xGqzQSHhPiNkFEjDvMBz5p53UjfKA6gAiPrLklp4rN/NVyiLBw20NeIqbL25VdkQa13ViS0Gm/eUQu7a2xQ1dvQFWWfuLaQxO0dh8L0ynkfmWKIjaiD5412Z8hYURu0otxbqVDdIbEMx5xQsXnFKeN93yHmgs7a7M6fLdp9jh+G8B+IlK1W7/9v2+RT0/yI3ZgWHVTvDRhMHuPGBjfTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBC5avtOPp9N65U1ILQENnvAgDBqI8XAjqbWIvXHqOEiKYdu+co0EEtsHR1v5xAeCmj/ZA6MLeKFlAVJbvpyCpzjons=]
diff --git a/hieradata/country/au/region/drw1/infra/puppet/master.yaml b/hieradata/country/au/region/drw1/infra/puppet/master.yaml
new file mode 100644
index 0000000..1b3d42c
--- /dev/null
+++ b/hieradata/country/au/region/drw1/infra/puppet/master.yaml
@@ -0,0 +1,4 @@
+---
+profiles::puppet::server::dns_alt_names:
+ - puppetca.main.unkin.net
+ - puppetca
diff --git a/hieradata/country/au/region/drw1/infra/storage/consul.eyaml b/hieradata/country/au/region/drw1/infra/storage/consul.eyaml
new file mode 100644
index 0000000..33b5046
--- /dev/null
+++ b/hieradata/country/au/region/drw1/infra/storage/consul.eyaml
@@ -0,0 +1,4 @@
+---
+profiles::consul::server::gossip_key: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEADwwYLK+fU0M/uLqQpRjHnIAyrt6yPEZSXpUX2jvOGVOA63X8LOYpLVfEGWMmkZ7BHRO0fgr847UUI/xI8otIuiOpgtW2E7QLWs806KUNXz+L8c7kSnQ1XAD5R81/5joDHl4AIxl5fAGryTXH1gfnpTMWh2yjFzU/KYuk2GhrU0M9ewCGJErQG4pT4u3ymGmkLjx6AiZ8r9xb4Eos2bhCCpFWfyb0kKcJqdKU9mzy508byNCfp8lr1DoKxEQrdqSSAQdepn6wCgBZtlAK/k63tOqM9dxyDaCsK8vLG9LlvuEwi3OL2lzTtc1mAcdYxahDo3uBX0/VcCswaXq3nPnu3TBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCUwXPoMh/dylvFwyRzAsnRgDDvh5CHrzJYdUXWGsauYlifOOukYokkwG3yqqtCByveMqVWfWsQukiDTixdqpCgfzw=]
+#profiles::consul::server::acl_tokens_initial_management: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAi1UH7AZirJ1PdxWy+KEgS5ufm0wbn2xy9rkg14hKYpcVjBa4pOZpSLMGMiiUpBIqBytDMZM4ezYa/luktpkBImJbM/TE16beGtsacQGA+9eZk2Tihs9GR2qbAQiu5lLITiDlwNnf0GeWdqHM8CTeD68DczQF320d9U14/k6pG/7z+w/MGLcjsQoSuOFTm42JVn1BI46t1CYSCHMXQc/9Tfs+FzI+vumohI8DxAYBIuyzU5HBX/MntAsvD/yixMJS1pZL9WwgqZJC/wK34rVRB39DpxWf/WROrI+WLuSJwr7WBjaeF9Ju+89WKCgsI53EWhFTj8GgDZm/jqPoE478NjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAoACRzJdQKNYXZv6cghFIIgDAzB81DMcuY815nb8POtZpiA06jT/068AoZmSctHoFK/zW9tY229N5r1Tb+WHElqLk=]
+#profiles::consul::server::acl_tokens_default: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAPRZN7DnYUhVL81p7xC9rUYPutoO3UrF2Sl8DlopfYoAG9omnXZlrut8wIffDZJSiU5XkOGv8x2QsXZc+bWqiplJ0VfzLClxEM2onWaT/GGGg7E+2YhrYuMG7mZYaqRYQ6/AgLDcIMBIdQBdL5mlpy+fVZn7Mu4cmsQYJTIe+yrNQtGMWMiNaHpwLGXvoXgwT6giX6L6VNiN51dAnHAdMYZ9Hf3G5CZEs6x8uOveqf6+qy+df24ItRUcsfQlSwsEaQRY+xjIVYIoiV8l8D8HiO+mVqbxtfQgyJIMv+0hl95zHGlc2W5lb6MvIFcJGu2xKIc00D7YOYgxLUx1aegixxzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBnYSZmhDFSDoO1s329ktFegDC2Z7A+TGqTtZXKXaj2qQmowIvTZOVoUyF/5G0aED0wo/h+vfgosSS3Tx1dam0KUl0=]
diff --git a/hieradata/country/au/region/drw1/infra/storage/consul.yaml b/hieradata/country/au/region/drw1/infra/storage/consul.yaml
new file mode 100644
index 0000000..b44e321
--- /dev/null
+++ b/hieradata/country/au/region/drw1/infra/storage/consul.yaml
@@ -0,0 +1,7 @@
+---
+profiles::consul::server::bootstrap_count: 3
+profiles::consul::server::raft_multiplier: 10
+profiles::consul::server::primary_datacenter: 'au-syd1'
+profiles::consul::server::join_remote_regions: true
+profiles::consul::server::remote_regions:
+ - syd1
diff --git a/hieradata/country/au/region/drw1/infra/storage/minio.yaml b/hieradata/country/au/region/drw1/infra/storage/minio.yaml
new file mode 100644
index 0000000..1b428c1
--- /dev/null
+++ b/hieradata/country/au/region/drw1/infra/storage/minio.yaml
@@ -0,0 +1,6 @@
+---
+profiles::minio::server::minio_members: 5
+profiles::minio::server::blockdev:
+ - /dev/sda
+ - /dev/sdb
+profiles::minio::server::minio_storage_class: 'EC:2'
diff --git a/hieradata/country/au/region/drw1/infra/storage/vault.eyaml b/hieradata/country/au/region/drw1/infra/storage/vault.eyaml
new file mode 100644
index 0000000..11fff31
--- /dev/null
+++ b/hieradata/country/au/region/drw1/infra/storage/vault.eyaml
@@ -0,0 +1,7 @@
+---
+vault::unseal_keys:
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAHfDhuu2C5ZEALdJlmOqWukEiAQQiVJ7KjpSRuf9h7RYwR+u8UNdcJYK1xFvYwmUczw6hkST/Zr06T4JwavpAHHuaRbyl8N1qZjlwt4MO5CPUTBT8k+EOaocF2byUXpYBThETjLB+WNLJAU3Dq8JboekCJ2F1Zjd8Mmdtu1C3Ip5ii5iVGbQShxDSPsdjtk8Q49lUKj61tLyuvadcTcxllHyXs6siWl7atBfIS6OX5KgA66VJhxOeoyyBaiqSSu7OqqZa2siYGTvjJS3UFDf8J+itsJJ1+0KUtkl07PvItkIruSAlHZGagVPrizAyEx1j4hFvVTGHac86bcV/5M9z5DBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDCjxoJHSXr/4XvXaxVbUGOgDCQ4DL05Qnw3+3qHWZRKvNChHgrhRPi2HmkiGni+A4ZVF9LHs+mF8TQ/t3Q1DrSy3I=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAoapLUNj1f+7BEvjzR9CO0Qz3LhI5M326BVliikRY7hpL2+0CnTOlR9K3YapD83LtpuiNbXqbk1mhi44ak0CTet8yz0ZH/BPkVYgV2Ll9ISdN4Knnnlf2Ljt/gHGf03jiUKwfXxu87LfvCySAMgzYonQ90cfIDc+XH6CoQv27WM3U1q79RcWl/w9Z/XwJiKyANSCXfBT16+RawrzmVo+zWbteqx09MfOHr7Q36VwOqjJaO94A/Dj3m/YJIOhmYXd52h+am6Kc1Q9dnzycKZYoKYOv+qi+bY4frx9sRvBxoGDGMb1mXTDSPeIT6NXbMCIsTsmYxjxAvBET72oKWXJUcDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDy/pkTHpz4F9l1J6cKW4A9gDD873VdHr3ArjpE1R82wS5brCbBe7ntEuNFQMbnFPvOXwI4EaYV3IMRNv6Lzk6BBSI=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAVKVb6/nhbgEx6b2b90gfuXbZglZpoJjQtyzDQtCZzcZxh/xVFjwUy1XX/3+dueazFd5Ge5NnqQdxs/h5MBSjexHJhEm3fmA+gnns8sdYX5SDJSnhYvS1cB/wmfHuvkj3ZhIFxg0jlPlKz24QST99ouxKI2c490ByIbcFCr+A5GWnO7D/kf1Y+M0Sg2YiPE4zqF2zx1sgOfaV2xvQbRqqSjDPim/mYff95AtWwN9KbcAvc/7vDi4PrHR8GY9RXhI8FBEvelAT0H0NmnaCw4TvWXF/YxztlG9E55G3MsFyVAQJT7Dl8w4w5nk4AJJBMaXlO2s4AWD4Y+MVQh62hjqgHjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBptatyhSChU/V0R+IVd5hRgDCmA07/V4UBz1nVMc2vZm2KvnUOPofO74hwkkoxOnk6O2h6arbw8GNHj7WxeHXoXPk=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAOGvhPhbKt8hkYTif5C+IE7iqcoeXm68BeUzlzE9qAY7lzQoAENauDKoIgoQT0hA7zrKZXPTUDrcw8SdxNp7Zo/Dr44urdr4LiT+QZwYTE09Xn8yIA3ij1XnXQ5bYP70TycuOjpVT0BKK+qSkklfd7IAw76AnUWF1D6P9MjT+shOmVNHQQSRrL2JLNppetQRCyOEMzkeDI/58/ohexvyUcY8WT4YMNhl/IrNBdcJ3xOwnJqEAXSUTre15T2I+7f+prhj4cS2V9qd0ZwUXSueL38EIMKwmq1ugb+zm8UYzqfKpRk/1THqT8T/r8B4PR2QxtiwtzLk388ag1mqQ/jHL9zBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAlKLuJOARFD1vt/R9gfp4LgDA0irHwG41ByRyYcKT87ra9tsdhb+i9ugnNRbFQ1UPTk7bFwS3HUteEJwNzcNIwFXY=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAEQvjVATvI+UVWrowTWSxtluiPrfa8akOSgr+MdcAh5Mgypw6RUeVJ2Sh8jekePZOO7Y0IQSfyNWOFAsaxBgeG7aEu6loFwxcSzrilg9c/2bV7Ybxr5saDViTjHO+UOYPPVRsJKeYvWd+vTdM+J7Eg3LGwzdLqyYu824affGm41KsSJdtxbNC1EzR+AOEU7SO8FkDIUZl2ekwz+3FfBX5TyXywlZGrbS7DkABB1jrO/JJtgnRu4D1AgUWjSJINXKyi9Xf91ZUyYCbVJ1asmRhOcCDcRigs82CF6nWbsSad80Z/ZoGVGYSlCsSXd4t8iEujCzeTkfBRK6Azr71f0zbBjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAeR7zOfSz3Sd19UkcmdMJLgDBiPUNdk6zh2inhCqms/qnt7BqDBAYEzHuzbsM3U3PO+UIeJdym51cu3YKw3MkVuyw=]
diff --git a/hieradata/country/au/region/drw1/infra/storage/vault.yaml b/hieradata/country/au/region/drw1/infra/storage/vault.yaml
new file mode 100644
index 0000000..3994ded
--- /dev/null
+++ b/hieradata/country/au/region/drw1/infra/storage/vault.yaml
@@ -0,0 +1,9 @@
+---
+# additional altnames
+profiles::pki::vault::alt_names:
+ - vault.service.au-drw1.consul
+
+profiles::nginx::simpleproxy::nginx_aliases:
+ - vault.service.au-drw1.consul
+
+profiles::vault::server::primary_datacenter: 'au-drw1'
diff --git a/hieradata/country/au/region/syd1.yaml b/hieradata/country/au/region/syd1.yaml
new file mode 100644
index 0000000..2a744b7
--- /dev/null
+++ b/hieradata/country/au/region/syd1.yaml
@@ -0,0 +1,2 @@
+---
+timezone::timezone: 'Australia/Sydney'
diff --git a/hieradata/country/au/region/syd1/infra/dns/resolver.yaml b/hieradata/country/au/region/syd1/infra/dns/resolver.yaml
new file mode 100644
index 0000000..088f065
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/dns/resolver.yaml
@@ -0,0 +1,52 @@
+---
+profiles::dns::resolver::zones:
+ main.unkin.net-forward:
+ domain: 'main.unkin.net'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.13.14
+ - 198.18.13.15
+ forward: 'only'
+ 13.18.198.in-addr.arpa-forward:
+ domain: '13.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.13.14
+ - 198.18.13.15
+ forward: 'only'
+ 14.18.198.in-addr.arpa-forward:
+ domain: '14.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.13.14
+ - 198.18.13.15
+ forward: 'only'
+ 15.18.198.in-addr.arpa-forward:
+ domain: '15.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.13.14
+ - 198.18.13.15
+ forward: 'only'
+ 16.18.198.in-addr.arpa-forward:
+ domain: '16.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.13.14
+ - 198.18.13.15
+ forward: 'only'
+ 17.18.198.in-addr.arpa-forward:
+ domain: '17.18.198.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.13.14
+ - 198.18.13.15
+ forward: 'only'
+ consul-forward:
+ domain: 'consul'
+ zone_type: 'forward'
+ forwarders:
+ - 198.18.13.19
+ - 198.18.13.20
+ - 198.18.13.21
+ forward: 'only'
diff --git a/hieradata/country/au/region/syd1/infra/halb/haproxy.yaml b/hieradata/country/au/region/syd1/infra/halb/haproxy.yaml
new file mode 100644
index 0000000..c7877aa
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/halb/haproxy.yaml
@@ -0,0 +1,79 @@
+---
+# mappings
+profiles::haproxy::mappings:
+ fe_http:
+ ensure: present
+ mappings:
+ - 'au-syd1-pve.main.unkin.net be_ausyd1pve_web'
+ - 'au-syd1-pve-api.main.unkin.net be_ausyd1pve_api'
+ fe_https:
+ ensure: present
+ mappings:
+ - 'au-syd1-pve.main.unkin.net be_ausyd1pve_web'
+ - 'au-syd1-pve-api.main.unkin.net be_ausyd1pve_api'
+
+profiles::haproxy::frontends:
+ fe_http:
+ options:
+ use_backend:
+ - "%[req.hdr(host),lower,map(/etc/haproxy/fe_http.map,be_default)]"
+ fe_https:
+ options:
+ acl:
+ - 'acl_ausyd1pve req.hdr(host) -i https://au-syd1-pve.main.unkin.net'
+ - 'acl_internalsubnets src 198.18.0.0/16 10.10.12.0/24'
+ use_backend:
+ - "%[req.hdr(host),lower,map(/etc/haproxy/fe_https.map,be_default)]"
+ http-request:
+ - 'deny if { hdr_dom(host) -i au-syd1-pve.main.unkin.net } !acl_internalsubnets'
+ http-response:
+ - 'set-header X-Frame-Options DENY if acl_ausyd1pve'
+ - 'set-header X-Content-Type-Options nosniff'
+ - 'set-header X-XSS-Protection 1;mode=block'
+
+profiles::haproxy::backends:
+ be_ausyd1pve_web:
+ description: Backend for au-syd1 pve cluster (Web)
+ collect_exported: false # handled in custom function
+ options:
+ balance: roundrobin
+ option:
+ - httpchk GET /
+ - forwardfor
+ - http-keep-alive
+ - prefer-last-server
+ cookie: SRVNAME insert indirect nocache
+ http-reuse: always
+ http-request:
+ - set-header X-Forwarded-Port %[dst_port]
+ - add-header X-Forwarded-Proto https if { dst_port 443 }
+ redirect: 'scheme https if !{ ssl_fc }'
+ be_ausyd1pve_api:
+ description: Backend for au-syd1 pve cluster (API only)
+ collect_exported: false # handled in custom function
+ options:
+ balance: roundrobin
+ option:
+ - httpchk GET /
+ - forwardfor
+ - http-keep-alive
+ - prefer-last-server
+ http-reuse: always
+ http-request:
+ - set-header X-Forwarded-Port %[dst_port]
+ - add-header X-Forwarded-Proto https if { dst_port 443 }
+ redirect: 'scheme https if !{ ssl_fc }'
+
+profiles::haproxy::certlist::enabled: true
+profiles::haproxy::certlist::certificates:
+ - /etc/pki/tls/vault/certificate.pem
+
+# additional altnames
+profiles::pki::vault::alt_names:
+ - au-syd1-pve.main.unkin.net
+ - au-syd1-pve-api.main.unkin.net
+
+# additional cnames
+profiles::haproxy::dns::cnames:
+ - au-syd1-pve.main.unkin.net
+ - au-syd1-pve-api.main.unkin.net
diff --git a/hieradata/country/au/region/syd1/infra/proxmox.yaml b/hieradata/country/au/region/syd1/infra/proxmox.yaml
new file mode 100644
index 0000000..5e07a1c
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/proxmox.yaml
@@ -0,0 +1,8 @@
+---
+profiles::proxmox::params::pve_members_role: 'roles::infra::proxmox::node'
+profiles::proxmox::params::pve_kernel_version: '1.0.1'
+profiles::proxmox::params::pve_kernel_release: '6.5.13-5-pve'
+profiles::proxmox::params::pve_ceph_repos: true
+profiles::proxmox::params::pve_ceph_release: 'reef'
+profiles::proxmox::params::pve_ceph_install: true
+profiles::proxmox::params::pve_ceph_network: '10.18.15.1/24'
diff --git a/hieradata/country/au/region/syd1/infra/puppet/master.eyaml b/hieradata/country/au/region/syd1/infra/puppet/master.eyaml
new file mode 100644
index 0000000..a6c1883
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/puppet/master.eyaml
@@ -0,0 +1,3 @@
+---
+certmanager::vault_token: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAJuE+uzgQaBRUXBCigckEo1j+UxxbiUGrzdf/B9K7XPdVxZh6TzYLpBgNnyaT6vLo0boX4uRD/By0gT5R/2qcXD6d/j+fh517Ctk4d2uO64f0vH3PzyyOBalsNtcCdPiV3q/xGqzQSHhPiNkFEjDvMBz5p53UjfKA6gAiPrLklp4rN/NVyiLBw20NeIqbL25VdkQa13ViS0Gm/eUQu7a2xQ1dvQFWWfuLaQxO0dh8L0ynkfmWKIjaiD5412Z8hYURu0otxbqVDdIbEMx5xQsXnFKeN93yHmgs7a7M6fLdp9jh+G8B+IlK1W7/9v2+RT0/yI3ZgWHVTvDRhMHuPGBjfTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBC5avtOPp9N65U1ILQENnvAgDBqI8XAjqbWIvXHqOEiKYdu+co0EEtsHR1v5xAeCmj/ZA6MLeKFlAVJbvpyCpzjons=]
+certmanager::role_id: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAJuE+uzgQaBRUXBCigckEo1j+UxxbiUGrzdf/B9K7XPdVxZh6TzYLpBgNnyaT6vLo0boX4uRD/By0gT5R/2qcXD6d/j+fh517Ctk4d2uO64f0vH3PzyyOBalsNtcCdPiV3q/xGqzQSHhPiNkFEjDvMBz5p53UjfKA6gAiPrLklp4rN/NVyiLBw20NeIqbL25VdkQa13ViS0Gm/eUQu7a2xQ1dvQFWWfuLaQxO0dh8L0ynkfmWKIjaiD5412Z8hYURu0otxbqVDdIbEMx5xQsXnFKeN93yHmgs7a7M6fLdp9jh+G8B+IlK1W7/9v2+RT0/yI3ZgWHVTvDRhMHuPGBjfTBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBC5avtOPp9N65U1ILQENnvAgDBqI8XAjqbWIvXHqOEiKYdu+co0EEtsHR1v5xAeCmj/ZA6MLeKFlAVJbvpyCpzjons=]
diff --git a/hieradata/country/au/region/syd1/infra/puppet/master.yaml b/hieradata/country/au/region/syd1/infra/puppet/master.yaml
new file mode 100644
index 0000000..1b3d42c
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/puppet/master.yaml
@@ -0,0 +1,4 @@
+---
+profiles::puppet::server::dns_alt_names:
+ - puppetca.main.unkin.net
+ - puppetca
diff --git a/hieradata/country/au/region/syd1/infra/sql/galera.yaml b/hieradata/country/au/region/syd1/infra/sql/galera.yaml
new file mode 100644
index 0000000..9c4119c
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/sql/galera.yaml
@@ -0,0 +1,4 @@
+---
+profiles::sql::galera_member::cluster_name: au-syd1
+profiles::sql::galera_member::galera_master: ausyd1nxvm1027.main.unkin.net
+profiles::sql::galera_member::innodb_buffer_pool_size: 256M
diff --git a/hieradata/country/au/region/syd1/infra/storage/consul.eyaml b/hieradata/country/au/region/syd1/infra/storage/consul.eyaml
new file mode 100644
index 0000000..fd508a6
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/storage/consul.eyaml
@@ -0,0 +1,2 @@
+---
+profiles::consul::server::gossip_key: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEADwwYLK+fU0M/uLqQpRjHnIAyrt6yPEZSXpUX2jvOGVOA63X8LOYpLVfEGWMmkZ7BHRO0fgr847UUI/xI8otIuiOpgtW2E7QLWs806KUNXz+L8c7kSnQ1XAD5R81/5joDHl4AIxl5fAGryTXH1gfnpTMWh2yjFzU/KYuk2GhrU0M9ewCGJErQG4pT4u3ymGmkLjx6AiZ8r9xb4Eos2bhCCpFWfyb0kKcJqdKU9mzy508byNCfp8lr1DoKxEQrdqSSAQdepn6wCgBZtlAK/k63tOqM9dxyDaCsK8vLG9LlvuEwi3OL2lzTtc1mAcdYxahDo3uBX0/VcCswaXq3nPnu3TBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCUwXPoMh/dylvFwyRzAsnRgDDvh5CHrzJYdUXWGsauYlifOOukYokkwG3yqqtCByveMqVWfWsQukiDTixdqpCgfzw=]
diff --git a/hieradata/country/au/region/syd1/infra/storage/consul.yaml b/hieradata/country/au/region/syd1/infra/storage/consul.yaml
new file mode 100644
index 0000000..52a084f
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/storage/consul.yaml
@@ -0,0 +1,7 @@
+---
+profiles::consul::server::bootstrap_count: 3
+profiles::consul::server::raft_multiplier: 10
+profiles::consul::server::primary_datacenter: 'au-syd1'
+profiles::consul::server::join_remote_regions: true
+profiles::consul::server::remote_regions:
+ - drw1
diff --git a/hieradata/country/au/region/syd1/infra/storage/vault.eyaml b/hieradata/country/au/region/syd1/infra/storage/vault.eyaml
new file mode 100644
index 0000000..74c3111
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/storage/vault.eyaml
@@ -0,0 +1,7 @@
+---
+vault::unseal_keys:
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEABDaLiGSq+xu4DjB/MygqwyVX2cRBlypzRTdijD0Q/Pk/KF4X/6dP1jFVH1hQOI4/oxfsv13PaLFFh/mHgh/WGtwsDKoc20KgUR9N5wvA6p83OLBfuueFFiFM6myh1uzcwgCETGAyGbIy3+Zm2KECfQGJVvcVVEvlCTdqSq8VRMpaxlVrjFA/A/JVI8Gcscuv/44SVAeQi0xsCt0e+HwiaBYq7b+bUjDIR3cHJq1/WZx9mY1rVlOK2385AXhZbN0yi3J+18TYY1ngNq4ag+8T5oFUNfvd66rjFE7sXVKwUCZ64vEVOO08E06rQmv9LHT6DLwPucWIp5AZ8Dc59yWBGzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBmNT7lhDBPD628O6AMkH15gDDuoa6S9NGknF8IOhFVUUSxODg/VCKI43Z9IXBgv3iboD1Q+Dhfje6Vmiyi1sukLRw=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAdpCkAgYhBO6psgTovA9cD0NEu3QxwT14KSzmxr37aHuhSBoh3tIX9asLvR3AduGbDRNI+eTGohSmQRMraTOFWHcTpVv1GShG/KD/wKwW9BGlNze/MwEuoV/OeFcrjfYbsSA338IMgWbG5+MfEduZGxWKIT5F5D14vx6pb9V7bYvbH9jKwSOwWry/RfWkEvMhMZSjFxtRrlMQqj7yqjs9RjauWXctYt4Rx9jK+I+ghWjjV26Q3Pust3OxYCJfCffZ0tpW6YikkGd1Qtq3kuPeh72YU1kYmuQIsDpcgwIuJIMJy2ekteQ/14JtIqN43OvXW5CVrmBemF0AK059LQ96WDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCDOOqa8oCU1St/MStiB/dngDCUp3/Vs0caWnMBi6z0oQ8FhfQR7zPSH8666bXh1U1ETCVL+B1c0NKLiig/3I4ncaQ=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEALAt+ASQS+MoaVoMTBGadYksrKq7REP3OchGXMZL97xdfRVtxaV75/HMES13q4B2dewJzBhpvgTBy9lqPCHXk7PXAkGv0YP2gbj3FXuzlXtZtXD0QHv1SY9assGABCQMdQY+DlZasGIRer/RzOLXpi3zSLlHVFu6dLndKhVs7B6RXgPMnf5Xo0yRijTKHRh8G2oizOxN7X0g5RNZAfAXN+gbDXF/KzpCM8Hox0+6UgJs9ghL7hH8c5Z8odJZcfNuqg87ELSp2XAvpC4jO4KC8VkcT0lIuDgYafyRZcWT4O8Zx6FNvSnDWEdtWHfOUYIg0RTXQ0OR0p28PzS8+0Fhh8TBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCXnDOd5VnrCXt3QIM9BCsIgDD3P5XS+w/EV85vkp9SciOtH95jZ1M0tt7uwA76Bsk69O5qxEbNlv40ZUOC1i02Z4w=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAlBQxsb/TK3gdOmohjoRs5ICN9PjQJvIxW5co7NDsynU6kT6jBinokhbfCRt2RpTUeZqRC2eodMxZSQrkqkMaAbkwSVnMLWzK5444VwT9OrSSwQ0NfT2CuGW9/Vb/XbGy4jwlwGlG23Zf6GptdwxKq1PaJb5FGgUcTXB1XUsDPwLRqpduH4JTdi7BIovOFzsz/hLkaAvrx3BD1ls+21oJpHiGGoomSoTki0tv9Yq2mgB3sn5/P4hIs2vA5gGKTE74nd71hGCg6LBQT9q29cuiM367qebKcSH+nzUlJXYvTxbJiMrs3k5K8IdPd7ocxn1iIuxprSVe6cxEPeoyUIm2dzBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCSHy2XB/CfyCxkgWoLNPWRgDB23dqS9tTUKvXffAAucl5pttdtg5PUknvs7uiOndQDY5J3R0b5hapS186njvlsrW0=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAY3xFtGYy4lQDhHa/t4qri4TJ2/nWAg+EP+tAP4P/9a1er2mR2WkSZD6zBpDMBwN73V0b7XNgAV1W3lPi3XsJlzjhE27a2qBGzoXXekkW5+C65hrVfcPrATos4vpY+ly7ldu6gsZgaE5TlRVt6BE/joi2U5+PfzICOG1Zwpb6/aPdW9UhNPLIRVmAVZBTdnh2qXbYhg/IpUeuX1CSK8F7ptryGXO/aiL4adSYluJkgDtjFplP0yy4IRe7PztnBb2w1XsgIL3SodyhT64OqvoIQd7g6lKwvPmpBJB/VqHwoQDw/GvZg8/BN9514hNpwYsZNIpvtJRE8HX7QJ28mv7TzjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBClVGY4pKZs+wNZ9dIPRSZVgDAW1mDpEnYXfciwNU/aUpZyo2GkTC2DUsNwFtKlgG1aICTfCjLOUhBzcON+Tfhq+7c=]
diff --git a/hieradata/country/au/region/syd1/infra/storage/vault.yaml b/hieradata/country/au/region/syd1/infra/storage/vault.yaml
new file mode 100644
index 0000000..47d6b32
--- /dev/null
+++ b/hieradata/country/au/region/syd1/infra/storage/vault.yaml
@@ -0,0 +1,31 @@
+---
+# additional altnames
+profiles::pki::vault::alt_names:
+ - vault.service.au-syd1.consul
+ - vault.query.consul
+
+profiles::nginx::simpleproxy::nginx_aliases:
+ - vault.service.au-syd1.consul
+ - vault.query.consul
+
+profiles::vault::server::primary_datacenter: 'au-syd1'
+consul::services:
+ vault:
+ service_name: 'vault'
+ tags:
+ - 'https'
+ - 'secure'
+ address: "%{facts.networking.ip}"
+ port: 8200
+ checks:
+ - id: 'vault_https_check'
+ name: 'Vault HTTPS Check'
+ http: "https://%{facts.networking.fqdn}:8200/v1/sys/health"
+ method: 'GET'
+ tls_skip_verify: true
+ interval: '10s'
+ timeout: '1s'
+profiles::consul::client::node_rules:
+ - resource: service
+ segment: vault
+ disposition: write
diff --git a/hieradata/nodes/ausyd1nxvm1017.main.unkin.net.yaml b/hieradata/nodes/ausyd1nxvm1017.main.unkin.net.yaml
new file mode 100644
index 0000000..f7ad64b
--- /dev/null
+++ b/hieradata/nodes/ausyd1nxvm1017.main.unkin.net.yaml
@@ -0,0 +1,2 @@
+---
+profiles::cobbler::params::is_cobbler_master: true
diff --git a/hieradata/nodes/ausyd1nxvm1036.main.unkin.net.yaml b/hieradata/nodes/ausyd1nxvm1036.main.unkin.net.yaml
new file mode 100644
index 0000000..a909eb0
--- /dev/null
+++ b/hieradata/nodes/ausyd1nxvm1036.main.unkin.net.yaml
@@ -0,0 +1,9 @@
+---
+profiles::puppet::server::dns_alt_names:
+ - puppetca.main.unkin.net
+ - puppetca.service.consul
+ - puppetca.query.consul
+ - puppetca
+
+profiles::puppet::puppetca::is_puppetca: true
+profiles::puppet::puppetca::allow_subject_alt_names: true
diff --git a/hieradata/nodes/prodinf01n01.main.unkin.net.yaml b/hieradata/nodes/prodinf01n01.main.unkin.net.yaml
new file mode 100644
index 0000000..e6e8fc8
--- /dev/null
+++ b/hieradata/nodes/prodinf01n01.main.unkin.net.yaml
@@ -0,0 +1,9 @@
+---
+profiles::puppet::server::dns_alt_names:
+ - puppetca.main.unkin.net
+ - puppetca.service.consul
+ - puppetca.query.consul
+ - puppetca
+
+profiles::puppet::puppetca::is_puppetca: false
+profiles::puppet::puppetca::allow_subject_alt_names: true
diff --git a/hieradata/nodes/prodnxsr0001.main.unkin.net.yaml b/hieradata/nodes/prodnxsr0001.main.unkin.net.yaml
new file mode 100644
index 0000000..13bad49
--- /dev/null
+++ b/hieradata/nodes/prodnxsr0001.main.unkin.net.yaml
@@ -0,0 +1,5 @@
+---
+profiles::proxmox::params::pve_clusterinit_master: true
+profiles::proxmox::params::pve_ceph_mon: true
+profiles::proxmox::params::pve_ceph_mgr: true
+profiles::proxmox::params::pve_ceph_osd: true
diff --git a/hieradata/nodes/prodnxsr0002.main.unkin.net.yaml b/hieradata/nodes/prodnxsr0002.main.unkin.net.yaml
new file mode 100644
index 0000000..5fb387e
--- /dev/null
+++ b/hieradata/nodes/prodnxsr0002.main.unkin.net.yaml
@@ -0,0 +1,4 @@
+---
+profiles::proxmox::params::pve_ceph_mon: true
+profiles::proxmox::params::pve_ceph_mgr: true
+profiles::proxmox::params::pve_ceph_osd: true
diff --git a/hieradata/nodes/prodnxsr0003.main.unkin.net.yaml b/hieradata/nodes/prodnxsr0003.main.unkin.net.yaml
new file mode 100644
index 0000000..5fb387e
--- /dev/null
+++ b/hieradata/nodes/prodnxsr0003.main.unkin.net.yaml
@@ -0,0 +1,4 @@
+---
+profiles::proxmox::params::pve_ceph_mon: true
+profiles::proxmox::params::pve_ceph_mgr: true
+profiles::proxmox::params::pve_ceph_osd: true
diff --git a/hieradata/nodes/prodnxsr0004.main.unkin.net.yaml b/hieradata/nodes/prodnxsr0004.main.unkin.net.yaml
new file mode 100644
index 0000000..342f672
--- /dev/null
+++ b/hieradata/nodes/prodnxsr0004.main.unkin.net.yaml
@@ -0,0 +1,2 @@
+---
+profiles::proxmox::params::pve_ceph_osd: true
diff --git a/hieradata/nodes/prodnxsr0005.main.unkin.net.yaml b/hieradata/nodes/prodnxsr0005.main.unkin.net.yaml
new file mode 100644
index 0000000..342f672
--- /dev/null
+++ b/hieradata/nodes/prodnxsr0005.main.unkin.net.yaml
@@ -0,0 +1,2 @@
+---
+profiles::proxmox::params::pve_ceph_osd: true
diff --git a/hieradata/nodes/prodnxsr0006.main.unkin.net.yaml b/hieradata/nodes/prodnxsr0006.main.unkin.net.yaml
new file mode 100644
index 0000000..342f672
--- /dev/null
+++ b/hieradata/nodes/prodnxsr0006.main.unkin.net.yaml
@@ -0,0 +1,2 @@
+---
+profiles::proxmox::params::pve_ceph_osd: true
diff --git a/hieradata/nodes/prodnxsr0007.main.unkin.net.yaml b/hieradata/nodes/prodnxsr0007.main.unkin.net.yaml
new file mode 100644
index 0000000..342f672
--- /dev/null
+++ b/hieradata/nodes/prodnxsr0007.main.unkin.net.yaml
@@ -0,0 +1,2 @@
+---
+profiles::proxmox::params::pve_ceph_osd: true
diff --git a/hieradata/nodes/prodnxsr0008.main.unkin.net.yaml b/hieradata/nodes/prodnxsr0008.main.unkin.net.yaml
new file mode 100644
index 0000000..342f672
--- /dev/null
+++ b/hieradata/nodes/prodnxsr0008.main.unkin.net.yaml
@@ -0,0 +1,2 @@
+---
+profiles::proxmox::params::pve_ceph_osd: true
diff --git a/hieradata/os/AlmaLinux/AlmaLinux8.yaml b/hieradata/os/AlmaLinux/AlmaLinux8.yaml
index ef48076..7861fca 100644
--- a/hieradata/os/AlmaLinux/AlmaLinux8.yaml
+++ b/hieradata/os/AlmaLinux/AlmaLinux8.yaml
@@ -1,10 +1,2 @@
# hieradata/os/AlmaLinux/AlmaLinux8.yaml
---
-profiles::yum::managed_repos:
- - 'base'
- - 'appstream'
- - 'epel'
- - 'powertools'
- - 'highavailability'
- - 'puppet7'
- - 'yum.postgresql.org'
diff --git a/hieradata/os/AlmaLinux/AlmaLinux9.yaml b/hieradata/os/AlmaLinux/AlmaLinux9.yaml
index 40c32c1..03c8c55 100644
--- a/hieradata/os/AlmaLinux/AlmaLinux9.yaml
+++ b/hieradata/os/AlmaLinux/AlmaLinux9.yaml
@@ -1,8 +1,2 @@
# hieradata/os/AlmaLinux/AlmaLinux9.yaml
---
-profiles::yum::managed_repos:
- - 'base'
- - 'appstream'
- - 'epel'
- - 'puppet7'
- - 'yum.postgresql.org'
diff --git a/hieradata/os/AlmaLinux/all_releases.yaml b/hieradata/os/AlmaLinux/all_releases.yaml
index 6592ae6..c383966 100644
--- a/hieradata/os/AlmaLinux/all_releases.yaml
+++ b/hieradata/os/AlmaLinux/all_releases.yaml
@@ -1,9 +1,62 @@
# hieradata/os/almalinux/all_releases.yaml
---
-profiles::yum::base::baseurl: http://repos.main.unkin.net/almalinux
-profiles::yum::epel::baseurl: http://repos.main.unkin.net/epel
profiles::firewall::firewalld::ensure_package: 'absent'
profiles::firewall::firewalld::ensure_service: 'stopped'
profiles::firewall::firewalld::enable_service: false
-
profiles::puppet::agent::puppet_version: '7.26.0'
+
+profiles::packages::install:
+ - lzo
+ - xz
+ - policycoreutils
+
+lm-sensors::package: lm_sensors
+
+profiles::yum::global::repos:
+ baseos:
+ name: baseos
+ descr: baseos repository
+ target: /etc/yum.repos.d/baseos.repo
+ baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/BaseOS/%{facts.os.architecture}/os
+ gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
+ extras:
+ name: extras
+ descr: extras repository
+ target: /etc/yum.repos.d/extras.repo
+ baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/extras/%{facts.os.architecture}/os
+ gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
+ appstream:
+ name: appstream
+ descr: appstream repository
+ target: /etc/yum.repos.d/appstream.repo
+ baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/AppStream/%{facts.os.architecture}/os
+ gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
+ powertools:
+ name: powertools
+ descr: powertools repository
+ target: /etc/yum.repos.d/powertools.repo
+ baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/PowerTools/%{facts.os.architecture}/os
+ gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
+ highavailability:
+ name: highavailability
+ descr: highavailability repository
+ target: /etc/yum.repos.d/highavailability.repo
+ baseurl: https://edgecache.query.consul/almalinux/%{facts.os.release.full}/HighAvailability/%{facts.os.architecture}/os
+ gpgkey: http://edgecache.query.consul/almalinux/RPM-GPG-KEY-AlmaLinux-%{facts.os.release.major}
+ epel:
+ name: epel
+ descr: epel repository
+ target: /etc/yum.repos.d/epel.repo
+ baseurl: https://edgecache.query.consul/epel/%{facts.os.release.major}/Everything/%{facts.os.architecture}
+ gpgkey: http://edgecache.query.consul/epel/RPM-GPG-KEY-EPEL-%{facts.os.release.major}
+ puppet:
+ name: puppet
+ descr: puppet repository
+ target: /etc/yum.repos.d/puppet.repo
+ baseurl: https://yum.puppet.com/puppet7/el/%{facts.os.release.major}/%{facts.os.architecture}
+ gpgkey: https://yum.puppet.com/RPM-GPG-KEY-puppet-20250406
+ unkin:
+ name: unkin
+ descr: unkin repository
+ target: /etc/yum.repos.d/unkin.repo
+ baseurl: https://repos.main.unkin.net/unkin/%{facts.os.release.major}/%{facts.os.architecture}/os
diff --git a/hieradata/os/Debian/all_releases.yaml b/hieradata/os/Debian/all_releases.yaml
index aa8a5bf..221b479 100644
--- a/hieradata/os/Debian/all_releases.yaml
+++ b/hieradata/os/Debian/all_releases.yaml
@@ -1,7 +1,14 @@
# hieradata/os/debian/all_releases.yaml
---
-profiles::apt::base::mirrorurl: http://debian.mirror.digitalpacific.com.au/debian
+profiles::apt::base::mirrorurl: http://repos.main.unkin.net/debian
profiles::apt::base::secureurl: http://security.debian.org/debian-security
profiles::apt::puppet7::mirror: http://apt.puppetlabs.com
profiles::apt::puppet7::repo: puppet7
-profiles::apt::puppet7::dist: bullseye
+profiles::pki::vaultca::ca_cert-path: /usr/local/share/ca-certificates/
+
+profiles::packages::install:
+ - lzop
+ - python3.11-venv
+ - xz-utils
+
+lm-sensors::package: lm-sensors
diff --git a/hieradata/roles/infra.yaml b/hieradata/roles/infra.yaml
index b2164e7..8c2ae06 100644
--- a/hieradata/roles/infra.yaml
+++ b/hieradata/roles/infra.yaml
@@ -1,5 +1,6 @@
---
-profiles::puppet::puppetdb::puppetdb_host: prodinf01n04.main.unkin.net
-profiles::puppet::puppetdb::postgres_host: prodinf01n05.main.unkin.net
+profiles::packages::install:
+ - policycoreutils
+
puppetdb::master::config::create_puppet_service_resource: false
#puppetdb::master::config::puppetdb_host: "%{lookup('profiles::puppet::puppetdb::puppetdb_host')}"
diff --git a/hieradata/roles/infra/cobbler/server.eyaml b/hieradata/roles/infra/cobbler/server.eyaml
new file mode 100644
index 0000000..6ccffe3
--- /dev/null
+++ b/hieradata/roles/infra/cobbler/server.eyaml
@@ -0,0 +1,2 @@
+---
+profiles::cobbler::params::default_password_crypted: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAJidO18dSzKXgDEvFhigrDmiMTW+D7obTCZVAvl0JzQ6nqRdnh6Xa+j+yc7YzYtCg9VH60vfcutHFGhJptlMbTQq3vSUoF9ylgTutaW/to4T8jb8gBqK1n7b+devEQh4soJtOdAPSidCX4aqsP9dK3I8IijNWMABz59usGbY6oWedmC4865PBcxyIu3phWynNULTXPBEAqdXAutkh4N3P1ydFk3eARCVS3uWo7zaXVsu4vIkjYRDCUyFXBWb12L/NmQ2EhGwckPwgX/rcKRL9r49GxQTLBHJ5MoHQanwoiRw+5Tz3qLW69z+hk91VpnpkZgANc081rmhdyp6qmuIAVDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBiDUwXVJ6mmwzt4YAxg3+qgDDWm5mlWEgsZqCHwG0n94v7oqCBqY2WQdTJAM3TtKlX2nOPlLEmfLrwqtsS2r3QzLo=]
diff --git a/hieradata/roles/infra/cobbler/server.yaml b/hieradata/roles/infra/cobbler/server.yaml
new file mode 100644
index 0000000..6709152
--- /dev/null
+++ b/hieradata/roles/infra/cobbler/server.yaml
@@ -0,0 +1,21 @@
+---
+profiles::packages::install:
+ - cobbler
+ - cobbler3.2-web
+ - httpd
+ - syslinux
+ - dnf-plugins-core
+ - debmirror
+ - pykickstart
+ - fence-agents
+ - selinux-policy-devel
+ - ipxe-bootimgs
+
+profiles::pki::vault::alt_names:
+ - cobbler.main.unkin.net
+
+profiles::cobbler::params::service_cname: 'cobbler.main.unkin.net'
+profiles::selinux::setenforce::mode: permissive
+
+hiera_classes:
+ - profiles::selinux::setenforce
diff --git a/hieradata/roles/infra/dhcp/server.yaml b/hieradata/roles/infra/dhcp/server.yaml
new file mode 100644
index 0000000..a186d6c
--- /dev/null
+++ b/hieradata/roles/infra/dhcp/server.yaml
@@ -0,0 +1,77 @@
+---
+profiles::dhcp::server::ntpservers:
+ - ntp01.main.unkin.net
+ - ntp02.main.unkin.net
+profiles::dhcp::server::interfaces:
+ - eth0
+profiles::dhcp::server::default_lease_time: 1200
+profiles::dhcp::server::globaloptions:
+ - 'arch code 93 = unsigned integer 16'
+
+profiles::dhcp::server::pools:
+ syd1-prod:
+ network: 198.18.15.0
+ mask: 255.255.255.0
+ range:
+ - '198.18.15.200 198.18.15.220'
+ gateway: 198.18.15.254
+ nameservers:
+ - 198.18.13.12
+ - 198.18.13.13
+ domain_name: main.unkin.net
+ pxeserver: 198.18.13.27
+ syd1-test:
+ network: 198.18.16.0
+ mask: 255.255.255.0
+ range:
+ - '198.18.16.200 198.18.16.220'
+ gateway: 198.18.16.254
+ nameservers:
+ - 198.18.13.12
+ - 198.18.13.13
+ domain_name: main.unkin.net
+ pxeserver: 198.18.13.27
+ syd1-prod1:
+ network: 198.18.13.0
+ mask: 255.255.255.0
+ range:
+ - '198.18.13.200 198.18.13.220'
+ gateway: 198.18.13.254
+ nameservers:
+ - 198.18.13.12
+ - 198.18.13.13
+ domain_name: main.unkin.net
+ pxeserver: 198.18.13.27
+ syd1-prod2:
+ network: 198.18.14.0
+ mask: 255.255.255.0
+ range:
+ - '198.18.14.200 198.18.14.220'
+ gateway: 198.18.14.254
+ nameservers:
+ - 198.18.13.12
+ - 198.18.13.13
+ domain_name: main.unkin.net
+ pxeserver: 198.18.13.27
+ drw1-prod:
+ network: 198.18.17.0
+ mask: 255.255.255.0
+ range:
+ - '198.18.17.200 198.18.17.220'
+ gateway: 198.18.17.1
+ nameservers:
+ - 198.18.17.7
+ - 198.18.17.8
+ domain_name: main.unkin.net
+ pxeserver: 198.18.13.27
+
+ # UFI 64-bit
+profiles::dhcp::server::classes:
+ UEFI-64:
+ parameters:
+ - 'match if option arch = 00:07 or option arch = 00:09'
+ - 'filename "/ipxe.efi"'
+ Legacy:
+ parameters:
+ - 'match if option arch = 00:00'
+ - 'filename "/undionly.kpxe"'
diff --git a/hieradata/roles/infra/dns/master.yaml b/hieradata/roles/infra/dns/master.yaml
index 4f0dcbc..e9b81b7 100644
--- a/hieradata/roles/infra/dns/master.yaml
+++ b/hieradata/roles/infra/dns/master.yaml
@@ -1,11 +1,13 @@
---
-profiles::dns::master::nameservers:
- - prodinf01n23.main.unkin.net
- - prodinf01n24.main.unkin.net
-
+profiles::dns::master::ns_role: roles::infra::dns::master
+profiles::dns::master::use_ns: region
profiles::dns::master::acls:
acl-main.unkin.net:
addresses:
+ - 198.18.13.0/24
+ - 198.18.14.0/24
+ - 198.18.15.0/24
+ - 198.18.16.0/24
- 198.18.17.0/24
profiles::dns::master::zones:
@@ -15,6 +17,30 @@ profiles::dns::master::zones:
dynamic: false
ns_notify: true
source: '/var/named/sources/main.unkin.net.conf'
+ 13.18.198.in-addr.arpa:
+ domain: '13.18.198.in-addr.arpa'
+ zone_type: 'master'
+ dynamic: false
+ ns_notify: true
+ source: '/var/named/sources/13.18.198.in-addr.arpa.conf'
+ 14.18.198.in-addr.arpa:
+ domain: '14.18.198.in-addr.arpa'
+ zone_type: 'master'
+ dynamic: false
+ ns_notify: true
+ source: '/var/named/sources/14.18.198.in-addr.arpa.conf'
+ 15.18.198.in-addr.arpa:
+ domain: '15.18.198.in-addr.arpa'
+ zone_type: 'master'
+ dynamic: false
+ ns_notify: true
+ source: '/var/named/sources/15.18.198.in-addr.arpa.conf'
+ 16.18.198.in-addr.arpa:
+ domain: '16.18.198.in-addr.arpa'
+ zone_type: 'master'
+ dynamic: false
+ ns_notify: true
+ source: '/var/named/sources/16.18.198.in-addr.arpa.conf'
17.18.198.in-addr.arpa:
domain: '17.18.198.in-addr.arpa'
zone_type: 'master'
@@ -27,6 +53,10 @@ profiles::dns::master::views:
recursion: false
zones:
- main.unkin.net
+ - 13.18.198.in-addr.arpa
+ - 14.18.198.in-addr.arpa
+ - 15.18.198.in-addr.arpa
+ - 16.18.198.in-addr.arpa
- 17.18.198.in-addr.arpa
match_clients:
- acl-main.unkin.net
diff --git a/hieradata/roles/infra/dns/resolver.yaml b/hieradata/roles/infra/dns/resolver.yaml
index 2e80a11..10751b9 100644
--- a/hieradata/roles/infra/dns/resolver.yaml
+++ b/hieradata/roles/infra/dns/resolver.yaml
@@ -2,28 +2,64 @@
profiles::dns::resolver::acls:
acl-main.unkin.net:
addresses:
+ - 10.10.8.1/32
+ - 198.18.21.160/27
+ - 198.18.21.192/27
+ - 198.18.13.0/24
+ - 198.18.14.0/24
+ - 198.18.15.0/24
+ - 198.18.16.0/24
- 198.18.17.0/24
profiles::dns::resolver::zones:
- main.unkin.net-forward:
- domain: 'main.unkin.net'
+ 8.10.10.in-addr.arpa-forward:
+ domain: '8.10.10.in-addr.arpa'
zone_type: 'forward'
forwarders:
- - 198.18.17.23
- - 198.18.17.24
+ - 10.10.16.32
+ - 10.10.16.33
+ forward: 'only'
+ 16.10.10.in-addr.arpa-forward:
+ domain: '16.10.10.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 10.10.16.32
+ - 10.10.16.33
+ forward: 'only'
+ 20.10.10.in-addr.arpa-forward:
+ domain: '20.10.10.in-addr.arpa'
+ zone_type: 'forward'
+ forwarders:
+ - 10.10.16.32
+ - 10.10.16.33
+ forward: 'only'
+ unkin.net-forward:
+ domain: 'unkin.net'
+ zone_type: 'forward'
+ forwarders:
+ - 10.10.16.32
+ - 10.10.16.33
+ forward: 'only'
+ dmz.unkin.net-forward:
+ domain: 'dmz.unkin.net'
+ zone_type: 'forward'
+ forwarders:
+ - 10.10.16.32
+ - 10.10.16.33
+ forward: 'only'
+ network.unkin.net-forward:
+ domain: 'network.unkin.net'
+ zone_type: 'forward'
+ forwarders:
+ - 10.10.16.32
+ - 10.10.16.33
forward: 'only'
prod.unkin.net-forward:
domain: 'prod.unkin.net'
zone_type: 'forward'
forwarders:
- - 10.10.8.1
- forward: 'only'
- 17.18.198.in-addr.arpa-forward:
- domain: '17.18.198.in-addr.arpa'
- zone_type: 'forward'
- forwarders:
- - 198.18.17.23
- - 198.18.17.24
+ - 10.10.16.32
+ - 10.10.16.33
forward: 'only'
profiles::dns::resolver::views:
@@ -31,7 +67,18 @@ profiles::dns::resolver::views:
recursion: true
zones:
- main.unkin.net-forward
+ - unkin.net-forward
+ - dmz.unkin.net-forward
+ - network.unkin.net-forward
- prod.unkin.net-forward
+ - consul-forward
+ - 13.18.198.in-addr.arpa-forward
+ - 14.18.198.in-addr.arpa-forward
+ - 15.18.198.in-addr.arpa-forward
+ - 16.18.198.in-addr.arpa-forward
- 17.18.198.in-addr.arpa-forward
+ - 8.10.10.in-addr.arpa-forward
+ - 16.10.10.in-addr.arpa-forward
+ - 20.10.10.in-addr.arpa-forward
match_clients:
- acl-main.unkin.net
diff --git a/hieradata/roles/infra/git/gitea.eyaml b/hieradata/roles/infra/git/gitea.eyaml
new file mode 100644
index 0000000..fa29e19
--- /dev/null
+++ b/hieradata/roles/infra/git/gitea.eyaml
@@ -0,0 +1,3 @@
+---
+profiles::gitea::init::mysql_pass: ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAjmMVHQcvy0PLruFWI6UmYqM2uEqXntV8HdA54RCTm7GaneXsW+rom+ibFVd0i9L+spQPQzcidh7FlzBRYgny8yH8TqZlh7XMraXSYG2EvrjwzNvgnwhY5mGEQNQcQkqN9Orfsf6HjXmXg2CxajYibKu0/belJZFffzPzzrn15wy3Cj5lDjAziqYoD+8Ko1zkF9lWz4ewVjll82yo8iSpidN+PyvoeWsi/eJ9cW72TgFLt/rvGquLq3MuW54J716hrR1Z37Uf0OO18AiKCVjoCi5Cf/k0VKRsXM8Myu2KInqrGcUHAO+fsOXBXnmU0MOxW0OIOmwxfwY6LJfN23arlDBMBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBB6GktEMe8gSTijJ/dIHC5/gCCblMojNKO1ig9fNsuT9I2u5Bt4iJrSMN+GBGnCzO1Bvw==]
+profiles::gitea::init::lfs_jwt_secret: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEACd6q4E/4l1EYD3SFjc1okibyJ13kcGGWU+ShbCgwLgkW7INkyCxhbNm69yPA7WcyuRhH/Lfz/XjJKd3BSCyRQPr5IUOIRINspx82tLBcaMzY/99GFrfyDnf3+SV/AxrPJ/zD5TGkKQP7uX6WjC9DXpHE+pFJa9wBAipmV439y0JDVt2gXFmhqBWThSjBDBfJ5X4zO5wY8CfBX4APOcD5hIQP/T4n04dQLNpigEKKy6B+GFuooTbdmMmFj3ZpT+cUS8Aw9mFkBwyyN1o+50XU3vW4eieUz8cYkzDPu574XfTunqD2jcvPiFjCla8G1SpKfHkruKnZWwgO0Ntw9td5QDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAIRVL5j4dzbYg6f2XjvkQ6gDAd2qUNzPn2flZgKwsjIZcYdmFMTn48hGPUFfVaMDeyzPoJi84CyRJl8cQvcAe52sw=]
diff --git a/hieradata/roles/infra/git/gitea.yaml b/hieradata/roles/infra/git/gitea.yaml
new file mode 100644
index 0000000..3199ed6
--- /dev/null
+++ b/hieradata/roles/infra/git/gitea.yaml
@@ -0,0 +1,39 @@
+---
+# additional altnames
+profiles::pki::vault::alt_names:
+ - git.main.unkin.net
+ - git.service.consul
+ - git.query.consul
+ - "git.service.%{facts.country}-%{facts.region}.consul"
+
+consul::services:
+ git:
+ service_name: 'git'
+ tags:
+ - 'git'
+ - 'gitea'
+ address: "%{facts.networking.ip}"
+ port: 443
+ checks:
+ - id: 'gitea_https_check'
+ name: 'Gitea HTTPS Check'
+ http: "https://%{facts.networking.fqdn}:443"
+ method: 'GET'
+ tls_skip_verify: true
+ interval: '10s'
+ timeout: '1s'
+profiles::consul::client::node_rules:
+ - resource: service
+ segment: git
+ disposition: write
+
+# manage a simple nginx reverse proxy
+profiles::nginx::simpleproxy::nginx_vhost: 'git.query.consul'
+profiles::nginx::simpleproxy::nginx_aliases:
+ - git.main.unkin.net
+ - git.service.consul
+ - git.query.consul
+ - "git.service.%{facts.country}-%{facts.region}.consul"
+profiles::nginx::simpleproxy::proxy_port: 3000
+profiles::nginx::simpleproxy::proxy_path: '/'
+nginx::client_max_body_size: 250M
diff --git a/hieradata/roles/infra/halb/haproxy.yaml b/hieradata/roles/infra/halb/haproxy.yaml
new file mode 100644
index 0000000..cd212ad
--- /dev/null
+++ b/hieradata/roles/infra/halb/haproxy.yaml
@@ -0,0 +1,91 @@
+---
+profiles::haproxy::ls_stats::port: 9090
+profiles::haproxy::ls_stats::user: 'admin'
+profiles::selinux::setenforce::mode: permissive
+
+profiles::haproxy::selinux::ports:
+ - 9090
+profiles::haproxy::selinux::sebooleans:
+ - haproxy_connect_any
+
+profiles::haproxy::server::globals:
+ log:
+ - /dev/log local0
+ - /dev/log local1 notice
+ stats:
+ - timeout 30s
+ - socket /var/lib/haproxy/stats
+ ca-base: /etc/ssl/certs
+ crt-base: /etc/ssl/private
+ ssl-default-bind-ciphers: EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
+ ssl-default-bind-options: 'ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.3'
+ ssl-default-server-ciphers: kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL
+ ssl-default-server-options: no-sslv3
+ tune.ssl.default-dh-param: 2048
+
+profiles::haproxy::server::defaults:
+ mode: http
+ option:
+ - httplog
+ - dontlognull
+ - http-server-close
+ - forwardfor except 127.0.0.0/8
+ - redispatch
+ timeout:
+ - http-request 10s
+ - queue 1m
+ - connect 10s
+ - client 5m
+ - server 5m
+ - http-keep-alive 10s
+ - check 10s
+ retries: 3
+ maxconn: 5000
+
+profiles::haproxy::frontends:
+ fe_http:
+ description: 'Global HTTP Frontend'
+ bind:
+ 0.0.0.0:80:
+ - transparent
+ mode: 'http'
+ options:
+ acl:
+ - 'acl-letsencrypt path_beg /.well-known/acme-challenge/'
+ http-request:
+ - 'set-header X-Forwarded-Proto https'
+ - 'set-header X-Real-IP %[src]'
+ fe_https:
+ description: 'Global HTTPS Frontend'
+ bind:
+ 0.0.0.0:443:
+ - ssl
+ - crt-list /etc/haproxy/certificate.list
+ - ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
+ - force-tlsv12
+ mode: 'http'
+ options:
+ acl:
+ - 'acl-letsencrypt path_beg /.well-known/acme-challenge/'
+ http-request:
+ - 'set-header X-Forwarded-Proto https'
+ - 'set-header X-Real-IP %[src]'
+
+profiles::haproxy::backends:
+ be_letsencrypt:
+ description: Backend for LetsEncrypt Verifications
+ collect_exported: true
+ options:
+ balance: roundrobin
+ be_default:
+ description: Backend for unmatched HTTP traffic
+ collect_exported: true
+ options:
+ balance: roundrobin
+ option:
+ - httpchk GET /
+ - forwardfor
+ cookie: SRVNAME insert
+ http-request:
+ - set-header X-Forwarded-Port %[dst_port]
+ - add-header X-Forwarded-Proto https if { dst_port 443 }
diff --git a/hieradata/roles/infra/ntp/server.yaml b/hieradata/roles/infra/ntp/server.yaml
index e618573..839e32d 100644
--- a/hieradata/roles/infra/ntp/server.yaml
+++ b/hieradata/roles/infra/ntp/server.yaml
@@ -1,6 +1,10 @@
---
profiles::ntp::client::client_only: false
profiles::ntp::server::allowquery:
+ - '198.18.13.0/24'
+ - '198.18.14.0/24'
+ - '198.18.15.0/24'
+ - '198.18.16.0/24'
- '198.18.17.0/24'
profiles::ntp::server::peers:
diff --git a/hieradata/roles/infra/ovirt/engine.yaml b/hieradata/roles/infra/ovirt/engine.yaml
new file mode 100644
index 0000000..b2a934d
--- /dev/null
+++ b/hieradata/roles/infra/ovirt/engine.yaml
@@ -0,0 +1,50 @@
+---
+profiles::yum::global::repos:
+ centos_8_advanced_virtualization:
+ name: 'virt-advanced-virtualization'
+ descr: 'CentOS Advanced Virtualization'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/virt/x86_64/advancedvirt-common
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
+ centos_8_ceph_pacific:
+ name: 'storage-ceph-pacific'
+ descr: 'CentOS Ceph Pacific'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/storage/x86_64/ceph-pacific
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
+ centos_8_rabbitmq_38:
+ name: 'messaging-rabbitmq-38'
+ descr: 'CentOS RabbitMQ 38'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/messaging/x86_64/rabbitmq-38
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Messaging'
+ centos_8_nfv_openvswitch:
+ name: 'nfv-openvswitch-2'
+ descr: 'CentOS NFV OpenvSwitch'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/nfv/x86_64/openvswitch-2
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-NFV'
+ centos_8_openstack_xena:
+ name: 'cloud-openstack-xena'
+ descr: 'CentOS OpenStack Xena'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/cloud/x86_64/openstack-xena
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Cloud'
+ centos_8_opstools:
+ name: 'opstools-collectd-5'
+ descr: 'CentOS OpsTools - collectd'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/opstools/x86_64/collectd-5
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-OpsTools'
+ centos_8_ovirt45:
+ name: 'virt-ovirt-45'
+ descr: 'CentOS oVirt 4.5'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/virt/x86_64/ovirt-45
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
+ centos_8_stream_gluster10:
+ name: 'storage-gluster-10'
+ descr: 'CentOS oVirt 4.5 - Glusterfs 10'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/storage/x86_64/gluster-10
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
diff --git a/hieradata/roles/infra/ovirt/node.yaml b/hieradata/roles/infra/ovirt/node.yaml
new file mode 100644
index 0000000..762c1aa
--- /dev/null
+++ b/hieradata/roles/infra/ovirt/node.yaml
@@ -0,0 +1,58 @@
+---
+profiles::firewall::firewalld::ensure_package: 'installed'
+profiles::firewall::firewalld::ensure_service: 'running'
+
+sudo::purge_ignore:
+ - '50_vdsm'
+ - '50_vdsm_hook_ovirt_provider_ovn_hook'
+ - '60_ovirt-ha'
+
+profiles::yum::global::repos:
+ centos_8_advanced_virtualization:
+ name: 'virt-advanced-virtualization'
+ descr: 'CentOS Advanced Virtualization'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/virt/x86_64/advancedvirt-common
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
+ centos_8_ceph_pacific:
+ name: 'storage-ceph-pacific'
+ descr: 'CentOS Ceph Pacific'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/storage/x86_64/ceph-pacific
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
+ centos_8_rabbitmq_38:
+ name: 'messaging-rabbitmq-38'
+ descr: 'CentOS RabbitMQ 38'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/messaging/x86_64/rabbitmq-38
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Messaging'
+ centos_8_nfv_openvswitch:
+ name: 'nfv-openvswitch-2'
+ descr: 'CentOS NFV OpenvSwitch'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/nfv/x86_64/openvswitch-2
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-NFV'
+ centos_8_openstack_xena:
+ name: 'cloud-openstack-xena'
+ descr: 'CentOS OpenStack Xena'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/cloud/x86_64/openstack-xena
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Cloud'
+ centos_8_opstools:
+ name: 'opstools-collectd-5'
+ descr: 'CentOS OpsTools - collectd'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/opstools/x86_64/collectd-5
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-OpsTools'
+ centos_8_ovirt45:
+ name: 'virt-ovirt-45'
+ descr: 'CentOS oVirt 4.5'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/virt/x86_64/ovirt-45
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
+ centos_8_stream_gluster10:
+ name: 'storage-gluster-10'
+ descr: 'CentOS oVirt 4.5 - Glusterfs 10'
+ target: /etc/yum.repos.d/ovirt.repo
+ baseurl: https://edgecache.query.consul/centos/8-stream/storage/x86_64/gluster-10
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
diff --git a/hieradata/roles/infra/proxmox.yaml b/hieradata/roles/infra/proxmox.yaml
new file mode 100644
index 0000000..7a1b911
--- /dev/null
+++ b/hieradata/roles/infra/proxmox.yaml
@@ -0,0 +1,7 @@
+---
+sudo::configs:
+ ceph-smartctl:
+ priority: 20
+ content: |
+ ceph ALL=NOPASSWD: /usr/sbin/smartctl -x --json=o /dev/*
+ ceph ALL=NOPASSWD: /usr/sbin/nvme * smart-log-add --json /dev/*
diff --git a/hieradata/roles/infra/puppet.yaml b/hieradata/roles/infra/puppet.yaml
new file mode 100644
index 0000000..6ae5977
--- /dev/null
+++ b/hieradata/roles/infra/puppet.yaml
@@ -0,0 +1,3 @@
+---
+profiles::packages::install:
+ - puppetserver
diff --git a/hieradata/roles/infra/puppet/master.eyaml b/hieradata/roles/infra/puppet/master.eyaml
new file mode 100644
index 0000000..07427fe
--- /dev/null
+++ b/hieradata/roles/infra/puppet/master.eyaml
@@ -0,0 +1,3 @@
+---
+profiles::puppet::eyaml::publickey: ENC[PKCS7,MIIFjQYJKoZIhvcNAQcDoIIFfjCCBXoCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAizhVN1svMJqLlkDWcm/qhMNajKL9G7GvBxG04dOdYLUu99wgmIlD1vetNIoJrQ6defmVuMMzT3IxzIDrRf8QEVL7hstIFoGlhv0ObBewjLJY34v3B7Sxj0nv8XPTLd8Q6LZQb+KSo0SLQxbjEw60qAl5DbDqXUNOx2OIV3yP1IaCzzi6llb1ZOWPcBESt6HEnLzqkwzEK+2/QGBOMqChP1EP7JHFrWQw5YYCLUcYCLVts1K57Q7ThFwckUA0v8Vh9HdlZqA0XPxKyVK7nfw/Y1CpwRTwZ8GYnry1/iLNYjFGkDU0V5pf+ZhlZfIChVccma9NCSlQtA+7DikNcpLTfTCCBE4GCSqGSIb3DQEHATAdBglghkgBZQMEASoEEJQ4jJz/oSqW79tDOSv2pWCAggQgvi+p2P7tkIY4c0yNEIFjnXa3Imopg4bZ29TQJnPLAqVM7Bexh0XhxAjWk8YFvxQ0Yio+3JKlvqlsFVpecumV6NHwVPe521Hl7l88eRvgCHBC3tVm98+N2A0GdGbT+begqsj0nPTDScixJE79dGZK6/qgf3NuYPCj+drFwWrDuZXpIYMHJcOrVhqlg4RFW4ZYUxbsAC2eNFXUF0bYpKej3voCnlj/o6RxLEC/Gv2T66e9sFjeANo9W84uAfZ1t4cweVzYh1h6Yiw+0ewWA6ndg8thgr2Uk9JdpjXzS0QTtElGmNv+tZmCH45o0HUunPZs0gkn5unT0pzZosqgSeu0HdHcsImJpuJVRIVjAXypku7LtBKnP3VA5iXi2lld/suEOeeU18Aw3pxFQrKV3cexiWLa4mpKn8JR1HBxw4NcLj3/fes41fxW0zLyY8m4MksaIpc4BXz33uup5rHdVblbD1raZJPAg7k8KufStsRBmeokdysF+PJebrCfTH8goR3BWGfCVWQEoDjB2wAhVTQKuzAh3d51k+s4uvJchNBDgfGt/s9hdBFU/VQTZUyOoSEOwxB1857sOF3iPLM1233XEhZd2AOl4h5xy1z3+aSOG0jiihWt6QdosUig/IHxyO4gWaEO37iaLlF0ZVSJKjOV/IBCHJAaAG476uSNv+kTKgvu0PQtIfcKHpa1ppHi96fO8FKX76l26VoGKf/kMi6bWdTObYZnyiN7fz342ewMpwu70wQQWo33riK0hhF6bRu40J/KmgoUaUz3jSnErv+EeeREYww5SSNlMhpQNBNj+WfEDRC4Zx9VsF1cjtTY1um0kYdoyTHBLH6V1oAEiFIScHqkW1zKVAEiBh2v6C1U3fwAzOyAbnDlBrsuhnVxbJa8O1d5yw+U2py6xdC3Wq6FsAP9kdfDu+mjNDOwwJWZa8iTj3NHum1G6xklF2JHtmp2p1gY0e/JCETIk5Xh1okf404F9Xi+CWvlmlPXie9SdwgyJWpXOM60pJN2iMOFKPGn4chppMka38HakDKbdNNTELxNE+/yVECT0uQ8iBvETX1FU+y4LpGFghmwAIiKB1HZXx/0Gof0+txj/p9AgnpeVvDbq4iiZOulcu2BepsrFDg2zNLollfhAo+6QvElpk2MI1yHrg3OaTt7U8JV1dxHyIWjbtRvbiiS1E6mKGiOpkIQd/IHBjkujvEd7LVeE721HrLdGRaTR9QJfTR8jPZGHMlZa14a2pcxliyYd9RFSVOkVZH2LetuSWStQ1gPdBEeKDSWyFBA0Rxzlw2Sl25MJ4PAIpimyUYrnxTa2XgHyavMa0kjVAhX15+ywze2ypOVnB9/q3L3M5JCq+eaOBicJQiERX4h7Yj499S9Y/2nxk2DOUxi965BDIZGSG3/qOtl]
+profiles::puppet::eyaml::privatekey: ENC[PKCS7,MIIH/QYJKoZIhvcNAQcDoIIH7jCCB+oCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAkH2q64bYf5Es/YNK6c6d5t9PYcbc9NGzC6F2AzjWeLV9rdT+DBNmhPeyHN4jR6edzLRaNL+u3cuur3mTxwSJcEXdyHQSbXJLlGpd9CPEjuerqdsXkFvamP//nHjwvSosBUo4PKtllphX0XHP6JS0Mm+nukv0YyDk+63+cETuyP5M1FVsLSK8ZWblOn1uBgNhhjGZF5nNeayjJKloWdVY8+pS8L6/y0QprF05oLDvI0JgK9wud8NID+LCNtb2Z5/mq2ScpMB/r/ji/oPHs40zhANqOiAuy/sUWwIivdB2iKKvcLfJ8tbtCanXuQxboqnulL1+C87Y4m1rmk4cNtKU3DCCBr4GCSqGSIb3DQEHATAdBglghkgBZQMEASoEELXUERpdYNf8m2IXbCw/MxiAggaQ187hqDCftN9RvnFRHnlHyPZijykRgs558tdh0yA8GscJ9vim8kxQXrxM6gqAGgmV7xYnpyK0pvEn0/6cEFkcBkpkQOtlyil+4WB9bcLJIF4LzPut0pz4Eq/6zMSM9PGWCRFe3ufkdoDq5M1SlHa/Aoi/LwNu5EFFlFZeeDiZyUMupLJUHbTQ+wt2JgQLfpBzeCGb5BRLvSPH0+Y7ShwHgp2ZCtxc/tT5cdQq5a3+tt9ZYSy5Hj+c8I2WBPm3wghA7QULCB1+42K4A8BJ7HQucaT1mRMc0QnCt68xQkhBulxGnADPaRAWICmuAF2KBv/eS74TdYj3z0OCSZW5k1wDBz8FCSIodn2a1LgBMrFRCAS2fwRn7Hc0yguCRl9ppERW+8K3pg7aAiBqJbeTwQN/VICNan92y+cbUndO9a/U16zKD4SxfW8PMwSu/qz6i45gUjQ83THjwNAE6el0lYFYivBsEEg66Sqo2cXtPQlAdB8lOsS34TQq21zipikgAAii0mGoH738t2CYL6tMUGthpcfXLioU0AhXjLVED1PIpmWxieFENWO8SUx3NjXyoefBVQrzc1PPAgeVGSaOBoJSN7xNx3/RQhWck0240DZmi+41z5CF1z91eZY+ZJYa/SaHVWWZ7GgQDEXGnWKQkMZce6RK0qw0/8B0x5O6aIlBrB7aSVQIkDLSUw8bq7N5dAeKXLu+2QHhG1yl+Bmn1xDMILFphJNT2ZNXkoSd0r1WUePWBEFCOBPsu3cHaK9DZiXSdfJ3dY+1NYuVZDQshQ1Fe4IKpHm/0mtz60DjrTTaJ3kAsPLCpeFGJ+1U/TdO+IgPAsiHUIaDRtv19ZeH7/Pa/kAceIe16F8CRNkzJ62D8CH4RYEXxTJ7oogYbhsw+5WQ3ZGzJHNvxcX4EVofjIsr2uIQEAVTu9VSDY2LyihJBEs0EBw25dai52u2g1Jjtteod9p6B+rwrcVGKAzdEo7nF9qK6+dS8VlfFbmbU1/ulIpM0hUr3ZFsUSv1qUGqUmYdgndvE0+gHop71fsnQRmT9wTdQlUs7RC0+BPWvf7eGljJT+omDwv+wSShikWku9ZSk58HqZ74f2RizxL7Ny8SWCkOf1u+Gi8kalMhr+1p8e39S6WTws8rJHxIQrzfY7aqZwYIZzLl4JMnqBvbkUlCEKNHmVAVt6AgPGfTmoEzSgulHEMCETuBQl4dS8mtFvWRKCy0jC2fAUfIAoihoh/2g3MTbKQCM3aSHrqyPTAduN2VkQwTM4JmgU6YYWy4kXjPWsgEm+FjqOKQqd5Q5bwIOoFLSVQgrTtoKVUXzK8VbTDNDhLj+LggB9MMncr5X44LkdtrktYWeQ1CbBGYUTNHyXxT2nbJm7DJos4zjSIqnkSiR2VyRAkxF9TSXjnZwtsziXC4gdonjA+ImV5aUvL5aTO2zbTYQOqgrauS/SWS4tXbZ4Thw86d2zbO32Kvuu4bfHVTN087eiRuiFmjtz43PwBRMxjABLDe/ZRUHLDomAVydTS98aIswUb33jHoPtEkz4bWEtZlhwrqguvPzLSJT1SNZnDhNsdzO96GDB2vtvXmIiQq+/8jh0LKIoOCFWKsFfB0GrkZZvLnF6oQQ/MiYNNY1TLnHMAg2uSF+ap/g8QRvfE5FX2UquYE1ATeD+8iRw0g2crNXGVRynBo6ESd5O+zwcMitO/Re9tQM4rfNj83VgWeSUNLxhOZmbYs0hDEbS0lXIWa1NbASuXWk/FBXzr8X/ZdlZPWAMWe3J9Bqh6e1FhgGD6ZZmSTYxHzlz5TNCf+aMqnJRb5eyN+UM5iWgW/VpAlKWMl98c1lsKwccAS/SH2zugKwBT8Bf/4wnbpHrZe817vVF7raVcaYvNnYTzdSQCcnvRK/D40sqleOhtfX/vdjOFWfoukbEJnXNytkTZeKrBm83z6tmYe4siQdfn4X9/lGNWEDyjYiJX8czH6yMlRW+FposOpE4Y9Dgs694iPHmYt1/1VbuW240uG6VT/d+OjSD5L6JfTT47pghoWTl0dQGbKd3kmoku7C7ll5etCdz5UIY2JOmS1gx6NgvsElJyflgQHgXLiSKpB0iSZ7zTRKlBmRG7uiU582nkbXHQ7BwZkP3nq95bgtCmk+0pvioYYg/jK8hvuiv+b8Ez2pHaTLabn/jYww8ewIZz0W5mWgcCDwdebtP2CCSnB2IPjyzAh2TW8JTljeoJAe9ai+iqiX4400R2hXZl6KMpC]
diff --git a/hieradata/roles/infra/puppet/master.yaml b/hieradata/roles/infra/puppet/master.yaml
index 5a5f87c..4af2c1c 100644
--- a/hieradata/roles/infra/puppet/master.yaml
+++ b/hieradata/roles/infra/puppet/master.yaml
@@ -1,5 +1,9 @@
---
profiles::puppet::autosign::subnet_ranges:
+ - '198.18.13.0/24'
+ - '198.18.14.0/24'
+ - '198.18.15.0/24'
+ - '198.18.16.0/24'
- '198.18.17.0/24'
profiles::puppet::autosign::domains:
@@ -8,9 +12,64 @@ profiles::puppet::autosign::domains:
# profiles::puppet::autosign::nodes:
# - 'somenode.main.unkin.net'
-profiles::puppet::enc::repo: https://git.unkin.net/unkinben/puppet-enc.git
-profiles::puppet::r10k::r10k_repo: https://git.unkin.net/unkinben/puppet-r10k.git
+profiles::puppet::cobbler_enc::cobbler_scheme: https
+profiles::puppet::cobbler_enc::cobbler_hostname: cobbler.main.unkin.net
+profiles::puppet::cobbler_enc::version: 'system'
+profiles::puppet::cobbler_enc::packages:
+ - 'requests'
+ - 'PyYAML'
+profiles::puppet::enc::repo: https://git.service.au-syd1.consul/unkinben/puppet-enc.git
+profiles::puppet::r10k::r10k_repo: https://git.service.au-syd1.consul/unkinben/puppet-r10k.git
profiles::puppet::g10k::bin_path: '/opt/puppetlabs/bin/g10k'
profiles::puppet::g10k::cfg_path: '/etc/puppetlabs/r10k/r10k.yaml'
profiles::puppet::g10k::environments_path: '/etc/puppetlabs/code/environments'
profiles::puppet::g10k::default_environment: 'develop'
+profiles::puppet::gems::puppet:
+ - 'deep_merge'
+ - 'ipaddr'
+ - 'hiera-eyaml'
+
+profiles::helpers::certmanager::vault_config:
+ addr: 'https://vault.query.consul:8200'
+ mount_point: 'pki_int'
+ approle_path: 'approle'
+ role_name: 'servers_default'
+ output_path: '/tmp/certmanager'
+ role_id: "%{lookup('certmanager::role_id')}"
+
+profiles::puppet::server::agent_server: 'puppet.query.consul'
+profiles::puppet::server::report_server: 'puppet.query.consul'
+profiles::puppet::server::ca_server: 'puppetca.query.consul'
+profiles::puppet::server::dns_alt_names:
+ - "%{facts.networking.fqdn}"
+ - "%{facts.networking.hostname}"
+ - puppetmaster.main.unkin.net
+ - puppet.main.unkin.net
+ - puppet.service.consul
+ - puppet.query.consul
+ - puppetmaster
+ - puppet
+
+consul::services:
+ puppet:
+ service_name: 'puppet'
+ tags:
+ - 'puppet'
+ - 'master'
+ address: "%{facts.networking.ip}"
+ port: 8140
+ checks:
+ - id: 'puppet_https_check'
+ name: 'Puppet HTTPS Check'
+ http: "https://%{facts.networking.fqdn}:8140/status/v1/simple"
+ method: 'GET'
+ tls_skip_verify: true
+ interval: '10s'
+ timeout: '1s'
+profiles::consul::client::node_rules:
+ - resource: service
+ segment: puppet
+ disposition: write
+ - resource: service
+ segment: puppetca
+ disposition: write
diff --git a/hieradata/roles/infra/puppetboard/server.yaml b/hieradata/roles/infra/puppetboard/server.yaml
new file mode 100644
index 0000000..d835603
--- /dev/null
+++ b/hieradata/roles/infra/puppetboard/server.yaml
@@ -0,0 +1,35 @@
+---
+# additional servername aliases
+profiles::puppet::puppetboard::nginx_aliases:
+ - puppetboard.service.consul
+ - puppetboard.query.consul
+ - "puppetboard.service.%{facts.country}-%{facts.region}.consul"
+ - "%{facts.networking.fqdn}"
+
+# additional altnames
+profiles::pki::vault::alt_names:
+ - puppetboard.main.unkin.net
+ - puppetboard.service.consul
+ - puppetboard.query.consul
+ - "puppetboard.service.%{facts.country}-%{facts.region}.consul"
+
+consul::services:
+ puppetboard:
+ service_name: 'puppetboard'
+ tags:
+ - 'puppet'
+ - 'puppetboard'
+ address: "%{facts.networking.ip}"
+ port: 80
+ checks:
+ - id: 'puppetboard_http_check'
+ name: 'Puppetboard HTTP Check'
+ http: "http://%{facts.networking.fqdn}:80"
+ method: 'GET'
+ tls_skip_verify: true
+ interval: '10s'
+ timeout: '1s'
+profiles::consul::client::node_rules:
+ - resource: service
+ segment: puppetboard
+ disposition: write
diff --git a/hieradata/roles/infra/puppetdb/api.yaml b/hieradata/roles/infra/puppetdb/api.yaml
new file mode 100644
index 0000000..784200a
--- /dev/null
+++ b/hieradata/roles/infra/puppetdb/api.yaml
@@ -0,0 +1,39 @@
+---
+profiles::puppet::puppetdb_api::java_bin: /usr/lib/jvm/jre-11/bin/java
+profiles::puppet::puppetdb_api::java_args:
+ '-Xmx': '2048m'
+ '-Xms': '256m'
+
+profiles::puppet::client::dns_alt_names:
+ - puppetdbapi.main.unkin.net
+ - puppetdbapi.service.consul
+ - puppetdbapi.query.consul
+
+# additional altnames
+profiles::pki::vault::alt_names:
+ - puppetdbapi.main.unkin.net
+ - puppetdbapi.service.consul
+ - puppetdbapi.query.consul
+ - puppetdbapi
+
+consul::services:
+ puppetdbapi:
+ service_name: 'puppetdbapi'
+ tags:
+ - 'puppet'
+ - 'puppetdb'
+ - 'puppetdbapi'
+ address: "%{facts.networking.ip}"
+ port: 8080
+ checks:
+ - id: 'puppetdbapi_http_check'
+ name: 'PuppetDB API HTTP Check'
+ http: "http://%{facts.networking.fqdn}:8080"
+ method: 'GET'
+ tls_skip_verify: true
+ interval: '10s'
+ timeout: '1s'
+profiles::consul::client::node_rules:
+ - resource: service
+ segment: puppetdbapi
+ disposition: write
diff --git a/hieradata/roles/infra/puppetdb/sql.yaml b/hieradata/roles/infra/puppetdb/sql.yaml
new file mode 100644
index 0000000..0d6409a
--- /dev/null
+++ b/hieradata/roles/infra/puppetdb/sql.yaml
@@ -0,0 +1,4 @@
+---
+postgresql_config_entries:
+ max_connections: 300
+ shared_buffers: '256MB'
diff --git a/hieradata/roles/infra/reposync/syncer.yaml b/hieradata/roles/infra/reposync/syncer.yaml
index e6a341e..f893a5b 100644
--- a/hieradata/roles/infra/reposync/syncer.yaml
+++ b/hieradata/roles/infra/reposync/syncer.yaml
@@ -1,40 +1,13 @@
---
+profiles::packages::install:
+ - createrepo
+
+profiles::pki::vault::alt_names:
+ - repos.main.unkin.net
+
+profiles::reposync::webserver::nginx_listen_mode: both
+profiles::reposync::webserver::nginx_cert_type: vault
profiles::reposync::repos_list:
- almalinux_8_8_baseos:
- repository: 'BaseOS'
- description: 'AlmaLinux 8.8 - BaseOS'
- osname: 'almalinux'
- release: '8.8'
- mirrorlist: https://mirrors.almalinux.org/mirrorlist/8.8/baseos
- gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux'
- almalinux_8_8_appstream:
- repository: 'AppStream'
- description: 'AlmaLinux 8.8 - AppStream'
- osname: 'almalinux'
- release: '8.8'
- mirrorlist: https://mirrors.almalinux.org/mirrorlist/8.8/appstream
- gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux'
- almalinux_8_8_highavailability:
- repository: 'HighAvailability'
- description: 'AlmaLinux 8.8 - HighAvailability'
- osname: 'almalinux'
- release: '8.8'
- mirrorlist: https://mirrors.almalinux.org/mirrorlist/8.8/ha
- gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux'
- almalinux_8_8_powertools:
- repository: 'PowerTools'
- description: 'AlmaLinux 8.8 - PowerTools'
- osname: 'almalinux'
- release: '8.8'
- mirrorlist: https://mirrors.almalinux.org/mirrorlist/8.8/powertools
- gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux'
- almalinux_8_8_extras:
- repository: 'extras'
- description: 'AlmaLinux 8.8 - extras'
- osname: 'almalinux'
- release: '8.8'
- mirrorlist: https://mirrors.almalinux.org/mirrorlist/8.8/extras
- gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux'
almalinux_8_9_baseos:
repository: 'BaseOS'
description: 'AlmaLinux 8.9 - BaseOS'
@@ -70,12 +43,67 @@ profiles::reposync::repos_list:
release: '8.9'
mirrorlist: https://mirrors.almalinux.org/mirrorlist/8.9/extras
gpgkey: 'http://mirror.aarnet.edu.au/pub/almalinux/RPM-GPG-KEY-AlmaLinux'
+ centos_8_advanced_virtualization:
+ repository: 'virt-advanced-virtualization'
+ description: 'CentOS Advanced Virtualization'
+ osname: 'centos'
+ release: '8' # Assumed static value for demonstration
+ mirrorlist: 'http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=virt-advanced-virtualization' # Assuming 'stream' and 'x86_64'
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
+ centos_8_ceph_pacific:
+ repository: 'storage-ceph-pacific'
+ description: 'CentOS Ceph Pacific'
+ osname: 'centos'
+ release: '8' # Assumed static value for demonstration
+ mirrorlist: 'http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=storage-ceph-pacific' # Assuming '8' and 'x86_64'
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
+ centos_8_rabbitmq_38:
+ repository: 'messaging-rabbitmq-38'
+ description: 'CentOS RabbitMQ 38'
+ osname: 'centos'
+ release: '8-stream' # Specified based on the repository name
+ mirrorlist: 'http://mirrorlist.centos.org/?release=8-stream&arch=x86_64&repo=messaging-rabbitmq-38' # Assuming '8' and 'x86_64'
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Messaging'
+ centos_8_nfv_openvswitch:
+ repository: 'nfv-openvswitch-2'
+ description: 'CentOS NFV OpenvSwitch'
+ osname: 'centos'
+ release: '8-stream' # Assumed static value for demonstration
+ mirrorlist: 'http://mirrorlist.centos.org/?release=8-stream&arch=x86_64&repo=nfv-openvswitch-2' # Assuming 'stream' and 'x86_64'
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-NFV'
+ centos_8_openstack_xena:
+ repository: 'cloud-openstack-xena'
+ description: 'CentOS OpenStack Xena'
+ osname: 'centos'
+ release: '8-stream' # Directly taken from the provided mirrorlist
+ mirrorlist: 'http://mirrorlist.centos.org/?release=8-stream&arch=x86_64&repo=cloud-openstack-xena' # Assuming 'x86_64'
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Cloud'
+ centos_8_opstools:
+ repository: 'opstools-collectd-5'
+ description: 'CentOS OpsTools - collectd'
+ osname: 'centos'
+ release: '8-stream' # Assumed static value for demonstration
+ mirrorlist: 'http://mirrorlist.centos.org/?arch=x86_64&release=8-stream&repo=opstools-collectd-5' # Assuming 'stream' and 'x86_64'
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-OpsTools'
+ centos_8_ovirt45:
+ repository: 'virt-ovirt-45'
+ description: 'CentOS oVirt 4.5'
+ osname: 'centos'
+ release: '8-stream' # Assumed static value for demonstration
+ mirrorlist: 'http://mirrorlist.centos.org/?release=8-stream&arch=x86_64&repo=virt-ovirt-45' # Assuming 'stream' and 'x86_64'
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Virtualization'
+ centos_8_stream_gluster10:
+ repository: 'storage-gluster-10'
+ description: 'CentOS oVirt 4.5 - Glusterfs 10'
+ osname: 'centos'
+ release: '8-stream' # Assumed static value for demonstration
+ mirrorlist: 'http://mirrorlist.centos.org/?release=8-stream&arch=x86_64&repo=storage-gluster-10' # Assuming 'stream' and 'x86_64'
+ gpgkey: 'https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage'
epel_8_everything:
repository: 'Everything'
description: 'EPEL 8 Everything'
osname: 'epel'
release: '8'
- # baseurl: 'https://dl.fedoraproject.org/pub/epel/8/Everything/x86_64/'
mirrorlist: 'https://mirrors.fedoraproject.org/mirrorlist?repo=epel-8&arch=x86_64'
gpgkey: 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8'
mariadb_11_2_el8:
@@ -91,18 +119,18 @@ profiles::reposync::repos_list:
osname: 'puppet7'
release: 'el'
baseurl: 'https://yum.puppet.com/puppet7/el/8/x86_64/'
- gpgkey: 'https://yum.puppet.com/RPM-GPG-KEY-puppet'
+ gpgkey: 'https://yum.puppet.com/RPM-GPG-KEY-puppet-20250406'
postgresql_rhel8_common:
repository: 'common'
description: 'PostgreSQL Common RHEL 8'
osname: 'postgresql'
release: 'rhel8'
baseurl: 'https://download.postgresql.org/pub/repos/yum/common/redhat/rhel-8-x86_64/'
- gpgkey: 'https://download.postgresql.org/pub/repos/yum/RPM-GPG-KEY-PGDG'
+ gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
postgresql_rhel8_16:
repository: '16'
description: 'PostgreSQL 16 RHEL 8'
osname: 'postgresql'
release: 'rhel8'
baseurl: 'https://download.postgresql.org/pub/repos/yum/16/redhat/rhel-8-x86_64/'
- gpgkey: 'https://download.postgresql.org/pub/repos/yum/RPM-GPG-KEY-PGDG'
+ gpgkey: 'https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL'
diff --git a/hieradata/roles/infra/sql/galera.yaml b/hieradata/roles/infra/sql/galera.yaml
index f6965e6..084072a 100644
--- a/hieradata/roles/infra/sql/galera.yaml
+++ b/hieradata/roles/infra/sql/galera.yaml
@@ -1,11 +1,27 @@
---
-profiles::sql::galera_member::cluster_name: galera01
-profiles::sql::galera_member::galera_master: prodinf01n29.main.unkin.net
profiles::sql::galera_member::configure_firewall: false
profiles::sql::galera_member::wsrep_sst_method: rsync
profiles::sql::galera_member::galera_members_lookup: true
profiles::sql::galera_member::galera_members_role: roles::infra::sql::galera
profiles::sql::galera_member::datadir: /data/mariadb
-profiles::sql::galera_member::innodb_buffer_pool_size: 256M
profiles::sql::galera_member::innodb_file_per_table: 1
profiles::sql::galera_member::package_name: mariadb-galera-server
+
+consul::services:
+ mariadb:
+ service_name: "mariadb-%{facts.environment}"
+ tags:
+ - 'database'
+ - 'mariadb'
+ address: "%{facts.networking.ip}"
+ port: 3306
+ checks:
+ - id: 'mariadb_tcp_check'
+ name: 'MariaDB TCP Check'
+ tcp: "%{facts.networking.ip}:3306"
+ interval: '10s'
+ timeout: '1s'
+profiles::consul::client::node_rules:
+ - resource: service
+ segment: "mariadb-%{facts.environment}"
+ disposition: write
diff --git a/hieradata/roles/infra/storage/consul.eyaml b/hieradata/roles/infra/storage/consul.eyaml
new file mode 100644
index 0000000..4182583
--- /dev/null
+++ b/hieradata/roles/infra/storage/consul.eyaml
@@ -0,0 +1,2 @@
+---
+profiles::consul::server::acl_master_token: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAFCDnJyImf/X8f6WGqt37XbuuSg5hCeC5Uhdd0u1/Jjlz4AzMyhF41Vs6iVrV6irlsMDziSQrcEvGumTPmYShRQiRv0GvkhHUpn2XROKd63KolsWRj2K2S5FhgwolgtQc05DLmGaQ6FIUMVk3aKU/v8IGSDopcjdhwTJtheOLgiiEjv8TsjWKOOIa0H7caa6ZiZxcf2Y99Wv9gIZdt+LnXGdlDuO88+gkYTpRM07RY21nr4VS821y0MwFcYx2SyzMDk60RvgCmvA6RdoyHBUYAu07IX6IjP5LZwpAkcPcA4gADVP7vOPT2WhVAtkzpg+RwNxkuWYA5roO2r1UhERixjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBC9TM/c8nXJswHAUSU6kFCDgDBob2r0tFLq1Jw313Ys8jUtKsetsrc5x7uIDYzOqr7ulEM9B0VOD2ekR9IRYZMsBCg=]
diff --git a/hieradata/roles/infra/storage/consul.yaml b/hieradata/roles/infra/storage/consul.yaml
new file mode 100644
index 0000000..a3ea581
--- /dev/null
+++ b/hieradata/roles/infra/storage/consul.yaml
@@ -0,0 +1,79 @@
+---
+profiles::consul::server::members_lookup: true
+profiles::consul::server::data_dir: /data/consul
+profiles::consul::server::addresses:
+ dns: "%{::networking.ip}"
+ http: "%{::networking.ip}"
+ https: "%{::networking.ip}"
+ grpc: "%{::networking.ip}"
+ grpc_tls: "%{::networking.ip}"
+profiles::consul::server::ports:
+ dns: 8600
+ http: 8500
+ https: -1
+profiles::consul::server::acl:
+ enabled: true
+ default_policy: 'deny'
+ down_policy: 'extend-cache'
+ tokens:
+ initial_management: "%{alias('profiles::consul::server::acl_tokens_initial_management')}"
+ default: "%{alias('profiles::consul::server::acl_tokens_default')}"
+ replication: "%{alias('profiles::consul::server::acl_tokens_replication')}"
+
+# additional altnames
+profiles::pki::vault::alt_names:
+ - consul.main.unkin.net
+ - consul.service.consul
+ - consul
+
+# manage a simple nginx reverse proxy
+profiles::nginx::simpleproxy::nginx_vhost: 'consul.service.consul'
+profiles::nginx::simpleproxy::nginx_aliases:
+ - consul
+ - consul.main.unkin.net
+profiles::nginx::simpleproxy::proxy_port: 8500
+profiles::nginx::simpleproxy::proxy_path: '/'
+
+profiles::consul::prepared_query::rules:
+ vault:
+ ensure: 'present'
+ service_name: 'vault'
+ service_failover_n: 3
+ service_only_passing: true
+ ttl: 10
+ puppet:
+ ensure: 'present'
+ service_name: 'puppet'
+ service_failover_n: 3
+ service_only_passing: true
+ ttl: 10
+ puppetca:
+ ensure: 'present'
+ service_name: 'puppetca'
+ 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
+ puppetdbapi:
+ ensure: 'present'
+ service_name: 'puppetdbapi'
+ service_failover_n: 3
+ service_only_passing: true
+ ttl: 10
+ puppetboard:
+ ensure: 'present'
+ service_name: 'puppetboard'
+ service_failover_n: 3
+ service_only_passing: true
+ ttl: 10
+ git:
+ ensure: 'present'
+ service_name: 'git'
+ 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..7fcd2f8
--- /dev/null
+++ b/hieradata/roles/infra/storage/edgecache.yaml
@@ -0,0 +1,120 @@
+---
+consul::services:
+ edgecache:
+ 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_resolvers_enable: true
+profiles::edgecache::params::nginx_resolvers_ipv4only: true
+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/centos: { 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 }
+ /data/edgecache/pub/postgres: { owner: nginx, group: nginx }
+ /data/edgecache/pub/postgres/apt: { owner: nginx, group: nginx }
+ /data/edgecache/pub/postgres/yum: { 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'
+ centos_repodata:
+ ensure: present
+ location: '~* ^/centos/.*/repodata/'
+ proxy: http://gsl-syd.mm.fcix.net
+ centos_data:
+ ensure: present
+ location: /centos
+ proxy: http://gsl-syd.mm.fcix.net
+ 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'
+ postgres_yum_repodata:
+ ensure: present
+ location: '~* ^/postgres/yum/.*/repodata/'
+ rewrite_rules:
+ - '^/postgres/yum/(.*)$ /pub/repos/yum/$1 break'
+ proxy: https://download.postgresql.org
+ postgres_yum_data:
+ ensure: present
+ location: /postgres/yum
+ proxy: https://download.postgresql.org/pub/repos/yum
+ proxy_cache: cache
+ proxy_cache_valid:
+ - '200 302 1440h'
+ - '404 1m'
+ postgres_apt:
+ ensure: present
+ location: /postgres/apt
+ proxy: https://download.postgresql.org/pub/repos/apt
+ postgres_apt_pool:
+ ensure: present
+ location: /postgres/apt/pool
+ proxy: https://download.postgresql.org/pub/repos/apt/pool
+ proxy_cache: cache
+ proxy_cache_valid:
+ - '200 302 1440h'
+ - '404 1m'
diff --git a/hieradata/roles/infra/storage/minio.eyaml b/hieradata/roles/infra/storage/minio.eyaml
new file mode 100644
index 0000000..08e0b2d
--- /dev/null
+++ b/hieradata/roles/infra/storage/minio.eyaml
@@ -0,0 +1,2 @@
+---
+profiles::minio::server::minio_root_pass: ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAcAGh4K8P/bOwHs7FEAssBcYgtT+FlkMW4/jpJf230sbOh0jswvCl0woQMMw+AIpkXNJ//YcmDBkhdE92RCK8C4Xi/2nkdWjPt9FQwuT47BhAKISjunRs9R61dKj5aOwAlTQ3lNtsQsknGz17AMTyPEGQC9SnPxYirLRr9VgJX/EKPjl7M2LbkZTJChwIE6IiT+LSzye7YgpkJ7O6h4jNIp5ryWaUqSUfooYjqHc1zl4Bs9ZfyY1K/CWCTIbtd4hY1ZlskRlVa9yA0cWhsufV0gw43RA/bCAJPowLc64bZ4XlLx9Fy0qHKjTCDRLzysUoq0QjIR2Ulf1TkcCJAVLwFDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBC3+P+RW/JoQemkVJE/mpAngDAw1JpFkBvLj4AlbJePvpnG+fFN8coOE+5N94NgGd9Gtl2NZt/g5x/7xFHS28cSlIg=]
diff --git a/hieradata/roles/infra/storage/minio.yaml b/hieradata/roles/infra/storage/minio.yaml
new file mode 100644
index 0000000..62505fb
--- /dev/null
+++ b/hieradata/roles/infra/storage/minio.yaml
@@ -0,0 +1,9 @@
+---
+profiles::minio::server::minio_members_role: roles::infra::storage::minio
+profiles::minio::server::minio_root_user: admin
+profiles::minio::server::minio_opts:
+ - '--anonymous'
+profiles::minio::server::minio_members_lookup: true
+profiles::minio::server::version: 'RELEASE.2023-12-20T01-00-02Z'
+profiles::minio::server::checksum: '09fafaf399885b4912bafda6fa03fc4ccbc39ec45e17239677217317915d6aeb'
+profiles::minio::server::checksum_type: 'sha256'
diff --git a/hieradata/roles/infra/storage/vault.eyaml b/hieradata/roles/infra/storage/vault.eyaml
new file mode 100644
index 0000000..11fff31
--- /dev/null
+++ b/hieradata/roles/infra/storage/vault.eyaml
@@ -0,0 +1,7 @@
+---
+vault::unseal_keys:
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAHfDhuu2C5ZEALdJlmOqWukEiAQQiVJ7KjpSRuf9h7RYwR+u8UNdcJYK1xFvYwmUczw6hkST/Zr06T4JwavpAHHuaRbyl8N1qZjlwt4MO5CPUTBT8k+EOaocF2byUXpYBThETjLB+WNLJAU3Dq8JboekCJ2F1Zjd8Mmdtu1C3Ip5ii5iVGbQShxDSPsdjtk8Q49lUKj61tLyuvadcTcxllHyXs6siWl7atBfIS6OX5KgA66VJhxOeoyyBaiqSSu7OqqZa2siYGTvjJS3UFDf8J+itsJJ1+0KUtkl07PvItkIruSAlHZGagVPrizAyEx1j4hFvVTGHac86bcV/5M9z5DBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDCjxoJHSXr/4XvXaxVbUGOgDCQ4DL05Qnw3+3qHWZRKvNChHgrhRPi2HmkiGni+A4ZVF9LHs+mF8TQ/t3Q1DrSy3I=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAoapLUNj1f+7BEvjzR9CO0Qz3LhI5M326BVliikRY7hpL2+0CnTOlR9K3YapD83LtpuiNbXqbk1mhi44ak0CTet8yz0ZH/BPkVYgV2Ll9ISdN4Knnnlf2Ljt/gHGf03jiUKwfXxu87LfvCySAMgzYonQ90cfIDc+XH6CoQv27WM3U1q79RcWl/w9Z/XwJiKyANSCXfBT16+RawrzmVo+zWbteqx09MfOHr7Q36VwOqjJaO94A/Dj3m/YJIOhmYXd52h+am6Kc1Q9dnzycKZYoKYOv+qi+bY4frx9sRvBxoGDGMb1mXTDSPeIT6NXbMCIsTsmYxjxAvBET72oKWXJUcDBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDy/pkTHpz4F9l1J6cKW4A9gDD873VdHr3ArjpE1R82wS5brCbBe7ntEuNFQMbnFPvOXwI4EaYV3IMRNv6Lzk6BBSI=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAVKVb6/nhbgEx6b2b90gfuXbZglZpoJjQtyzDQtCZzcZxh/xVFjwUy1XX/3+dueazFd5Ge5NnqQdxs/h5MBSjexHJhEm3fmA+gnns8sdYX5SDJSnhYvS1cB/wmfHuvkj3ZhIFxg0jlPlKz24QST99ouxKI2c490ByIbcFCr+A5GWnO7D/kf1Y+M0Sg2YiPE4zqF2zx1sgOfaV2xvQbRqqSjDPim/mYff95AtWwN9KbcAvc/7vDi4PrHR8GY9RXhI8FBEvelAT0H0NmnaCw4TvWXF/YxztlG9E55G3MsFyVAQJT7Dl8w4w5nk4AJJBMaXlO2s4AWD4Y+MVQh62hjqgHjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBptatyhSChU/V0R+IVd5hRgDCmA07/V4UBz1nVMc2vZm2KvnUOPofO74hwkkoxOnk6O2h6arbw8GNHj7WxeHXoXPk=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAOGvhPhbKt8hkYTif5C+IE7iqcoeXm68BeUzlzE9qAY7lzQoAENauDKoIgoQT0hA7zrKZXPTUDrcw8SdxNp7Zo/Dr44urdr4LiT+QZwYTE09Xn8yIA3ij1XnXQ5bYP70TycuOjpVT0BKK+qSkklfd7IAw76AnUWF1D6P9MjT+shOmVNHQQSRrL2JLNppetQRCyOEMzkeDI/58/ohexvyUcY8WT4YMNhl/IrNBdcJ3xOwnJqEAXSUTre15T2I+7f+prhj4cS2V9qd0ZwUXSueL38EIMKwmq1ugb+zm8UYzqfKpRk/1THqT8T/r8B4PR2QxtiwtzLk388ag1mqQ/jHL9zBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAlKLuJOARFD1vt/R9gfp4LgDA0irHwG41ByRyYcKT87ra9tsdhb+i9ugnNRbFQ1UPTk7bFwS3HUteEJwNzcNIwFXY=]
+ - ENC[PKCS7,MIIBmQYJKoZIhvcNAQcDoIIBijCCAYYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAEQvjVATvI+UVWrowTWSxtluiPrfa8akOSgr+MdcAh5Mgypw6RUeVJ2Sh8jekePZOO7Y0IQSfyNWOFAsaxBgeG7aEu6loFwxcSzrilg9c/2bV7Ybxr5saDViTjHO+UOYPPVRsJKeYvWd+vTdM+J7Eg3LGwzdLqyYu824affGm41KsSJdtxbNC1EzR+AOEU7SO8FkDIUZl2ekwz+3FfBX5TyXywlZGrbS7DkABB1jrO/JJtgnRu4D1AgUWjSJINXKyi9Xf91ZUyYCbVJ1asmRhOcCDcRigs82CF6nWbsSad80Z/ZoGVGYSlCsSXd4t8iEujCzeTkfBRK6Azr71f0zbBjBcBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBAeR7zOfSz3Sd19UkcmdMJLgDBiPUNdk6zh2inhCqms/qnt7BqDBAYEzHuzbsM3U3PO+UIeJdym51cu3YKw3MkVuyw=]
diff --git a/hieradata/roles/infra/storage/vault.yaml b/hieradata/roles/infra/storage/vault.yaml
new file mode 100644
index 0000000..7d5cc42
--- /dev/null
+++ b/hieradata/roles/infra/storage/vault.yaml
@@ -0,0 +1,24 @@
+---
+profiles::vault::server::members_role: roles::infra::storage::vault
+profiles::vault::server::members_lookup: true
+profiles::vault::server::data_dir: /data/vault
+profiles::vault::server::manage_storage_dir: true
+profiles::vault::server::tls_disable: false
+vault::download_url: http://repos.main.unkin.net/unkin/8/x86_64/os/Archives/vault_1.15.5_linux_amd64.zip
+
+# additional altnames
+profiles::pki::vault::alt_names:
+ - vault.main.unkin.net
+ - vault.service.consul
+ - vault.service.consul
+ - vault
+
+# manage a simple nginx reverse proxy
+profiles::nginx::simpleproxy::nginx_vhost: 'vault.service.consul'
+profiles::nginx::simpleproxy::nginx_aliases:
+ - vault.main.unkin.net
+ - vault
+profiles::nginx::simpleproxy::proxy_scheme: 'http'
+profiles::nginx::simpleproxy::proxy_host: '127.0.0.1'
+profiles::nginx::simpleproxy::proxy_port: 8200
+profiles::nginx::simpleproxy::proxy_path: '/'
diff --git a/hieradata/virtual/kvm.yaml b/hieradata/virtual/kvm.yaml
new file mode 100644
index 0000000..e69de29
diff --git a/hieradata/virtual/physical.yaml b/hieradata/virtual/physical.yaml
new file mode 100644
index 0000000..75630e7
--- /dev/null
+++ b/hieradata/virtual/physical.yaml
@@ -0,0 +1,3 @@
+---
+profiles::packages::install:
+ - "%{hiera('lm-sensors::package')}"
diff --git a/site/profiles/lib/facter/arpa.rb b/modules/libs/lib/facter/arpa.rb
similarity index 100%
rename from site/profiles/lib/facter/arpa.rb
rename to modules/libs/lib/facter/arpa.rb
diff --git a/modules/libs/lib/facter/cobbler_data_dir_exists.rb b/modules/libs/lib/facter/cobbler_data_dir_exists.rb
new file mode 100644
index 0000000..d716b35
--- /dev/null
+++ b/modules/libs/lib/facter/cobbler_data_dir_exists.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+Facter.add('cobbler_data_dir_exists') do
+ confine enc_role: 'roles::infra::cobbler::server'
+ setcode do
+ File.exist?('/data/cobbler')
+ end
+end
diff --git a/modules/libs/lib/facter/cobbler_var_www_exists.rb b/modules/libs/lib/facter/cobbler_var_www_exists.rb
new file mode 100644
index 0000000..aa445b8
--- /dev/null
+++ b/modules/libs/lib/facter/cobbler_var_www_exists.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+Facter.add('cobbler_var_www_exists') do
+ confine enc_role: 'roles::infra::cobbler::server'
+ setcode do
+ File.exist?('/var/www/cobbler')
+ end
+end
diff --git a/modules/libs/lib/facter/cobbler_var_www_islink.rb b/modules/libs/lib/facter/cobbler_var_www_islink.rb
new file mode 100644
index 0000000..13d9c6e
--- /dev/null
+++ b/modules/libs/lib/facter/cobbler_var_www_islink.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+Facter.add('cobbler_var_www_islink') do
+ confine enc_role: 'roles::infra::cobbler::server'
+ setcode do
+ File.exist?('/var/www/cobbler') and File.symlink?('/var/www/cobbler')
+ end
+end
diff --git a/modules/libs/lib/facter/enc_env.rb b/modules/libs/lib/facter/enc_env.rb
new file mode 100644
index 0000000..2975c45
--- /dev/null
+++ b/modules/libs/lib/facter/enc_env.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+Facter.add('enc_env') do
+ setcode do
+ require 'yaml'
+ # Check if the YAML file exists
+ if File.exist?('/root/.cache/custom_facts.yaml')
+ data = YAML.load_file('/root/.cache/custom_facts.yaml')
+ # Use safe navigation to return 'enc_env' or nil
+ data&.dig('enc_env')
+ end
+ end
+end
diff --git a/modules/libs/lib/facter/enc_role.rb b/modules/libs/lib/facter/enc_role.rb
new file mode 100644
index 0000000..979b4bf
--- /dev/null
+++ b/modules/libs/lib/facter/enc_role.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+Facter.add('enc_role') do
+ setcode do
+ require 'yaml'
+ # Check if the YAML file exists
+ if File.exist?('/root/.cache/custom_facts.yaml')
+ data = YAML.load_file('/root/.cache/custom_facts.yaml')
+ # Use safe navigation to return 'enc_role' or nil
+ data&.dig('enc_role')
+ end
+ end
+end
diff --git a/site/profiles/lib/facter/enc_role_path.rb b/modules/libs/lib/facter/enc_role_path.rb
similarity index 100%
rename from site/profiles/lib/facter/enc_role_path.rb
rename to modules/libs/lib/facter/enc_role_path.rb
diff --git a/site/profiles/lib/facter/enc_role_tier1.rb b/modules/libs/lib/facter/enc_role_tier1.rb
similarity index 100%
rename from site/profiles/lib/facter/enc_role_tier1.rb
rename to modules/libs/lib/facter/enc_role_tier1.rb
diff --git a/site/profiles/lib/facter/enc_role_tier2.rb b/modules/libs/lib/facter/enc_role_tier2.rb
similarity index 100%
rename from site/profiles/lib/facter/enc_role_tier2.rb
rename to modules/libs/lib/facter/enc_role_tier2.rb
diff --git a/site/profiles/lib/facter/enc_role_tier3.rb b/modules/libs/lib/facter/enc_role_tier3.rb
similarity index 100%
rename from site/profiles/lib/facter/enc_role_tier3.rb
rename to modules/libs/lib/facter/enc_role_tier3.rb
diff --git a/modules/libs/lib/facter/firstrun.rb b/modules/libs/lib/facter/firstrun.rb
new file mode 100644
index 0000000..012aafc
--- /dev/null
+++ b/modules/libs/lib/facter/firstrun.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+Facter.add(:firstrun) do
+ confine kernel: 'Linux'
+ setcode do
+ File.exist?('/root/.cache/puppet_firstrun_complete') ? false : true
+ end
+end
diff --git a/modules/libs/lib/facter/is_pveceph_mgr.rb b/modules/libs/lib/facter/is_pveceph_mgr.rb
new file mode 100644
index 0000000..cb1a243
--- /dev/null
+++ b/modules/libs/lib/facter/is_pveceph_mgr.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'facter'
+
+Facter.add('is_pveceph_mgr') do
+ confine enc_role: 'roles::infra::proxmox::node'
+ setcode do
+ system('pgrep -x ceph-mgr > /dev/null 2>&1')
+ end
+end
diff --git a/modules/libs/lib/facter/is_pveceph_mon.rb b/modules/libs/lib/facter/is_pveceph_mon.rb
new file mode 100644
index 0000000..e32a312
--- /dev/null
+++ b/modules/libs/lib/facter/is_pveceph_mon.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'facter'
+
+Facter.add('is_pveceph_mon') do
+ confine enc_role: 'roles::infra::proxmox::node'
+ setcode do
+ system('pgrep -x ceph-mon > /dev/null 2>&1')
+ end
+end
diff --git a/site/profiles/lib/facter/mariadb_active.rb b/modules/libs/lib/facter/mariadb_active.rb
similarity index 100%
rename from site/profiles/lib/facter/mariadb_active.rb
rename to modules/libs/lib/facter/mariadb_active.rb
diff --git a/site/profiles/lib/facter/mariadb_datapath.rb b/modules/libs/lib/facter/mariadb_datapath.rb
similarity index 100%
rename from site/profiles/lib/facter/mariadb_datapath.rb
rename to modules/libs/lib/facter/mariadb_datapath.rb
diff --git a/site/profiles/lib/facter/mariadb_galera_active.rb b/modules/libs/lib/facter/mariadb_galera_active.rb
similarity index 100%
rename from site/profiles/lib/facter/mariadb_galera_active.rb
rename to modules/libs/lib/facter/mariadb_galera_active.rb
diff --git a/site/profiles/lib/facter/mariadb_installed.rb b/modules/libs/lib/facter/mariadb_installed.rb
similarity index 100%
rename from site/profiles/lib/facter/mariadb_installed.rb
rename to modules/libs/lib/facter/mariadb_installed.rb
diff --git a/modules/libs/lib/facter/minio_datadirs_initialised.rb b/modules/libs/lib/facter/minio_datadirs_initialised.rb
new file mode 100644
index 0000000..17180ab
--- /dev/null
+++ b/modules/libs/lib/facter/minio_datadirs_initialised.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+# check all datadirs for minio are initialised
+
+require 'yaml'
+Facter.add('minio_datadirs_initialised') do
+ setcode do
+ yaml_file_path = '/opt/puppetlabs/facter/facts.d/minio_facts.yaml'
+
+ # check if the YAML file exists first
+ next false unless File.exist?(yaml_file_path)
+
+ minio_facts = YAML.load_file(yaml_file_path)
+ dev_count = minio_facts['minio_blockdev_count']
+ datadir = minio_facts['minio_datadir']
+
+ # check datadir if no blockdevices are used, otherwise check the store locations
+ if dev_count.zero?
+ Dir.exist?(datadir)
+ else
+ (1..dev_count).all? do |number|
+ Dir.exist?("#{datadir}/store#{number}")
+ end
+ end
+ end
+end
diff --git a/modules/libs/lib/facter/minio_group_exists.rb b/modules/libs/lib/facter/minio_group_exists.rb
new file mode 100644
index 0000000..14c322a
--- /dev/null
+++ b/modules/libs/lib/facter/minio_group_exists.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+# check that the minio group exists
+
+require 'yaml'
+Facter.add('minio_group_exists') do
+ setcode do
+ yaml_file_path = '/opt/puppetlabs/facter/facts.d/minio_facts.yaml'
+
+ # check if the YAML file exists first
+ next false unless File.exist?(yaml_file_path)
+
+ minio_facts = YAML.load_file(yaml_file_path)
+ group_name = minio_facts['minio_group']
+
+ group_exists = system("getent group #{group_name} >/dev/null 2>&1")
+
+ group_exists
+ end
+end
diff --git a/modules/libs/lib/facter/minio_pool_dns.rb b/modules/libs/lib/facter/minio_pool_dns.rb
new file mode 100644
index 0000000..6ccf804
--- /dev/null
+++ b/modules/libs/lib/facter/minio_pool_dns.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'facter'
+require 'yaml'
+
+Facter.add('minio_pool_dns') do
+ setcode do
+ yaml_file_path = '/opt/puppetlabs/facter/facts.d/minio_facts.yaml'
+
+ # check if the YAML file exists
+ next {} unless File.exist?(yaml_file_path)
+
+ # load data from YAML
+ data = YAML.load_file(yaml_file_path)
+ minio_members = data['minio_members']
+ minio_region = data['minio_region']
+ minio_pool = data['minio_pool']
+ domain = Facter.value(:networking)['domain']
+
+ # create result hash
+ result = {}
+
+ # Check CNAME for each node_id from 1 to minio_members
+ (1..minio_members).each do |node_id|
+ cname_target = "#{minio_region}-#{minio_pool}-#{node_id}.#{domain}"
+ command = "host #{cname_target} > /dev/null 2>&1"
+
+ # Using system method to execute the command
+ # It returns true if the command gives exit status 0 (success), otherwise false
+ result[cname_target] = system(command)
+ end
+
+ result
+ end
+end
diff --git a/modules/libs/lib/facter/minio_user_exists.rb b/modules/libs/lib/facter/minio_user_exists.rb
new file mode 100644
index 0000000..e1b3ef2
--- /dev/null
+++ b/modules/libs/lib/facter/minio_user_exists.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+# check that the minio user exists
+
+require 'yaml'
+Facter.add('minio_user_exists') do
+ setcode do
+ yaml_file_path = '/opt/puppetlabs/facter/facts.d/minio_facts.yaml'
+
+ # check if the YAML file exists first
+ next false unless File.exist?(yaml_file_path)
+
+ minio_facts = YAML.load_file(yaml_file_path)
+ user_name = minio_facts['minio_user']
+
+ user_exists = system("id #{user_name} >/dev/null 2>&1")
+
+ user_exists
+ end
+end
diff --git a/site/profiles/lib/facter/mysql_wsrep.rb b/modules/libs/lib/facter/mysql_wsrep.rb
similarity index 100%
rename from site/profiles/lib/facter/mysql_wsrep.rb
rename to modules/libs/lib/facter/mysql_wsrep.rb
diff --git a/modules/libs/lib/facter/nameservers.rb b/modules/libs/lib/facter/nameservers.rb
new file mode 100644
index 0000000..8ece095
--- /dev/null
+++ b/modules/libs/lib/facter/nameservers.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+Facter.add(:nameservers) do
+ confine kernel: 'Linux'
+ setcode do
+ nameservers = File.readlines('/etc/resolv.conf').grep(/^nameserver\s+(\S+)/) { Regexp.last_match(1) }
+ nameservers
+ end
+end
diff --git a/modules/libs/lib/facter/pve_ceph_config.rb b/modules/libs/lib/facter/pve_ceph_config.rb
new file mode 100644
index 0000000..e836a99
--- /dev/null
+++ b/modules/libs/lib/facter/pve_ceph_config.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'facter'
+
+Facter.add('ceph_global_config') do
+ confine enc_role: 'roles::infra::proxmox::node'
+ setcode do
+ config_file = '/etc/pve/ceph.conf'
+ config_hash = {}
+ in_global_section = false
+
+ if File.exist?(config_file)
+ File.readlines(config_file).each do |line|
+ line.strip!
+ # Detect the [global] section and set flag
+ if line == '[global]'
+ in_global_section = true
+ next
+ end
+
+ # Exit the loop once we're out of the global section
+ break if line.start_with?('[') && in_global_section
+
+ # Parse key-value pairs if we are in the global section
+ if in_global_section && line.include?('=')
+ key, value = line.split('=', 2).map(&:strip)
+ config_hash[key] = value
+ end
+ end
+ end
+
+ config_hash
+ end
+end
diff --git a/modules/libs/lib/facter/pve_ceph_initialised.rb b/modules/libs/lib/facter/pve_ceph_initialised.rb
new file mode 100644
index 0000000..52c4c4e
--- /dev/null
+++ b/modules/libs/lib/facter/pve_ceph_initialised.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'facter'
+
+Facter.add('pve_ceph_initialised') do
+ confine enc_role: 'roles::infra::proxmox::node'
+ setcode do
+ File.exist?('/etc/pve/ceph.conf')
+ end
+end
diff --git a/modules/libs/lib/facter/pve_cluster.rb b/modules/libs/lib/facter/pve_cluster.rb
new file mode 100644
index 0000000..05efec1
--- /dev/null
+++ b/modules/libs/lib/facter/pve_cluster.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'facter'
+
+Facter.add('pve_cluster') do
+ confine enc_role: 'roles::infra::proxmox::node'
+ setcode do
+ conf_file = '/etc/pve/corosync.conf'
+ totem_details = {}
+ in_totem_section = false
+
+ if File.exist?(conf_file)
+ File.foreach(conf_file) do |line|
+ if line =~ /^\s*totem\s*\{/
+ in_totem_section = true
+ elsif line =~ /^\s*\}/ && in_totem_section
+ break
+ elsif in_totem_section && line =~ /^\s*(\w+):\s*(.+)$/
+ key = Regexp.last_match(1).strip
+ value = Regexp.last_match(2).strip
+ totem_details[key] = value
+ end
+ end
+ end
+
+ totem_details.empty? ? nil : totem_details
+ end
+end
diff --git a/modules/libs/lib/facter/pve_cluster_member.rb b/modules/libs/lib/facter/pve_cluster_member.rb
new file mode 100644
index 0000000..602adf8
--- /dev/null
+++ b/modules/libs/lib/facter/pve_cluster_member.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'facter'
+
+Facter.add('pve_cluster_member') do
+ confine enc_role: 'roles::infra::proxmox::node'
+ setcode do
+ if Facter::Util::Resolution.which('pvesh')
+ cluster_status = `pvesh get /cluster/status --output-format json`
+ if cluster_status.empty?
+ false
+ else
+ require 'json'
+ status = JSON.parse(cluster_status)
+ !status.empty?
+ end
+ else
+ false
+ end
+ end
+end
diff --git a/modules/libs/lib/facter/pve_nodelist.rb b/modules/libs/lib/facter/pve_nodelist.rb
new file mode 100644
index 0000000..4e16d81
--- /dev/null
+++ b/modules/libs/lib/facter/pve_nodelist.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'facter'
+
+Facter.add('pve_nodelist') do
+ confine enc_role: 'roles::infra::proxmox::node'
+ setcode do
+ conf_file = '/etc/pve/corosync.conf'
+ node_list = {}
+ current_node = nil
+ # rubocop:disable Metrics/BlockNesting
+
+ if File.exist?(conf_file)
+ File.foreach(conf_file) do |line|
+ if line =~ /^\s*node\s*\{/
+ current_node = {}
+ elsif line =~ /^\s*\}/
+ if current_node
+ node_name = current_node['name']
+ node_list[node_name] = current_node if node_name
+ current_node = nil
+ end
+ elsif current_node && line =~ /^\s*(\w+):\s*(.+)$/
+ key = Regexp.last_match(1).strip
+ value = Regexp.last_match(2).strip
+ current_node[key] = value
+ end
+ end
+ end
+
+ # rubocop:enable Metrics/BlockNesting
+
+ node_list.empty? ? nil : node_list
+ end
+end
diff --git a/modules/libs/lib/facter/pve_nodes_active.rb b/modules/libs/lib/facter/pve_nodes_active.rb
new file mode 100644
index 0000000..fade65d
--- /dev/null
+++ b/modules/libs/lib/facter/pve_nodes_active.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'facter'
+
+Facter.add('pve_nodes_active') do
+ confine enc_role: 'roles::infra::proxmox::node'
+ setcode do
+ if Facter::Util::Resolution.which('pvesh')
+ proxmox_nodes = `pvesh get /nodes --output-format json`
+ unless proxmox_nodes.empty?
+ require 'json'
+ nodes = JSON.parse(proxmox_nodes)
+ nodes.count
+ end
+ end
+ end
+end
diff --git a/modules/libs/lib/facter/subnet_facts.rb b/modules/libs/lib/facter/subnet_facts.rb
new file mode 100644
index 0000000..458c8e0
--- /dev/null
+++ b/modules/libs/lib/facter/subnet_facts.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'ipaddr'
+
+# a class that creates facts based on the subnet
+class SubnetAttributes
+ SUBNET_TO_ATTRIBUTES = {
+ '198.18.13.0/24' => { environment: 'prod', region: 'syd1', country: 'au' },
+ '198.18.14.0/24' => { environment: 'prod', region: 'syd1', country: 'au' },
+ '198.18.15.0/24' => { environment: 'prod', region: 'syd1', country: 'au' },
+ '198.18.16.0/24' => { environment: 'test', region: 'syd1', country: 'au' },
+ '198.18.17.0/24' => { environment: 'prod', region: 'drw1', country: 'au' },
+ '198.18.18.0/24' => { environment: 'test', region: 'drw1', country: 'au' }
+ }.freeze
+
+ # Default attributes if no subnet matches, also defined as a constant
+ DEFAULT_ATTRIBUTES = { environment: 'unknown', region: 'unknown', country: 'unknown' }.freeze
+
+ # provide ip to return attributes
+ def self.attributes(ip)
+ SUBNET_TO_ATTRIBUTES.each do |subnet, attrs|
+ return attrs if IPAddr.new(subnet).include?(IPAddr.new(ip))
+ end
+
+ DEFAULT_ATTRIBUTES
+ end
+end
+
+# Use the primary IP address from facts
+ip = Facter.value(:networking)['ip']
+
+# Call the class method directly without creating an instance
+subnet_attributes = SubnetAttributes.attributes(ip)
+
+# Add separate facts for environment, region, and country
+Facter.add('environment') { setcode { subnet_attributes[:environment] } }
+Facter.add('region') { setcode { subnet_attributes[:region] } }
+Facter.add('country') { setcode { subnet_attributes[:country] } }
diff --git a/modules/libs/lib/facter/vault_cert_altnames.rb b/modules/libs/lib/facter/vault_cert_altnames.rb
new file mode 100644
index 0000000..05194f0
--- /dev/null
+++ b/modules/libs/lib/facter/vault_cert_altnames.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# lib/facter/vault_cert_altnames.rb
+require 'puppet'
+
+Facter.add('vault_cert_altnames') do
+ setcode do
+ alt_names_file = '/etc/pki/tls/vault/alt_names'
+ if File.exist?(alt_names_file)
+ File.read(alt_names_file).split("\n")
+ else
+ []
+ end
+ end
+end
diff --git a/modules/libs/lib/facter/vault_cert_expiring.rb b/modules/libs/lib/facter/vault_cert_expiring.rb
new file mode 100644
index 0000000..359609c
--- /dev/null
+++ b/modules/libs/lib/facter/vault_cert_expiring.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+# lib/facter/vault_cert_expiring.rb
+require 'puppet'
+
+Facter.add(:vault_cert_expiring) do
+ setcode do
+ require 'openssl'
+ cert_path = '/etc/pki/tls/vault/certificate.crt'
+ if File.exist?(cert_path)
+ # If the certificate file exists, check its expiration
+ cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
+ cert_expiry = cert.not_after
+ days_remaining = (cert_expiry - Time.now).to_i / (24 * 60 * 60)
+ days_remaining < 30
+ else
+ # Report true if the certificate file does not exist
+ true
+ end
+ end
+end
diff --git a/site/profiles/manifests/accounts/sysadmin.pp b/site/profiles/manifests/accounts/sysadmin.pp
index 81bde92..f766f31 100644
--- a/site/profiles/manifests/accounts/sysadmin.pp
+++ b/site/profiles/manifests/accounts/sysadmin.pp
@@ -1,15 +1,16 @@
# create the sysadmin user
class profiles::accounts::sysadmin(
+ String $password,
Array[String] $sshkeys = [],
){
profiles::base::account {'sysadmin':
- username => 'sysadmin',
- uid => 1000,
- gid => 1000,
- groups => ['wheel'],
- sshkeys => $sshkeys,
- sudo_rules => ['sysadmin ALL=(ALL) NOPASSWD:ALL'],
- password => '',
- ignore_pass => true,
+ username => 'sysadmin',
+ uid => 1000,
+ gid => 1000,
+ groups => ['adm', 'admins', 'systemd-journal'],
+ sshkeys => $sshkeys,
+ sudo_rules => ['sysadmin ALL=(ALL) NOPASSWD:ALL'],
+ password => $password,
+ require => Group['admins'],
}
}
diff --git a/site/profiles/manifests/apt/puppet7.pp b/site/profiles/manifests/apt/puppet7.pp
index e9e336f..6424efe 100644
--- a/site/profiles/manifests/apt/puppet7.pp
+++ b/site/profiles/manifests/apt/puppet7.pp
@@ -30,27 +30,17 @@ class profiles::apt::puppet7 (
Array[String] $managed_repos,
String $mirror,
String $repo,
- String $dist,
) {
$codename = $facts['os']['distro']['codename']
if 'puppet7' in $managed_repos {
- $puppet_source = "${mirror}/${repo}-release-${dist}.deb"
-
- # Install the puppet release using dpkg
- package { "${repo}-${dist}":
- ensure => installed,
- name => "${repo}-release",
- provider => dpkg,
- source => $puppet_source,
- }
# deb http://apt.puppet.com bullseye puppet7
apt::source { 'puppet7':
location => $mirror,
repos => $repo,
- release => $dist,
+ release => $codename,
include => {
'src' => false,
'deb' => true,
diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp
index 607136b..13f6b10 100644
--- a/site/profiles/manifests/base.pp
+++ b/site/profiles/manifests/base.pp
@@ -3,55 +3,64 @@ class profiles::base (
Array $puppet_servers,
) {
- case $facts['os']['family'] {
- 'RedHat': {
- include profiles::yum::global
- include profiles::firewall::firewalld
+ # run a limited set of classes on the first run aimed at bootstrapping the new node
+ if $facts['firstrun'] {
+ include profiles::firstrun::init
+ }else{
+
+ # install the vault ca first
+ include profiles::pki::vaultca
+
+ # manage the puppet agent
+ include profiles::puppet::agent
+
+ # manage puppet clients
+ if ! member($puppet_servers, $trusted['certname']) {
+ include profiles::puppet::client
}
- 'Debian': {
- include profiles::apt::global
+
+ # include the base profiles
+ include profiles::base::repos
+ include profiles::packages
+ include profiles::base::facts
+ include profiles::base::motd
+ include profiles::base::scripts
+ include profiles::base::hosts
+ include profiles::base::groups
+ include profiles::base::root
+ include profiles::accounts::sysadmin
+ include profiles::ntp::client
+ include profiles::dns::base
+ include profiles::pki::vault
+ include profiles::cloudinit::init
+ include profiles::metrics::default
+ include profiles::helpers::node_lookup
+ include profiles::consul::client
+
+ # include the python class
+ class { 'python':
+ manage_python_package => true,
+ manage_venv_package => true,
+ manage_pip_package => true,
+ use_epel => false,
}
- default: {
- fail("Unsupported OS family ${facts['os']['family']}")
+
+ # all hosts will have sudo applied
+ class { 'sudo':
+ secure_path => '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/opt/puppetlabs/bin'
}
- }
- # manage the puppet agent
- include profiles::puppet::agent
+ # manage virtualised guest agents
+ if $::facts['is_virtual'] and $::facts['dmi']['manufacturer'] == 'QEMU' {
+ include profiles::qemu::agent
+ }
- # manage puppet clients
- if ! member($puppet_servers, $trusted['certname']) {
- include profiles::puppet::client
- }
+ # include classes from hiera
+ lookup('hiera_classes', Array[String], 'unique').include
- # include the base profiles
- include profiles::packages::base
- include profiles::base::facts
- include profiles::base::motd
- include profiles::base::scripts
- include profiles::base::hosts
- include profiles::accounts::sysadmin
- include profiles::ntp::client
- include profiles::dns::base
- include profiles::cloudinit::init
- include profiles::metrics::default
- include profiles::helpers::node_lookup
-
- # include the python class
- class { 'python':
- manage_python_package => true,
- manage_venv_package => true,
- manage_pip_package => true,
- use_epel => false,
- }
-
- # all hosts will have sudo applied
- class { 'sudo':
- secure_path => '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/opt/puppetlabs/bin'
- }
-
- # manage virtualised guest agents
- if $::facts['is_virtual'] and $::facts['dmi']['manufacturer'] == 'QEMU' {
- include profiles::qemu::agent
+ # specifc ordering constraints
+ Class['profiles::pki::vaultca']
+ -> Class['profiles::base::repos']
+ -> Class['profiles::packages']
}
}
diff --git a/site/profiles/manifests/base/datavol.pp b/site/profiles/manifests/base/datavol.pp
index 4384bb6..5cb2a12 100644
--- a/site/profiles/manifests/base/datavol.pp
+++ b/site/profiles/manifests/base/datavol.pp
@@ -11,6 +11,7 @@
#
class profiles::base::datavol (
Enum['present', 'absent'] $ensure = 'present',
+ Enum['present', 'absent', 'mounted'] $mountstate = 'mounted',
Enum['ext2', 'ext3', 'ext4', 'xfs', 'btrfs'] $fstype = 'xfs',
String $vg = 'datavg',
String $pv = '/dev/vdb',
@@ -63,7 +64,7 @@ class profiles::base::datavol (
# Ensure the logical volume is mounted at the desired location
mount { $mount:
- ensure => $ensure,
+ ensure => $mountstate,
device => "/dev/${vg}/${lv}",
fstype => $fstype,
options => $mount_options.join(','),
diff --git a/site/profiles/manifests/base/facts.pp b/site/profiles/manifests/base/facts.pp
index e234625..5344d19 100644
--- a/site/profiles/manifests/base/facts.pp
+++ b/site/profiles/manifests/base/facts.pp
@@ -12,18 +12,28 @@ class profiles::base::facts {
mode => '0755',
}
- # facts to create
+ # cleanup old facts files
$fact_list = [ 'enc_role', 'enc_env' ]
-
- # Manage the external fact file with content from the template
$fact_list.each | String $item | {
file { "${facts_d_path}/${item}.txt":
- ensure => file,
- owner => 'root',
- group => 'root',
- mode => '0644',
- content => template("profiles/base/facts/${item}.erb"),
- require => File[$facts_d_path],
+ ensure => absent,
}
}
+
+ # ensure the path to the custom store exists
+ file { '/root/.cache':
+ ensure => directory,
+ owner => 'root',
+ group => 'root',
+ mode => '0750',
+ }
+
+ # create the file that will be read
+ file { '/root/.cache/custom_facts.yaml':
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ content => template('profiles/base/facts/custom_facts.yaml.erb'),
+ }
}
diff --git a/site/profiles/manifests/base/groups.pp b/site/profiles/manifests/base/groups.pp
new file mode 100644
index 0000000..56d9237
--- /dev/null
+++ b/site/profiles/manifests/base/groups.pp
@@ -0,0 +1,12 @@
+# profiles::base::groups
+# simple group management
+class profiles::base::groups (
+ Hash $local = {},
+) {
+ $local.each |$group, $data| {
+ group { $group:
+ name => $group,
+ * => $data,
+ }
+ }
+}
diff --git a/site/profiles/manifests/base/motd.pp b/site/profiles/manifests/base/motd.pp
index e1dd5ca..4799976 100644
--- a/site/profiles/manifests/base/motd.pp
+++ b/site/profiles/manifests/base/motd.pp
@@ -7,6 +7,8 @@ class profiles::base::motd (
String $nic = $facts['networking']['primary'],
String $os_name = $facts['os']['name'],
String $os_release = $facts['os']['release']['full'],
+ String $location = "${facts['country']}-${facts['region']}",
+ String $env = $facts['environment'],
) {
# Use the regsubst function to remove the 'roles::' prefix from the role name
diff --git a/site/profiles/manifests/base/repos.pp b/site/profiles/manifests/base/repos.pp
new file mode 100644
index 0000000..8d3223f
--- /dev/null
+++ b/site/profiles/manifests/base/repos.pp
@@ -0,0 +1,16 @@
+# profiles::base::repos
+class profiles::base::repos {
+ # manage package repositories
+ case $facts['os']['family'] {
+ 'RedHat': {
+ include profiles::yum::global
+ include profiles::firewall::firewalld
+ }
+ 'Debian': {
+ include profiles::apt::global
+ }
+ default: {
+ fail("Unsupported OS family ${facts['os']['family']}")
+ }
+ }
+}
diff --git a/site/profiles/manifests/base/root.pp b/site/profiles/manifests/base/root.pp
new file mode 100644
index 0000000..d53951e
--- /dev/null
+++ b/site/profiles/manifests/base/root.pp
@@ -0,0 +1,13 @@
+# manage the root user
+class profiles::base::root {
+
+ # TODO
+ # for now, add some root directories
+
+ file {'/root/.config':
+ ensure => directory,
+ owner => 'root',
+ group => 'root',
+ mode => '0600',
+ }
+}
diff --git a/site/profiles/manifests/cobbler/config.pp b/site/profiles/manifests/cobbler/config.pp
new file mode 100644
index 0000000..90aee5d
--- /dev/null
+++ b/site/profiles/manifests/cobbler/config.pp
@@ -0,0 +1,77 @@
+# profiles::cobbler::config
+class profiles::cobbler::config {
+
+ include profiles::cobbler::params
+
+ $default_password_crypted = $profiles::cobbler::params::default_password_crypted
+ $httpd_ssl_certificate = $profiles::cobbler::params::httpd_ssl_certificate
+ $httpd_ssl_privatekey = $profiles::cobbler::params::httpd_ssl_privatekey
+ $pxe_just_once = $profiles::cobbler::params::pxe_just_once
+ $is_cobbler_master = $profiles::cobbler::params::is_cobbler_master
+ $service_cname = $profiles::cobbler::params::service_cname
+ $next_server = $profiles::cobbler::params::next_server
+ $server = $profiles::cobbler::params::server
+
+ # manage the cobbler settings file
+ file { '/etc/cobbler/settings.yaml':
+ ensure => 'file',
+ content => template('profiles/cobbler/settings.yaml.erb'),
+ group => 'apache',
+ owner => 'root',
+ mode => '0640',
+ require => Package['cobbler'],
+ notify => Service['cobblerd'],
+ }
+
+ # manage the debmirror config to meet cobbler requirements
+ file { '/etc/debmirror.conf':
+ ensure => 'file',
+ content => template('profiles/cobbler/debmirror.conf.erb'),
+ group => 'root',
+ owner => 'root',
+ mode => '0644',
+ require => Package['debmirror'],
+ }
+
+ # manage the httpd ssl configuration
+ file { '/etc/httpd/conf.d/ssl.conf':
+ ensure => 'file',
+ content => template('profiles/cobbler/httpd_ssl.conf.erb'),
+ group => 'root',
+ owner => 'root',
+ mode => '0644',
+ require => Package['httpd'],
+ notify => Service['httpd'],
+ }
+
+ # fix permissions in /var/lib/cobbler/web.ss
+ file {'/var/lib/cobbler/web.ss':
+ ensure => 'file',
+ group => 'root',
+ owner => 'apache',
+ mode => '0660',
+ require => Package['cobbler'],
+ notify => Service['cobblerd'],
+ }
+
+ # manage the main ipxe menu script
+ file { '/var/lib/tftpboot/main.ipxe':
+ ensure => 'file',
+ content => template('profiles/cobbler/main.ipxe.erb'),
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ require => Package['cobbler'],
+ }
+
+ # export cnames for cobbler
+ if $is_cobbler_master {
+ profiles::dns::record { "${::facts['networking']['fqdn']}_${service_cname}_CNAME":
+ value => $::facts['networking']['hostname'],
+ type => 'CNAME',
+ record => "${service_cname}.",
+ zone => $::facts['networking']['domain'],
+ order => 10,
+ }
+ }
+}
diff --git a/site/profiles/manifests/cobbler/init.pp b/site/profiles/manifests/cobbler/init.pp
new file mode 100644
index 0000000..24b1555
--- /dev/null
+++ b/site/profiles/manifests/cobbler/init.pp
@@ -0,0 +1,17 @@
+# profiles::cobbler::init
+class profiles::cobbler::init (
+) {
+ # wait for enc_role to be populated, needed for hieradata to match
+ if $facts['enc_role'] == 'roles::infra::cobbler::server' {
+ include profiles::cobbler::config
+ include profiles::cobbler::install
+ include profiles::cobbler::ipxebins
+ include profiles::cobbler::selinux
+ include profiles::cobbler::service
+
+ Class['profiles::cobbler::install']
+ -> Class['profiles::cobbler::config']
+ -> Class['profiles::cobbler::ipxebins']
+ -> Class['profiles::cobbler::selinux']
+ }
+}
diff --git a/site/profiles/manifests/cobbler/install.pp b/site/profiles/manifests/cobbler/install.pp
new file mode 100644
index 0000000..f6bb8d6
--- /dev/null
+++ b/site/profiles/manifests/cobbler/install.pp
@@ -0,0 +1,34 @@
+# profiles::cobbler::install
+class profiles::cobbler::install {
+
+ include profiles::cobbler::params
+
+ $packages = $profiles::cobbler::params::packages
+
+ ensure_packages($packages, { ensure => 'present' })
+
+ # move the /var/www/cobbler directory to /data/cobbler
+ if ! $facts['cobbler_var_www_islink'] and ! $facts['cobbler_data_exists'] {
+ exec {'move_cobbler_data':
+ command => 'mv /var/www/cobbler /data/cobbler',
+ onlyif => 'test -d /var/www/cobbler',
+ path => ['/bin', '/usr/bin'],
+ before => Service['cobblerd'],
+ }
+ file { '/var/www/cobbler':
+ ensure => 'link',
+ target => '/data/cobbler',
+ require => Exec['move_cobbler_data'],
+ before => Service['httpd'],
+ notify => Service['httpd'],
+ }
+ }
+ if ! $facts['cobbler_var_www_exists'] and $facts['cobbler_data_exists'] {
+ file { '/var/www/cobbler':
+ ensure => 'link',
+ target => '/data/cobbler',
+ before => Service['httpd'],
+ notify => Service['httpd'],
+ }
+ }
+}
diff --git a/site/profiles/manifests/cobbler/ipxebins.pp b/site/profiles/manifests/cobbler/ipxebins.pp
new file mode 100644
index 0000000..1fc0bf9
--- /dev/null
+++ b/site/profiles/manifests/cobbler/ipxebins.pp
@@ -0,0 +1,48 @@
+# profiles::cobbler::ipxebins
+class profiles::cobbler::ipxebins {
+
+ include profiles::cobbler::params
+
+ # download the custom undionly.kpxe file
+ # https://gist.github.com/rikka0w0/50895b82cbec8a3a1e8c7707479824c1
+ exec { 'download_undionly_kpxe':
+ command => 'wget -O /var/lib/tftpboot/undionly.kpxe http://repos.main.unkin.net/unkin/8/x86_64/os/Archives/undionly.kpxe',
+ path => ['/bin', '/usr/bin'],
+ creates => '/var/lib/tftpboot/undionly.kpxe',
+ }
+
+ # set correct permissions ipxe boot image to tftpboot
+ file { '/var/lib/tftpboot/undionly.kpxe':
+ ensure => 'file',
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ require => [
+ Package['ipxe-bootimgs'],
+ Package['cobbler'],
+ Exec['download_undionly_kpxe']
+ ],
+ }
+
+ # download the custom ipxe.efi file
+ # https://gist.github.com/rikka0w0/50895b82cbec8a3a1e8c7707479824c1
+ exec { 'download_ipxe_efi':
+ command => 'wget -O /var/lib/tftpboot/ipxe.efi http://repos.main.unkin.net/unkin/8/x86_64/os/Archives/ipxe.efi',
+ path => ['/bin', '/usr/bin'],
+ creates => '/var/lib/tftpboot/ipxe.efi',
+ }
+
+ # set correct permissions ipxe boot image to tftpboot
+ file { '/var/lib/tftpboot/ipxe.efi':
+ ensure => 'file',
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ require => [
+ Package['ipxe-bootimgs'],
+ Package['cobbler'],
+ Exec['download_ipxe_efi']
+ ],
+ }
+}
+
diff --git a/site/profiles/manifests/cobbler/params.pp b/site/profiles/manifests/cobbler/params.pp
new file mode 100644
index 0000000..877f986
--- /dev/null
+++ b/site/profiles/manifests/cobbler/params.pp
@@ -0,0 +1,25 @@
+# profiles::cobbler::params
+class profiles::cobbler::params (
+ Stdlib::Absolutepath $httpd_ssl_certificate = '/etc/pki/tls/vault/certificate.crt',
+ Stdlib::Absolutepath $httpd_ssl_privatekey = '/etc/pki/tls/vault/private.key',
+ Stdlib::Absolutepath $tftpboot_path = '/var/lib/tftpboot/boot',
+ Stdlib::Fqdn $service_cname = $facts['networking']['fqdn'],
+ String $default_password_crypted = 'changeme',
+ String $server = $::facts['networking']['ip'],
+ String $next_server = $::facts['networking']['ip'],
+ Boolean $pxe_just_once = true,
+ Boolean $is_cobbler_master = false,
+ Array $packages = [
+ 'cobbler',
+ 'cobbler3.2-web',
+ 'httpd',
+ 'syslinux',
+ 'dnf-plugins-core',
+ 'debmirror',
+ 'pykickstart',
+ 'fence-agents',
+ 'selinux-policy-devel',
+ 'ipxe-bootimgs',
+ ]
+){
+}
diff --git a/site/profiles/manifests/cobbler/selinux.pp b/site/profiles/manifests/cobbler/selinux.pp
new file mode 100644
index 0000000..df8dab5
--- /dev/null
+++ b/site/profiles/manifests/cobbler/selinux.pp
@@ -0,0 +1,48 @@
+# profiles::cobbler::selinux
+class profiles::cobbler::selinux inherits profiles::cobbler::params {
+
+ include profiles::cobbler::params
+
+ $tftpboot_path = $profiles::cobbler::params::tftpboot_path
+
+ # manage selinux requirements for cobbler
+ if $::facts['os']['selinux']['config_mode'] == 'enforcing' {
+
+ $enable_sebooleans = [
+ 'httpd_can_network_connect_cobbler',
+ 'httpd_serve_cobbler_files',
+ 'cobbler_can_network_connect'
+ ]
+
+ $enable_sebooleans.each |$bool| {
+ selboolean { $bool:
+ value => on,
+ persistent => true,
+ }
+ }
+
+ selinux::fcontext { $tftpboot_path:
+ ensure => 'present',
+ seltype => 'cobbler_var_lib_t',
+ pathspec => "${tftpboot_path}(/.*)?",
+ }
+ selinux::fcontext { '/data/cobbler':
+ ensure => 'present',
+ seltype => 'cobbler_var_lib_t',
+ pathspec => '/data/cobbler(/.*)?',
+ }
+
+ exec { "restorecon_${tftpboot_path}":
+ path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'],
+ command => "restorecon -Rv ${tftpboot_path}",
+ refreshonly => true,
+ subscribe => Selinux::Fcontext[$tftpboot_path],
+ }
+ exec { 'restorecon_/data/cobbler':
+ path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'],
+ command => 'restorecon -Rv /data/cobbler',
+ refreshonly => true,
+ subscribe => Selinux::Fcontext['/data/cobbler'],
+ }
+ }
+}
diff --git a/site/profiles/manifests/cobbler/service.pp b/site/profiles/manifests/cobbler/service.pp
new file mode 100644
index 0000000..63b2645
--- /dev/null
+++ b/site/profiles/manifests/cobbler/service.pp
@@ -0,0 +1,17 @@
+# profiles::cobbler::service
+class profiles::cobbler::service inherits profiles::cobbler::params {
+
+ # ensure cobblerd is running
+ service {'cobblerd':
+ ensure => 'running',
+ enable => true,
+ require => File['/etc/cobbler/settings.yaml'],
+ }
+
+ # ensure httpd is running
+ service {'httpd':
+ ensure => 'running',
+ enable => true,
+ require => File['/etc/httpd/conf.d/ssl.conf'],
+ }
+}
diff --git a/site/profiles/manifests/consul/client.pp b/site/profiles/manifests/consul/client.pp
new file mode 100644
index 0000000..4524b87
--- /dev/null
+++ b/site/profiles/manifests/consul/client.pp
@@ -0,0 +1,87 @@
+# profiles::consul::client
+class profiles::consul::client (
+ String $secret_id_salt = '',
+ Stdlib::Fqdn $consul_hostname = 'consul.service.consul',
+ Enum['http','https'] $consul_protocol = 'http',
+ Stdlib::Port $consul_port = 8500,
+ String $consul_api_token = lookup('profiles::consul::server::acl_tokens_initial_management'),
+ Boolean $members_lookup = false,
+ String $members_role = undef,
+ Array $consul_servers = [],
+ Stdlib::Absolutepath $data_dir = '/opt/consul',
+ Array[Hash] $node_rules = [],
+) {
+
+ if $facts['enc_role'] != $members_role {
+
+ # set a datacentre/cluster name
+ $consul_cluster = "${::facts['country']}-${::facts['region']}"
+
+ # if lookup is enabled, find all the hosts in the specified role and create the servers_array
+ if $members_lookup {
+
+ # check that the role is also set
+ unless !($members_role == undef) {
+ fail("members_role must be provided for ${title} when members_lookup is True")
+ }
+
+ # if it is, find hosts, sort them so they dont cause changes every run
+ $servers_array = sort(query_nodes("enc_role='${members_role}' and region='${::facts['region']}'", 'networking.fqdn'))
+
+ # else use provided array from params
+ }else{
+ $servers_array = $consul_servers
+ }
+
+ # deploy the consul agent
+ class { 'consul':
+ config_hash => {
+ 'data_dir' => $data_dir,
+ 'datacenter' => $consul_cluster,
+ 'log_level' => 'INFO',
+ 'node_name' => $facts['networking']['fqdn'],
+ 'retry_join' => $servers_array,
+ 'bind_addr' => $::facts['networking']['ip'],
+ 'advertise_addr' => $::facts['networking']['ip'],
+ 'acl' => {
+ tokens => {
+ default => fqdn_uuid("${facts['networking']['fqdn']}-${secret_id_salt}")
+ }
+ }
+ },
+ }
+ }
+
+ # Create ACL policy that allows nodes to update themselves and read others
+ consul_policy { $facts['networking']['hostname']:
+ description => "${facts['networking']['fqdn']} puppet-generated-policy",
+ rules => $node_rules,
+ acl_api_token => $consul_api_token,
+ hostname => $consul_hostname,
+ protocol => $consul_protocol,
+ port => $consul_port,
+ }
+
+ consul_token { $facts['networking']['hostname']:
+ accessor_id => fqdn_uuid($facts['networking']['fqdn']),
+ description => "${facts['networking']['fqdn']} puppet-generated-token",
+ policies_by_name => [$facts['networking']['hostname']],
+ acl_api_token => $consul_api_token,
+ secret_id => fqdn_uuid("${facts['networking']['fqdn']}-${secret_id_salt}"),
+ hostname => $consul_hostname,
+ protocol => $consul_protocol,
+ port => $consul_port,
+
+ }
+
+ # ensure the consul token is saved for the root user
+ file {'/root/.config/consul_node_token':
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0600',
+ content => Sensitive(fqdn_uuid("${facts['networking']['fqdn']}-${secret_id_salt}")),
+ require => File['/root/.config'],
+ }
+
+}
diff --git a/site/profiles/manifests/consul/policies.pp b/site/profiles/manifests/consul/policies.pp
new file mode 100644
index 0000000..df1bf2a
--- /dev/null
+++ b/site/profiles/manifests/consul/policies.pp
@@ -0,0 +1,23 @@
+# profiles::consul::policies
+class profiles::consul::policies (
+ String $root_api_token = lookup('profiles::consul::server::acl_tokens_initial_management'),
+) {
+
+ consul_policy { 'node_editor':
+ description => 'Policy to read/write all nodes puppet-generated-policy',
+ rules => [
+ {
+ 'resource' => 'node',
+ 'segment' => '',
+ 'disposition' => 'write'
+ },
+ {
+ 'resource' => 'node',
+ 'segment' => '',
+ 'disposition' => 'read'
+ }
+ ],
+ acl_api_token => $root_api_token,
+ hostname => $facts['networking']['ip'],
+ }
+}
diff --git a/site/profiles/manifests/consul/prepared_query.pp b/site/profiles/manifests/consul/prepared_query.pp
new file mode 100644
index 0000000..16df79f
--- /dev/null
+++ b/site/profiles/manifests/consul/prepared_query.pp
@@ -0,0 +1,14 @@
+# profile::consul::prepared_query
+class profiles::consul::prepared_query (
+ String $root_api_token = lookup('profiles::consul::server::acl_tokens_initial_management'),
+ Hash $rules = {},
+) {
+
+ $rules.each | $rule, $data | {
+ consul_prepared_query { $rule:
+ acl_api_token => $root_api_token,
+ hostname => $facts['networking']['ip'],
+ * => $data,
+ }
+ }
+}
diff --git a/site/profiles/manifests/consul/server.pp b/site/profiles/manifests/consul/server.pp
new file mode 100644
index 0000000..f71c567
--- /dev/null
+++ b/site/profiles/manifests/consul/server.pp
@@ -0,0 +1,158 @@
+# profiles::consul::server
+class profiles::consul::server (
+ Variant[
+ Undef,
+ String
+ ] $gossip_key = undef,
+ Variant[
+ Undef,
+ String
+ ] $primary_datacenter = undef,
+ Hash $acl = {},
+ Hash $ports = {},
+ Hash $addresses = {},
+ Boolean $members_lookup = false,
+ String $members_role = undef,
+ Array $consul_servers = [],
+ Boolean $enable_ui = true,
+ Boolean $enable_ui_config = true,
+ Boolean $manage_repo = false,
+ String $package_ensure = 'latest',
+ String $package_name = 'consul',
+ Integer $bootstrap_count = 1,
+ String $domain = 'consul',
+ Integer $raft_multiplier = 1,
+ Enum[
+ 'allow',
+ 'deny',
+ 'extend-cache',
+ 'async-cache'
+ ] $acl_down_policy = 'extend-cache',
+ Enum[
+ 'allow',
+ 'deny'
+ ] $acl_default_policy = 'deny',
+ Enum[
+ 'url',
+ 'package',
+ 'docker',
+ 'none'
+ ] $install_method = 'package',
+ Stdlib::IP::Address $client_addr = '0.0.0.0',
+ Stdlib::Absolutepath $data_dir = '/opt/consul',
+ Stdlib::Absolutepath $bin_dir = '/usr/bin',
+ Boolean $disable_remote_exec = true,
+ Boolean $disable_update_check = true,
+ Boolean $join_remote_regions = false,
+ Array[String] $remote_regions = [],
+) {
+
+ # wait for all attributes to be ready
+ if $facts['enc_role'] == $members_role {
+
+ # set a datacentre/cluster name
+ $consul_cluster = "${::facts['country']}-${::facts['region']}"
+
+ # if lookup is enabled, find all the hosts in the specified role and create the servers_array
+ if $members_lookup {
+
+ # check that the role is also set
+ unless !($members_role == undef) {
+ fail("members_role must be provided for ${title} when members_lookup is True")
+ }
+
+ # if it is, find hosts, sort them so they dont cause changes every run
+ $servers_array = sort(query_nodes("enc_role='${members_role}' and region='${::facts['region']}'", 'networking.fqdn'))
+
+ if $join_remote_regions {
+ # get all nodes in the members_role for each other region
+ $region_to_servers = $remote_regions.reduce({}) |$memo, $region| {
+ $servers = sort(query_nodes("enc_role='${members_role}' and region='${region}'", 'networking.fqdn'))
+ $memo + { $region => $servers }
+ }
+
+ # sort and flatten the regions into a single array of fqdns
+ $remote_servers_array = sort(flatten($region_to_servers.values))
+
+ } else {
+ # else just send an empty array
+ $remote_servers_array = []
+ }
+
+ # else use provided array from params
+ }else{
+ $servers_array = $consul_servers
+ }
+
+ # if $data_dir starts with /data, ensure the data mount exists
+ if ($data_dir.stdlib::start_with('/data') and $::facts['mountpoints']['/data']) or ! $data_dir.stdlib::start_with('/data') {
+
+ # install consul
+ class { 'consul':
+ install_method => $install_method,
+ manage_repo => $manage_repo,
+ package_name => $package_name,
+ package_ensure => $package_ensure,
+ bin_dir => $bin_dir,
+ config_hash => {
+ 'primary_datacenter' => $primary_datacenter,
+ 'acl' => $acl,
+ 'ports' => $ports,
+ 'addresses' => $addresses,
+ 'disable_remote_exec' => $disable_remote_exec,
+ 'disable_update_check' => $disable_update_check,
+ 'domain' => $domain,
+ 'bootstrap_expect' => $bootstrap_count,
+ 'client_addr' => '0.0.0.0',
+ 'data_dir' => $data_dir,
+ 'datacenter' => $consul_cluster,
+ 'log_level' => 'INFO',
+ 'node_name' => $::facts['networking']['fqdn'],
+ 'server' => true,
+ 'ui' => $enable_ui,
+ 'ui_config' => { 'enabled' => $enable_ui_config },
+ 'performance' => { 'raft_multiplier' => $raft_multiplier },
+ 'bind_addr' => $::facts['networking']['ip'],
+ 'advertise_addr' => $::facts['networking']['ip'],
+ 'retry_join' => $servers_array,
+ 'retry_join_wan' => $remote_servers_array,
+ },
+ }
+ }
+ }
+ # consul before extra services
+ if defined(Class['consul']) {
+
+ # include nginx, policies and tokens
+ include profiles::nginx::simpleproxy
+ include profiles::consul::policies
+ include profiles::consul::tokens
+ include profiles::consul::prepared_query
+
+ # get the dns port from the $ports hash, otherwise use the default
+ $dns_port = pick($ports['dns'], 8600)
+
+ # install dnsmasq
+ package { 'dnsmasq':
+ ensure => installed,
+ }
+
+ # create the 10-consul.conf file
+ file { '/etc/dnsmasq.d/10-consul.conf':
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ content => "server=/${domain}/${::facts['networking']['ip']}#${dns_port}\n",
+ require => Package['dnsmasq'],
+ notify => Service['dnsmasq'],
+ }
+
+ # ensure dnsmasq service is running and enabled at boot
+ service { 'dnsmasq':
+ ensure => running,
+ enable => true,
+ subscribe => File['/etc/dnsmasq.d/10-consul.conf'], # Restart dnsmasq if the consul config changes
+ }
+ }
+}
diff --git a/site/profiles/manifests/consul/tokens.pp b/site/profiles/manifests/consul/tokens.pp
new file mode 100644
index 0000000..c471783
--- /dev/null
+++ b/site/profiles/manifests/consul/tokens.pp
@@ -0,0 +1,13 @@
+# profiles::consul::tokens
+class profiles::consul::tokens (
+ String $root_api_token = lookup('profiles::consul::server::acl_tokens_initial_management'),
+){
+
+ consul_token { 'node_editor':
+ accessor_id => lookup('profiles::consul::token::node_editor::accessor_id'),
+ policies_by_name => ['node_editor'],
+ acl_api_token => $root_api_token,
+ secret_id => lookup('profiles::consul::token::node_editor::secret_id'),
+ hostname => $facts['networking']['ip'],
+ }
+}
diff --git a/site/profiles/manifests/defaults.pp b/site/profiles/manifests/defaults.pp
index 5c72fb6..c0b94a8 100644
--- a/site/profiles/manifests/defaults.pp
+++ b/site/profiles/manifests/defaults.pp
@@ -8,7 +8,9 @@ class profiles::defaults {
}
Package {
- ensure => present,
+ ensure => present,
+ require => Class['profiles::base::repos']
+
}
File {
@@ -27,4 +29,13 @@ class profiles::defaults {
ensure => present,
shell => '/bin/bash',
}
+
+ Yumrepo {
+ ensure => 'present',
+ enabled => 1,
+ gpgcheck => 1,
+ mirrorlist => 'absent',
+ require => Class['profiles::pki::vaultca'],
+ notify => Exec['dnf_makecache'],
+ }
}
diff --git a/site/profiles/manifests/dhcp/server.pp b/site/profiles/manifests/dhcp/server.pp
new file mode 100644
index 0000000..726ff19
--- /dev/null
+++ b/site/profiles/manifests/dhcp/server.pp
@@ -0,0 +1,39 @@
+# profiles::dhcp::server
+class profiles::dhcp::server (
+ Array[Stdlib::Host] $ntpservers = [
+ '0.au.pool.ntp.org',
+ '1.au.pool.ntp.org',
+ '2.au.pool.ntp.org',
+ '3.au.pool.ntp.org'
+ ],
+ Array[String] $interfaces = ['eth0'],
+ Integer $default_lease_time = 86400,
+ Array[String] $globaloptions = [],
+ Hash $pools = {},
+ Hash $classes = {},
+){
+
+ if $facts['enc_role'] == 'roles::infra::dhcp::server' {
+ class { 'dhcp':
+ service_ensure => running,
+ interfaces => $interfaces,
+ ntpservers => $ntpservers,
+ default_lease_time => $default_lease_time,
+ globaloptions => $globaloptions
+ }
+
+ # if pools, import them
+ $pools.each | $name, $data | {
+ dhcp::pool { $name:
+ * => $data,
+ }
+ }
+
+ # if classes, import them
+ $classes.each | $name, $data | {
+ dhcp::dhcp_class { $name:
+ * => $data,
+ }
+ }
+ }
+}
diff --git a/site/profiles/manifests/dns/base.pp b/site/profiles/manifests/dns/base.pp
index 6510453..e22e964 100644
--- a/site/profiles/manifests/dns/base.pp
+++ b/site/profiles/manifests/dns/base.pp
@@ -3,13 +3,24 @@ class profiles::dns::base (
String $ns_role = undef,
Array $search = [],
Array $nameservers = ['8.8.8.8', '1.1.1.1'],
+ Enum[
+ 'all',
+ 'region',
+ 'country'
+ ] $use_ns = 'all',
){
+ # install bind_utils
+ include bind::updater
+
# if ns_role is set, find all hosts matching that enc_role
- if $ns_role == undef {
- $nameserver_array = $nameservers
- }else{
- $nameserver_array = query_nodes("enc_role='${ns_role}'", 'networking.ip')
+ $nameserver_array = $ns_role ? {
+ undef => $nameservers,
+ default => $use_ns ? {
+ 'all' => query_nodes("enc_role='${ns_role}'", 'networking.ip'),
+ 'region' => query_nodes("enc_role='${ns_role}' and region=${facts['region']}", 'networking.ip'),
+ 'country' => query_nodes("enc_role='${ns_role}' and country=${facts['country']}", 'networking.ip'),
+ }
}
# if search is undef, fallback to domainname from facts
@@ -21,8 +32,8 @@ class profiles::dns::base (
# include resolvconf class
class { 'profiles::dns::resolvconf':
- nameservers => $nameserver_array,
- search_domains => $search_array,
+ nameservers => sort($nameserver_array),
+ search_domains => sort($search_array),
}
# export dns records for client
diff --git a/site/profiles/manifests/dns/master.pp b/site/profiles/manifests/dns/master.pp
index a66b665..440325e 100644
--- a/site/profiles/manifests/dns/master.pp
+++ b/site/profiles/manifests/dns/master.pp
@@ -1,6 +1,5 @@
# profiles::dns::master authoritative service
class profiles::dns::master (
- Array[String] $nameservers,
Stdlib::AbsolutePath $basedir,
Hash $acls = {},
Hash $zones = {},
@@ -13,8 +12,27 @@ class profiles::dns::master (
String $owner = 'root',
String $group = 'named',
Boolean $dnssec = false,
+ Variant[String, Undef] $ns_role = undef,
+ Enum['all', 'region', 'country'] $use_ns = 'all',
){
+ # if ns_role is set, find all hosts matching that enc_role, otherwise use the current host
+ $nameservers_array = $ns_role ? {
+ undef => [$facts['networking']['fqdn']],
+ default => $use_ns ? {
+ 'all' => query_nodes("enc_role='${ns_role}'", 'networking.fqdn'),
+ 'region' => query_nodes("enc_role='${ns_role}' and region=${facts['region']}", 'networking.fqdn'),
+ 'country' => query_nodes("enc_role='${ns_role}' and country=${facts['country']}", 'networking.fqdn'),
+ }
+ }
+
+ # if nameservers is empty, use the current host, otherwise use nameservers_array as nameservers
+ $nameservers = empty($nameservers_array) ? {
+ true => [$facts['networking']['fqdn']],
+ false => $nameservers_array,
+ default => [$facts['networking']['fqdn']],
+ }
+
class {'profiles::dns::server':
acls => $acls,
zones => $zones,
@@ -37,7 +55,7 @@ class profiles::dns::master (
profiles::dns::zone { $name:
zone => $data['domain'],
basedir => $basedir,
- nameservers => $nameservers,
+ nameservers => sort($nameservers),
owner => $owner,
group => $group,
before => Bind::Zone[$name]
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..30e2c69
--- /dev/null
+++ b/site/profiles/manifests/edgecache/nginx.pp
@@ -0,0 +1,129 @@
+# 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
+ $nginx_resolvers_enable = $profiles::edgecache::params::nginx_resolvers_enable
+ $nginx_resolvers_ipv4only = $profiles::edgecache::params::nginx_resolvers_ipv4only
+
+ # 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
+ }
+ }
+
+ if $nginx_resolvers_ipv4only and $nginx_resolvers_enable {
+ $resolvers = $facts['nameservers'].join(' ')
+ file { '/etc/nginx/conf.d/resolvers.conf':
+ ensure => file,
+ content => "resolver ${resolvers} ipv4=on;\n",
+ }
+ }
+
+ # 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..0766ea7
--- /dev/null
+++ b/site/profiles/manifests/edgecache/params.pp
@@ -0,0 +1,15 @@
+# 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',
+ Boolean $nginx_resolvers_enable = false,
+ Boolean $nginx_resolvers_ipv4only = false,
+ 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/profiles/manifests/firstrun/complete.pp b/site/profiles/manifests/firstrun/complete.pp
new file mode 100644
index 0000000..b79eaf2
--- /dev/null
+++ b/site/profiles/manifests/firstrun/complete.pp
@@ -0,0 +1,19 @@
+# profiles::firstrun::complete
+class profiles::firstrun::complete {
+
+ file { '/root/.cache':
+ ensure => 'directory',
+ owner => 'root',
+ group => 'root',
+ mode => '0750',
+ }
+
+ file {'/root/.cache/puppet_firstrun_complete':
+ ensure => 'file',
+ owner => 'root',
+ group => 'root',
+ mode => '0750',
+ content => 'firstrun completed',
+ require => File['/root/.cache'],
+ }
+}
diff --git a/site/profiles/manifests/firstrun/init.pp b/site/profiles/manifests/firstrun/init.pp
new file mode 100644
index 0000000..c4845e1
--- /dev/null
+++ b/site/profiles/manifests/firstrun/init.pp
@@ -0,0 +1,20 @@
+# profiles::firstrun::init
+class profiles::firstrun::init {
+
+ # include the required CA certificates
+ include profiles::pki::vaultca
+
+ # fast install packages on the first run
+ include profiles::base::repos
+ include profiles::firstrun::packages
+
+ # mark the firstrun as done
+ include profiles::firstrun::complete
+
+
+ Class['profiles::defaults']
+ -> Class['profiles::pki::vaultca']
+ -> Class['profiles::base::repos']
+ -> Class['profiles::firstrun::packages']
+ -> Class['profiles::firstrun::complete']
+}
diff --git a/site/profiles/manifests/firstrun/packages.pp b/site/profiles/manifests/firstrun/packages.pp
new file mode 100644
index 0000000..5bcc6d4
--- /dev/null
+++ b/site/profiles/manifests/firstrun/packages.pp
@@ -0,0 +1,27 @@
+# profiles::firstrun::packages
+class profiles::firstrun::packages {
+ # include the correct package repositories, define the install_packages exec
+ case $facts['os']['family'] {
+ 'RedHat': {
+ include profiles::yum::global
+ $install_command = 'dnf install -y'
+ }
+ 'Debian': {
+ include profiles::apt::global
+ $install_command = 'apt-get install -y'
+ }
+ default: {
+ fail("Unsupported OS family ${facts['os']['family']}")
+ }
+ }
+
+ # get all the packages to install, and convert into a space separated list
+ $packages = hiera_array('profiles::packages::install', [])
+ $package_list = $packages.join(' ')
+
+ # install all the packages
+ exec { 'install_packages':
+ command => "${install_command} ${package_list}",
+ path => ['/bin', '/usr/bin'],
+ }
+}
diff --git a/site/profiles/manifests/gitea/init.pp b/site/profiles/manifests/gitea/init.pp
new file mode 100644
index 0000000..90e9e47
--- /dev/null
+++ b/site/profiles/manifests/gitea/init.pp
@@ -0,0 +1,55 @@
+# profiles::gitea::init
+class profiles::gitea::init (
+ String $mysql_pass = '',
+ String $lfs_jwt_secret = '',
+) {
+
+ include profiles::nginx::simpleproxy
+
+ class { 'gitea':
+ ensure => '1.22.0',
+ checksum => 'a31086f073cb9592d28611394b2de3655db515d961e4fdcf5b549cb40753ef3d',
+ custom_configuration => {
+ '' => {
+ 'APP_NAME' => 'Gitea',
+ 'RUN_USER' => 'git',
+ 'RUN_MODE' => 'prod',
+ },
+ 'repository' => {
+ 'ROOT' => '/data/gitea/repos',
+ 'FORCE_PRIVATE' => false,
+ 'MAX_CREATION_LIMIT' => -1,
+ 'DISABLE_HTTP_GIT' => false,
+ 'DEFAULT_BRANCH' => 'main',
+ 'DEFAULT_PRIVATE' => 'last',
+ },
+ 'ui' => {
+ 'SHOW_USER_EMAIL' => false,
+ },
+ 'server' => {
+ 'PROTOCOL' => 'http',
+ 'DOMAIN' => 'git.query.consul',
+ 'ROOT_URL' => 'https://git.query.consul',
+ 'HTTP_ADDR' => '0.0.0.0',
+ 'HTTP_PORT' => 3000,
+ 'START_SSH_SERVER' => false,
+ 'SSH_DOMAIN' => 'git.query.consul',
+ 'SSH_PORT' => 2222,
+ 'SSH_LISTEN_HOST' => '0.0.0.0',
+ 'OFFLINE_MODE' => true,
+ 'APP_DATA_PATH' => '/var/lib/gitea/data',
+ 'SSH_LISTEN_PORT' => 22,
+ },
+ 'database' => {
+ 'DB_TYPE' => 'mysql',
+ 'HOST' => 'mariadb-prod.service.au-syd1.consul:3306',
+ 'NAME' => 'gitea',
+ 'USER' => 'gitea',
+ 'PASSWD' => Sensitive($mysql_pass),
+ 'SSL_MODE' => 'disable',
+ 'PATH' => '/var/lib/gitea/data/gitea.db',
+ 'LOG_SQL' => false,
+ },
+ }
+ }
+}
diff --git a/site/profiles/manifests/haproxy/backends.pp b/site/profiles/manifests/haproxy/backends.pp
new file mode 100644
index 0000000..a8d1294
--- /dev/null
+++ b/site/profiles/manifests/haproxy/backends.pp
@@ -0,0 +1,19 @@
+# profiles::haproxy::backends
+class profiles::haproxy::backends {
+ # set location_environment
+ $location_environment = "${facts['country']}-${facts['region']}-${facts['environment']}"
+
+ # for each backend:
+ $backends = lookup('profiles::haproxy::backends', Hash, 'deep', {})
+ $backends.each |$backend, $data| {
+
+ # create backend
+ haproxy::backend { $backend:
+ * => $data,
+ }
+
+ # collect exported resources
+ $tag = "${backend}_${location_environment}"
+ Haproxy::Balancermember <<| tag == $tag |>>
+ }
+}
diff --git a/site/profiles/manifests/haproxy/balancemember.pp b/site/profiles/manifests/haproxy/balancemember.pp
new file mode 100644
index 0000000..a477a91
--- /dev/null
+++ b/site/profiles/manifests/haproxy/balancemember.pp
@@ -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 { $title:
+ listening_service => $service,
+ ports => $ports,
+ server_names => $facts['networking']['hostname'],
+ ipaddresses => $facts['networking']['ip'],
+ options => $options,
+ tag => $balancemember_tag,
+ }
+}
diff --git a/site/profiles/manifests/haproxy/certlist.pp b/site/profiles/manifests/haproxy/certlist.pp
new file mode 100644
index 0000000..301bd8c
--- /dev/null
+++ b/site/profiles/manifests/haproxy/certlist.pp
@@ -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')
+ }
+ }
+
+}
diff --git a/site/profiles/manifests/haproxy/dns.pp b/site/profiles/manifests/haproxy/dns.pp
new file mode 100644
index 0000000..af0e8ac
--- /dev/null
+++ b/site/profiles/manifests/haproxy/dns.pp
@@ -0,0 +1,27 @@
+# profiles::haproxy::dns
+class profiles::haproxy::dns (
+ Array[Stdlib::Fqdn] $cnames = [],
+ Integer $order = 10,
+){
+
+ # create an A record for each load balancer in a region
+ $location_environment = "${facts['country']}-${facts['region']}-${facts['environment']}"
+ profiles::dns::record { "${facts['networking']['fqdn']}_${location_environment}-halb_A":
+ value => $::facts['networking']['ip'],
+ type => 'A',
+ record => "${location_environment}-halb",
+ zone => $::facts['networking']['domain'],
+ order => $order,
+ }
+
+ # export cnames for haproxy applications
+ $cnames.each |$cname| {
+ profiles::dns::record { "${::facts['networking']['fqdn']}_${cname}_CNAME":
+ value => "${location_environment}-halb",
+ type => 'CNAME',
+ record => "${cname}.",
+ zone => $::facts['networking']['domain'],
+ order => $order,
+ }
+ }
+}
diff --git a/site/profiles/manifests/haproxy/frontends.pp b/site/profiles/manifests/haproxy/frontends.pp
new file mode 100644
index 0000000..10721db
--- /dev/null
+++ b/site/profiles/manifests/haproxy/frontends.pp
@@ -0,0 +1,14 @@
+# profiles::haproxy::frontends
+class profiles::haproxy::frontends {
+
+ # for each frontend:
+ $frontends = lookup('profiles::haproxy::frontends', Hash, 'deep', {})
+ $frontends.each |$frontend, $data| {
+
+ # create frontends
+ haproxy::frontend { $frontend:
+ * => $data,
+ }
+
+ }
+}
diff --git a/site/profiles/manifests/haproxy/listeners.pp b/site/profiles/manifests/haproxy/listeners.pp
new file mode 100644
index 0000000..3fbe07e
--- /dev/null
+++ b/site/profiles/manifests/haproxy/listeners.pp
@@ -0,0 +1,19 @@
+# profiles::haproxy::listeners
+class profiles::haproxy::listeners {
+ # set location_environment
+ $location_environment = "${facts['country']}-${facts['region']}-${facts['environment']}"
+
+ # for each listener:
+ $listeners = lookup('profiles::haproxy::listeners', Hash, 'deep', {})
+ $listeners.each |$listen, $data| {
+
+ # create listener
+ haproxy::listen { $listen:
+ * => $data,
+ }
+
+ # collect exported resources
+ $tag = "${listen}_${location_environment}"
+ Haproxy::Balancermember <<| tag == $tag |>>
+ }
+}
diff --git a/site/profiles/manifests/haproxy/ls_stats.pp b/site/profiles/manifests/haproxy/ls_stats.pp
new file mode 100644
index 0000000..7c8bc9d
--- /dev/null
+++ b/site/profiles/manifests/haproxy/ls_stats.pp
@@ -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}",
+ ],
+ },
+ }
+}
diff --git a/site/profiles/manifests/haproxy/mappings.pp b/site/profiles/manifests/haproxy/mappings.pp
new file mode 100644
index 0000000..df844df
--- /dev/null
+++ b/site/profiles/manifests/haproxy/mappings.pp
@@ -0,0 +1,13 @@
+# profiles::haproxy::mappings
+class profiles::haproxy::mappings {
+
+ # for each mapping:
+ $mappings = lookup('profiles::haproxy::mappings')
+ $mappings.each |$mapping, $data| {
+
+ # create mapping
+ haproxy::mapfile { $mapping:
+ * => $data,
+ }
+ }
+}
diff --git a/site/profiles/manifests/haproxy/selinux.pp b/site/profiles/manifests/haproxy/selinux.pp
new file mode 100644
index 0000000..a5b7271
--- /dev/null
+++ b/site/profiles/manifests/haproxy/selinux.pp
@@ -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,
+ }
+ }
+ }
+}
+
diff --git a/site/profiles/manifests/haproxy/server.pp b/site/profiles/manifests/haproxy/server.pp
new file mode 100644
index 0000000..3ac313e
--- /dev/null
+++ b/site/profiles/manifests/haproxy/server.pp
@@ -0,0 +1,63 @@
+# 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)
+
+ # wait until enc_role matches haproxy enc_role
+ if $facts['enc_role'] == 'roles::infra::halb::haproxy' {
+
+ # 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::dns # manage dns for haproxy
+ include profiles::haproxy::frontends # create frontends
+ include profiles::haproxy::backends # create backends
+ include profiles::haproxy::listeners # create listeners
+
+ Class['profiles::haproxy::certlist']
+ -> Class['profiles::haproxy::dns']
+ -> Class['profiles::haproxy::mappings']
+ }
+}
diff --git a/site/profiles/manifests/helpers/certmanager.pp b/site/profiles/manifests/helpers/certmanager.pp
new file mode 100644
index 0000000..41d1730
--- /dev/null
+++ b/site/profiles/manifests/helpers/certmanager.pp
@@ -0,0 +1,77 @@
+# profiles::helpers::certmanager
+#
+# wrapper class for python, pip and venv
+class profiles::helpers::certmanager (
+ String $script_name = 'certmanager',
+ Stdlib::AbsolutePath $base_path = "/opt/${script_name}",
+ Stdlib::AbsolutePath $venv_path = "${base_path}/venv",
+ Stdlib::AbsolutePath $config_path = "${base_path}/config.yaml",
+ Hash $vault_config = {},
+ String $owner = 'root',
+ String $group = 'root',
+ Boolean $systempkgs = false,
+ String $version = 'system',
+ Array[String[1]] $packages = ['requests', 'pyyaml'],
+){
+
+ if $::facts['python3_version'] {
+
+ $python_version = $version ? {
+ 'system' => $::facts['python3_version'],
+ default => $version,
+ }
+
+ # ensure the base_path exists
+ file { $base_path:
+ ensure => directory,
+ mode => '0755',
+ owner => $owner,
+ group => $group,
+ }
+
+ # create a venv
+ python::pyvenv { $venv_path :
+ ensure => present,
+ version => $python_version,
+ systempkgs => $systempkgs,
+ venv_dir => $venv_path,
+ owner => $owner,
+ group => $group,
+ require => File[$base_path],
+ }
+
+ # install the required pip packages
+ $packages.each |String $package| {
+ python::pip { "${venv_path}_${package}":
+ ensure => present,
+ pkgname => $package,
+ virtualenv => $venv_path,
+ }
+ }
+
+ # create the script from a template
+ file { "${base_path}/${script_name}":
+ ensure => file,
+ mode => '0755',
+ content => template("profiles/helpers/${script_name}.erb"),
+ require => Python::Pyvenv[$venv_path],
+ }
+
+ # create the config from a template
+ file { $config_path:
+ ensure => file,
+ mode => '0660',
+ owner => 'puppet',
+ group => 'root',
+ content => Sensitive(template("profiles/helpers/${script_name}_config.yaml.erb")),
+ require => Python::Pyvenv[$venv_path],
+ }
+
+ # create symbolic link in $PATH
+ file { "/usr/local/bin/${script_name}":
+ ensure => 'link',
+ target => "${base_path}/${script_name}",
+ require => File["${base_path}/${script_name}"],
+ }
+ }
+}
diff --git a/site/profiles/manifests/helpers/node_lookup.pp b/site/profiles/manifests/helpers/node_lookup.pp
index b155f6c..4e6ee01 100644
--- a/site/profiles/manifests/helpers/node_lookup.pp
+++ b/site/profiles/manifests/helpers/node_lookup.pp
@@ -12,45 +12,54 @@ class profiles::helpers::node_lookup (
Array[String[1]] $packages = ['requests'],
){
- # ensure the base_path exists
- file { $base_path:
- ensure => directory,
- mode => '0755',
- owner => $owner,
- group => $group,
- }
- # create a venv
- python::pyvenv { $venv_path :
- ensure => present,
- version => $version,
- systempkgs => $systempkgs,
- venv_dir => $venv_path,
- owner => $owner,
- group => $group,
- require => File[$base_path],
- }
+ if $::facts['python3_version'] {
- # install the required pip packages
- $packages.each |String $package| {
- python::pip { "${venv_path}_${package}":
+ $python_version = $version ? {
+ 'system' => $::facts['python3_version'],
+ default => $version,
+ }
+
+ # ensure the base_path exists
+ file { $base_path:
+ ensure => directory,
+ mode => '0755',
+ owner => $owner,
+ group => $group,
+ }
+
+ # create a venv
+ python::pyvenv { $venv_path :
ensure => present,
- pkgname => $package,
- virtualenv => $venv_path,
+ version => $python_version,
+ systempkgs => $systempkgs,
+ venv_dir => $venv_path,
+ owner => $owner,
+ group => $group,
+ require => File[$base_path],
+ }
+
+ # install the required pip packages
+ $packages.each |String $package| {
+ python::pip { "${venv_path}_${package}":
+ ensure => present,
+ pkgname => $package,
+ virtualenv => $venv_path,
+ }
+ }
+
+ # create the script from a template
+ file { "${base_path}/${script_name}":
+ ensure => file,
+ mode => '0755',
+ content => template("profiles/helpers/${script_name}.erb"),
+ require => Python::Pyvenv[$venv_path],
+ }
+
+ # create symbolic link in $PATH
+ file { "/usr/local/bin/${script_name}":
+ ensure => 'link',
+ target => "${base_path}/${script_name}",
+ require => File["${base_path}/${script_name}"],
}
}
-
- # create the script from a template
- file { "${base_path}/${script_name}":
- ensure => file,
- mode => '0755',
- content => template("profiles/helpers/${script_name}.erb"),
- require => Python::Pyvenv[$venv_path],
- }
-
- # create symbolic link in $PATH
- file { "/usr/local/bin/${script_name}":
- ensure => 'link',
- target => "${base_path}/${script_name}",
- require => File["${base_path}/${script_name}"],
- }
}
diff --git a/site/profiles/manifests/minio/server.pp b/site/profiles/manifests/minio/server.pp
new file mode 100644
index 0000000..3fdec43
--- /dev/null
+++ b/site/profiles/manifests/minio/server.pp
@@ -0,0 +1,208 @@
+# profiles::minio::server
+class profiles::minio::server (
+ String $minio_root_user,
+ String $minio_root_pass,
+ Array $minio_opts = [],
+ Boolean $minio_members_lookup = false,
+ String $minio_members_role = undef,
+ Integer $minio_members = undef,
+ Array $minio_servers = [],
+ String $minio_storage_class = 'EC:2',
+ String $version = 'RELEASE.2023-12-20T01-00-02Z',
+ String $checksum = '09fafaf399885b4912bafda6fa03fc4ccbc39ec45e17239677217317915d6aeb',
+ String $checksum_type = 'sha256',
+ String $owner = 'minio',
+ String $group = 'minio',
+ Stdlib::Fqdn $url_domain = $::facts['networking']['domain'],
+ Enum['http', 'https'] $url_scheme = 'http',
+ Array[String[0]] $blockdev = [],
+ Stdlib::Port $listen_port = 9000,
+ Stdlib::IP::Address $listen_addr = $::facts['networking']['ip'],
+ Stdlib::AbsolutePath $datadir = '/data/minio',
+ Stdlib::AbsolutePath $confdir = '/etc/minio',
+ Stdlib::AbsolutePath $homedir = '/var/lib/minio',
+ Stdlib::AbsolutePath $bindir = '/opt/minio',
+ Optional[Enum['puppet']] $cert_type = 'puppet',
+) {
+
+ # create the region string
+ $minio_region = "${::facts['country']}-${::facts['region']}"
+
+ # count the block devices
+ $blockdev_count = count($blockdev)
+
+ # create minio static facts, which are used by pre-compile facts
+ file { "${lookup('facts_path')}/minio_facts.yaml":
+ ensure => file,
+ content => template('profiles/minio/minio_facts.yaml.erb'),
+ }
+
+ # create the user if its not yet initialised, if it is initialised, let the minio::server class manage
+ # manage the resource. This is done so that the user/group exist before attempting to create the data-
+ # directories.
+ if ! $::facts['minio_user_exists'] {
+ class {'minio::server::user':
+ manage_user => true,
+ manage_group => true,
+ manage_home => true,
+ owner => $owner,
+ group => $group,
+ home => $homedir,
+ }
+ }
+
+ # create the datadir
+ if ! $::facts['minio_datadirs_initialised'] {
+
+ # create the datadir root
+ exec { "mkdir_p_${datadir}":
+ command => "mkdir -p '${datadir}'",
+ unless => "test -d '${datadir}'",
+ path => '/bin:/usr/bin',
+ }
+
+ # create te datavol's if blockdev's are listed
+ $blockdev.each |Integer $index, String $device| {
+ $id = $index + 1
+ profiles::storage::datavol {"${::facts['networking']['fqdn']}_${device}":
+ fstype => 'xfs',
+ vg => "minio_vg${id}",
+ pv => $device,
+ lv => "store${id}",
+ owner => $owner,
+ group => $group,
+ mount => "${datadir}/store${id}",
+ require => Exec["mkdir_p_${datadir}"],
+ }
+ }
+ }
+
+ # copy puppet certs to /etc/pki/tls/puppet
+ include profiles::pki::puppetcerts
+
+ # create the cert configuration hash
+ if $cert_type == 'puppet' {
+ $cert_conf = {
+ 'source_path' => '/etc/pki/tls/puppet',
+ 'source_cert_name' => $::facts['networking']['fqdn'],
+ 'source_key_name' => $::facts['networking']['fqdn'],
+ }
+ }
+
+ # if lookup is enabled, find all the hosts in the specified role and create the servers_array
+ if $minio_members_lookup {
+
+ # check that the role is also set
+ unless !($minio_members_role == undef) {
+ fail("minio_members_role must be provided for ${title} when minio_members_lookup is True")
+ }
+
+ # if it is, find hosts, sort them so they dont cause changes every run
+ #$servers_array = sort(query_nodes("enc_role='${minio_members_role}'", 'networking.fqdn'))
+ $servers_array = sort(query_nodes("enc_role='${minio_members_role}' and minio_region='${minio_region}'", 'networking.fqdn'))
+
+ # else use provided array from params
+ }else{
+ $servers_array = $minio_servers
+ }
+
+ # iterate through the servers_array and find the nodeid for each host
+ $servers_array.each |Integer $index, String $server| {
+ $id = $index + 1
+ if $::facts['networking']['fqdn'] == $server {
+ $nodeid = $id
+ if $::facts['minio_pool'] != undef {
+
+ # create a cname which is used to create a sequential group of names for distributed minio pool
+ profiles::dns::record { "${minio_region}-${::facts['minio_pool']}-${nodeid}.${::facts['networking']['domain']}_CNAME":
+ value => $::facts['networking']['hostname'],
+ type => 'CNAME',
+ record => "${minio_region}-${::facts['minio_pool']}-${nodeid}.${::facts['networking']['domain']}.",
+ zone => $::facts['networking']['domain'],
+ order => 10,
+ }
+ }
+ }
+ }
+
+ # wait until all expected servers in the pool have reported into puppet
+ if count($servers_array) == $::facts['minio_members'] and $::facts['minio_pool'] != undef {
+
+ # if datadirs and user have been initialised, prepare configuration.
+ if $::facts['minio_datadirs_initialised'] and $::facts['minio_user_exists'] {
+
+ # join the minio_opts
+ $options = join($minio_opts, ' ')
+
+ # create vars for $deployment_definition, others used below are params
+ $url_location = "${minio_region}-${::facts['minio_pool']}"
+ $url_servers = "1...${count($servers_array)}"
+
+ # create the deployment definition line
+ # >= 1 : https://au-somewhere-1-pool1-{1...5}.example.domain/var/minio/store{1...4}
+ # == 1 : https://au-somewhere-1-pool1-{1...5}.example.domain/var/minio/store1
+ # else : https://au-somewhere-1-pool1-{1...5}.example.domain/var/minio
+ if $blockdev_count >= 1 {
+ $deployment_definition = "${url_scheme}://${url_location}-{${url_servers}}.${url_domain}:${listen_port}${datadir}/store{1...${blockdev_count}}"
+ }elsif $blockdev_count == 1 {
+ $deployment_definition = "${url_scheme}://${url_location}-{${url_servers}}.${url_domain}:${listen_port}${datadir}/store1"
+ }else{
+ $deployment_definition = "${url_scheme}://${url_location}-{${url_servers}}.${url_domain}:${listen_port}${datadir}"
+ }
+
+ # create the configuration hash
+ $configuration = {
+ 'MINIO_ROOT_USER' => $minio_root_user,
+ 'MINIO_ROOT_PASSWORD' => $minio_root_pass.unwrap,
+ 'MINIO_REGION_NAME' => $minio_region,
+ 'MINIO_OPTS' => "\'${options}\'",
+ 'MINIO_DEPLOYMENT_DEFINITION' => $deployment_definition,
+ 'MINIO_STORAGE_CLASS_STANDARD' => $minio_storage_class,
+ }
+ }
+ }
+
+ # check all the expected DNS CNAME records do not exist
+ $all_dns_exist = $::facts['minio_pool_dns'].all |String $cname, Boolean $exists| { $exists }
+
+ # create the minio server if all dns records exist
+ if $all_dns_exist {
+ class { 'minio::server::install':
+ package_ensure => 'present',
+ owner => $owner,
+ group => $group,
+ base_url => 'https://dl.minio.io/server/minio/release',
+ version => $version,
+ checksum => $checksum,
+ checksum_type => $checksum_type,
+ configuration_directory => $confdir,
+ installation_directory => $bindir,
+ storage_root => $datadir,
+ listen_ip => $listen_addr,
+ listen_port => $listen_port,
+ manage_service => true,
+ service_template => 'profiles/minio/minio.service.erb',
+ service_provider => 'systemd',
+ cert_directory => "${confdir}/certs",
+ custom_configuration_file_path => '/etc/default/minio',
+ }
+
+ class { 'minio::server::config':
+ owner => $owner,
+ group => $group,
+ configuration_directory => $confdir,
+ installation_directory => $bindir,
+ storage_root => $datadir,
+ configuration => $configuration,
+ custom_configuration_file_path => '/etc/default/minio',
+ require => Class['Minio::Server::Install'],
+ }
+
+ class { 'minio::server::service':
+ manage_service => true,
+ service_provider => 'systemd',
+ service_ensure => 'running',
+ require => Class['Minio::Server::Config'],
+ }
+ }
+}
diff --git a/site/profiles/manifests/nginx/simpleproxy.pp b/site/profiles/manifests/nginx/simpleproxy.pp
new file mode 100644
index 0000000..28d6c1e
--- /dev/null
+++ b/site/profiles/manifests/nginx/simpleproxy.pp
@@ -0,0 +1,116 @@
+# profiles::nginx:simpleproxy
+#
+# only one simpleproxy per host, for anything more advanced, use nginx class
+class profiles::nginx::simpleproxy (
+ Stdlib::Fqdn $nginx_vhost = 'localhost',
+ Array[Stdlib::Host] $nginx_aliases = [],
+ Stdlib::Port $nginx_port = 80,
+ Stdlib::Port $nginx_ssl_port = 443,
+ Enum['http','https','both'] $nginx_listen_mode = 'https',
+ Enum['puppet', 'vault'] $nginx_cert_type = 'vault',
+ Enum['http','https'] $proxy_scheme = 'http',
+ Stdlib::Port $proxy_port = 80,
+ Stdlib::Host $proxy_host = $facts['networking']['ip'],
+ String $proxy_path = '/',
+) {
+
+ # if nginx_version isnt set, install nginx
+ if ! $facts['nginx_version'] {
+ package {'nginx':
+ ensure => 'present',
+ }
+
+ # else, configure simple proxy
+ }else{
+
+ # build the proxyurl from proxy_* variables
+ $proxyurl = "${proxy_scheme}://${proxy_host}:${proxy_port}${proxy_path}"
+
+ # set the server_names
+ $server_names = unique([$facts['networking']['fqdn'], $nginx_vhost] + $nginx_aliases)
+
+ # 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
+ }
+ }
+
+ # 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",
+ 'autoindex' => 'on',
+ 'ssl' => $enable_ssl,
+ 'ssl_cert' => $ssl_cert,
+ 'ssl_key' => $ssl_key,
+ 'ssl_port' => $listen_ssl_port,
+ 'proxy' => $proxyurl,
+ }
+
+ # merge the hashes conditionally
+ $nginx_parameters = merge($defaults, $extras_hash)
+
+ # manage the nginx class
+ include 'nginx'
+
+ # create the nginx vhost with the merged parameters
+ create_resources('nginx::resource::server', { $nginx_vhost => $nginx_parameters })
+
+ # manage selinux
+ if $::facts['os']['selinux']['config_mode'] == 'enforcing' {
+
+ # make sure nginx can reverse proxy
+ selboolean { 'httpd_can_network_connect':
+ persistent => true,
+ value => 'on',
+ }
+ }
+ }
+}
diff --git a/site/profiles/manifests/ntp/client.pp b/site/profiles/manifests/ntp/client.pp
index e3c90a7..c09cff2 100644
--- a/site/profiles/manifests/ntp/client.pp
+++ b/site/profiles/manifests/ntp/client.pp
@@ -11,6 +11,11 @@ class profiles::ntp::client (
'running',
'stopped'
] $wait_ensure = 'running',
+ Enum[
+ 'all',
+ 'region',
+ 'country'
+ ] $use_ntp = 'all',
Boolean $client_only = true,
) {
@@ -18,23 +23,25 @@ class profiles::ntp::client (
# through the profiles::ntp::server class.
if $client_only {
- # if ntp_role is set, find all hosts matching that enc_role
- if $ntp_role == undef {
- $ntpserver_array = $peers
- }else{
- $ntpserver_array = query_nodes("enc_role='${ntp_role}'", 'networking.fqdn')
+ $ntpserver_array = $ntp_role ? {
+ undef => $peers,
+ default => $use_ntp ? {
+ 'all' => query_nodes("enc_role='${ntp_role}'", 'networking.fqdn'),
+ 'region' => query_nodes("enc_role='${ntp_role}' and region=${facts['region']}", 'networking.fqdn'),
+ 'country' => query_nodes("enc_role='${ntp_role}' and country=${facts['country']}", 'networking.fqdn'),
+ }
}
# Define the client configuration based on OS family
if $facts['os']['family'] == 'RedHat' {
class { 'chrony':
- servers => $ntpserver_array,
+ servers => sort($ntpserver_array),
wait_enable => $wait_enable,
wait_ensure => $wait_ensure,
}
} else {
class { 'chrony':
- servers => $ntpserver_array,
+ servers => sort($ntpserver_array),
}
}
}
diff --git a/site/profiles/manifests/ovirt/node.pp b/site/profiles/manifests/ovirt/node.pp
new file mode 100644
index 0000000..9979c95
--- /dev/null
+++ b/site/profiles/manifests/ovirt/node.pp
@@ -0,0 +1,20 @@
+# profiles::ovirt::node
+class profiles::ovirt::node {
+ # Define the DNF modules to be enabled
+ $dnf_modules_to_enable = {
+ 'javapackages-tools' => { 'ensure' => 'latest' },
+ 'pki-deps' => { 'ensure' => 'latest' },
+ 'postgresql' => { 'ensure' => '12' },
+ 'mod_auth_openidc' => { 'ensure' => '2.3' },
+ 'nodejs' => { 'ensure' => '14' },
+ }
+
+ # Enable the DNF modules
+ create_resources(
+ 'package',
+ $dnf_modules_to_enable, {
+ provider => dnfmodule,
+ enable_only => true
+ }
+ )
+}
diff --git a/site/profiles/manifests/packages.pp b/site/profiles/manifests/packages.pp
new file mode 100644
index 0000000..ca43908
--- /dev/null
+++ b/site/profiles/manifests/packages.pp
@@ -0,0 +1,23 @@
+# This class manages the installation of packages for the base profile
+#
+# Parameters:
+# - $install: An array of package names to be installed
+# - $remove: An array of package names to be removed
+#
+class profiles::packages (
+ Array $install = [],
+ Array $install_exclude = [],
+ Array $remove = [],
+ Array $remove_exclude = [],
+) {
+
+ # Filter out excluded packages
+ $install_real = $install.filter |$item| { !$install_exclude.any |$exclude_item| { $exclude_item == $item } }
+ $remove_real = $remove.filter |$item| { !$remove_exclude.any |$exclude_item| { $exclude_item == $item } }
+
+ # Ensure packages to install are installed
+ ensure_packages($install_real, {'ensure' => 'present'})
+
+ # Ensure packages to remove are absent
+ ensure_packages($remove_real, {'ensure' => 'absent'})
+}
diff --git a/site/profiles/manifests/packages/base.pp b/site/profiles/manifests/packages/base.pp
deleted file mode 100644
index f7d51cf..0000000
--- a/site/profiles/manifests/packages/base.pp
+++ /dev/null
@@ -1,21 +0,0 @@
-# This class manages the installation of packages for the base profile
-#
-# Parameters:
-# - $add: An array of package names to be installed
-# - $remove: An array of package names to be removed
-#
-class profiles::packages::base (
- Array $add = [],
- Array $remove = [],
-) {
-
- # Ensure packages to add are installed
- ensure_packages($add, {'ensure' => 'present'})
-
- # Ensure packages to remove are absent
- $remove.each |String $package| {
- package { $package:
- ensure => 'absent',
- }
- }
-}
diff --git a/site/profiles/manifests/packages/git.pp b/site/profiles/manifests/packages/git.pp
deleted file mode 100644
index 578aca7..0000000
--- a/site/profiles/manifests/packages/git.pp
+++ /dev/null
@@ -1,11 +0,0 @@
-# installs git related packages
-#
-class profiles::packages::git (
- Array[String] $packages = lookup('profiles::packages::git', Array, 'first', ['git']),
-) {
- $packages.each |String $package| {
- package { $package:
- ensure => installed,
- }
- }
-}
diff --git a/site/profiles/manifests/packages/reposync.pp b/site/profiles/manifests/packages/reposync.pp
deleted file mode 100644
index f6525a5..0000000
--- a/site/profiles/manifests/packages/reposync.pp
+++ /dev/null
@@ -1,11 +0,0 @@
-# installs reposync related packages
-#
-class profiles::packages::reposync (
- Array[String] $packages = lookup('profiles::packages::reposync', Array, 'first', ['createrepo']),
-) {
- $packages.each |String $package| {
- package { $package:
- ensure => installed,
- }
- }
-}
diff --git a/site/profiles/manifests/packages/selinux.pp b/site/profiles/manifests/packages/selinux.pp
deleted file mode 100644
index 1bbd457..0000000
--- a/site/profiles/manifests/packages/selinux.pp
+++ /dev/null
@@ -1,11 +0,0 @@
-# installs selinux related packages
-#
-class profiles::packages::selinux (
- Array[String] $packages = lookup('profiles::packages::selinux', Array, 'first', ['policycoreutils']),
-) {
- $packages.each |String $package| {
- package { $package:
- ensure => installed,
- }
- }
-}
diff --git a/site/profiles/manifests/pki/puppetcerts.pp b/site/profiles/manifests/pki/puppetcerts.pp
new file mode 100644
index 0000000..bf02ecd
--- /dev/null
+++ b/site/profiles/manifests/pki/puppetcerts.pp
@@ -0,0 +1,42 @@
+# profiles::pki::puppetcerts
+class profiles::pki::puppetcerts {
+
+ # Define the directory
+ file { '/etc/pki/tls/puppet':
+ ensure => 'directory',
+ owner => 'root',
+ group => 'root',
+ mode => '0755',
+ }
+
+ # Copy the CA certificate
+ file { '/etc/pki/tls/puppet/ca.pem':
+ ensure => 'file',
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ source => '/etc/puppetlabs/puppet/ssl/certs/ca.pem',
+ require => File['/etc/pki/tls/puppet'],
+ }
+
+ # Copy the private key
+ file { "/etc/pki/tls/puppet/${facts['networking']['fqdn']}.key":
+ ensure => 'file',
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ source => "/etc/puppetlabs/puppet/ssl/private_keys/${facts['networking']['fqdn']}.pem",
+ require => File['/etc/pki/tls/puppet'],
+ }
+
+ # Copy the certificate
+ $cert = "/etc/puppetlabs/puppet/ssl/certs/${facts['networking']['fqdn']}.pem"
+ file { "/etc/pki/tls/puppet/${facts['networking']['fqdn']}.crt":
+ ensure => 'file',
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ source => "/etc/puppetlabs/puppet/ssl/certs/${facts['networking']['fqdn']}.pem",
+ require => File['/etc/pki/tls/puppet'],
+ }
+}
diff --git a/site/profiles/manifests/pki/vault.pp b/site/profiles/manifests/pki/vault.pp
new file mode 100644
index 0000000..e680383
--- /dev/null
+++ b/site/profiles/manifests/pki/vault.pp
@@ -0,0 +1,141 @@
+# profiles::pki::vault
+class profiles::pki::vault (
+ Optional[Array[Stdlib::Host]] $alt_names = [],
+ Optional[Array[Stdlib::IP::Address]] $ip_sans = [],
+){
+
+ # validate and prepare additional alt_names, if any
+ $default_alt_names = [$::facts['networking']['hostname'], $::facts['networking']['fqdn']]
+ $effective_alt_names = $alt_names ? {
+ [] => $default_alt_names,
+ default => concat($default_alt_names, $alt_names),
+ }
+
+ # validate and prepare additional ip_sans, if any
+ $default_ip_sans = ['127.0.0.1', $::facts['networking']['ip']]
+ $effective_ip_sans = $ip_sans ? {
+ [] => $default_ip_sans,
+ default => concat($default_ip_sans, $ip_sans),
+ }
+
+ # path for the alt names file
+ $base_path = '/etc/pki/tls/vault'
+ $alt_names_file = "${base_path}/alt_names"
+
+ # ensure the base directory exists
+ file { '/etc/pki':
+ ensure => directory,
+ owner => 'root',
+ group => 'root',
+ mode => '0755',
+ }
+ file { '/etc/pki/tls':
+ ensure => directory,
+ owner => 'root',
+ group => 'root',
+ mode => '0755',
+ require => File['/etc/pki']
+ }
+ file { $base_path:
+ ensure => directory,
+ owner => 'root',
+ group => 'root',
+ mode => '0755',
+ require => File['/etc/pki/tls']
+ }
+
+ # alt_names_file contents
+ $alt_names_content = concat($effective_alt_names, $effective_ip_sans)
+
+ # manage the alt names file
+ file { $alt_names_file:
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ content => join($alt_names_content, "\n"),
+ require => File[$base_path]
+ }
+
+ # compare the sorted arrays of altnames from disk (fact) vs what is intended (this run)
+ $alt_names_match = sort($::facts['vault_cert_altnames']) == sort($alt_names_content)
+
+ # only renew certificate if its expiring or the alt names have changed
+ if $::facts['vault_cert_expiring'] or ! $alt_names_match {
+
+ # certificate variables
+ $common_name = $::facts['networking']['fqdn']
+ $valid_days = 90
+
+ # prepare alt_names and ip_sans arguments conditionally
+ $alt_names_string = $effective_alt_names.empty() ? {
+ true => '',
+ default => join($effective_alt_names, ','),
+ }
+ $ip_sans_string = $effective_ip_sans.empty() ? {
+ true => '',
+ default => join($effective_ip_sans, ','),
+ }
+
+ # certmanager arguments
+ $cmd = '/usr/local/bin/certmanager'
+ $alt_names_arg = '--alt-names'
+ $ip_sans_arg = '--ip-sans'
+ $expiry_days_arg = '--expiry-days'
+
+ # call the script with generate(), capturing json output
+ $json_output = generate(
+ $cmd,
+ $common_name,
+ $alt_names_arg,
+ $alt_names_string,
+ $ip_sans_arg,
+ $ip_sans_string,
+ $expiry_days_arg,
+ $valid_days,
+ '--json'
+ )
+ $cert_data = parsejson($json_output)
+
+ # manage certificate file resources based on script output
+ $certificate_files = {
+ "${base_path}/certificate.crt" => $cert_data['certificate'],
+ "${base_path}/private.key" => $cert_data['private_key'],
+ "${base_path}/full_chain.crt" => $cert_data['full_chain'],
+ "${base_path}/ca_certificate.crt" => $cert_data['ca_certificate'],
+ "${base_path}/certificate.pem" => "${cert_data['certificate']}\n${cert_data['private_key']}",
+ }
+
+ # manage each file resources
+ $certificate_files.each |$file_path, $content| {
+ file { $file_path:
+ ensure => file,
+ content => $content,
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ require => File[$base_path],
+ }
+ }
+
+ }else{
+ # manage each file resources, but dont change the content
+ $certificate_files = [
+ "${base_path}/certificate.crt",
+ "${base_path}/private.key",
+ "${base_path}/full_chain.crt",
+ "${base_path}/ca_certificate.crt",
+ "${base_path}/certificate.pem"
+ ]
+
+ $certificate_files.each |$file_path| {
+ file { $file_path:
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ require => File[$base_path],
+ }
+ }
+ }
+}
diff --git a/site/profiles/manifests/pki/vaultca.pp b/site/profiles/manifests/pki/vaultca.pp
new file mode 100644
index 0000000..9ebc067
--- /dev/null
+++ b/site/profiles/manifests/pki/vaultca.pp
@@ -0,0 +1,37 @@
+# ensure the ca certificate for vault is installed everywhere
+class profiles::pki::vaultca {
+ $root_cacert = 'vaultcaroot.pem'
+
+ # Define the target path based on the operating system
+ case $facts['os']['family'] {
+ 'RedHat': {
+ $ca_cert_target_path = "/etc/pki/ca-trust/source/anchors/${root_cacert}"
+ $update_ca_cert_command = 'update-ca-trust extract'
+ }
+ 'Debian': {
+ $ca_cert_target_path = "/usr/local/share/ca-certificates/${root_cacert}"
+ $update_ca_cert_command = 'update-ca-certificates'
+ }
+ default: {
+ fail("Unsupported operating system: ${facts['os']['family']}")
+ }
+ }
+
+ # Ensure the CA certificate is present and contains the content from the template
+ file { $ca_cert_target_path:
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ content => template('profiles/pki/vaultcaroot.pem.erb'),
+ notify => Exec['update_ca_trust_store'],
+ }
+
+ # Execute the system command to update the CA trust store
+ exec { 'update_ca_trust_store':
+ command => $update_ca_cert_command,
+ path => ['/bin', '/usr/bin', 'sbin', '/usr/sbin'],
+ refreshonly => true,
+ require => File[$ca_cert_target_path],
+ }
+}
diff --git a/site/profiles/manifests/proxmox/ceph.pp b/site/profiles/manifests/proxmox/ceph.pp
new file mode 100644
index 0000000..3bff1b0
--- /dev/null
+++ b/site/profiles/manifests/proxmox/ceph.pp
@@ -0,0 +1,50 @@
+# profiles::proxmox::ceph
+class profiles::proxmox::ceph {
+
+ # include params class
+ include profiles::proxmox::params
+
+ # localise some vars
+ $network = $profiles::proxmox::params::pve_ceph_network
+ $size = $profiles::proxmox::params::pve_ceph_size
+ $min_size = $profiles::proxmox::params::pve_ceph_minsize
+
+ # install ceph if it is enabled
+ if $profiles::proxmox::params::pve_ceph_install {
+
+ # initialise the cluster, but only on the clusterinit node and only if its not already initialised
+ if $profiles::proxmox::params::pve_clusterinit_master and ! $facts['pve_ceph_initialised']{
+ exec { 'pveceph_init':
+ command => "/usr/bin/pveceph init --network ${network} --size ${size} --min_size ${min_size}",
+ user => 'root',
+ }
+ }
+
+ if $facts['pve_ceph_initialised'] {
+
+ # create monitors
+ if $profiles::proxmox::params::pve_ceph_mon {
+
+ # only when its not already a monitor
+ if ! $facts['is_pveceph_mon'] {
+ exec { 'pveceph_mon':
+ command => '/usr/bin/pveceph mon create',
+ user => 'root',
+ }
+ }
+ }
+
+ # create managers
+ if $profiles::proxmox::params::pve_ceph_mgr {
+
+ # only when its not already a manager
+ if ! $facts['is_pveceph_mgr'] {
+ exec { 'pveceph_mgr':
+ command => '/usr/bin/pveceph mgr create',
+ user => 'root',
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/site/profiles/manifests/proxmox/clusterinit.pp b/site/profiles/manifests/proxmox/clusterinit.pp
new file mode 100644
index 0000000..65189b3
--- /dev/null
+++ b/site/profiles/manifests/proxmox/clusterinit.pp
@@ -0,0 +1,41 @@
+# profiles::proxmox::clusterinit
+class profiles::proxmox::clusterinit {
+
+ # include params class
+ include profiles::proxmox::params
+
+ # localise some vars
+ $clusterinit_master = $profiles::proxmox::params::pve_clusterinit_master
+ $clustername = $profiles::proxmox::params::pve_cluster
+ $membersrole = $profiles::proxmox::params::pve_members_role
+
+ # if this is the cluster master
+ if $clusterinit_master {
+
+ # and its not a member of a cluster yet
+ if ! $facts['pve_cluster_member'] {
+
+ # initialise a cluster
+ exec {'pve_init_cluster':
+ command => "/usr/bin/pvecm create ${clustername}",
+ unless => 'pvecm status',
+ timeout => 60,
+ }
+ }
+ }
+
+ $servers_array = sort(query_nodes(
+ "enc_role='${membersrole}' and country='${facts['country']}' and region='${facts['region']}'",
+ 'networking.fqdn'
+ ))
+
+ if ! $profiles::proxmox::params::pve_clusterinit_master {
+ if !empty($servers_array) {
+ notify { "Cluster ${profiles::proxmox::params::pve_cluster} detected, proceeding to join...":
+ }
+ } else {
+ notify { "No cluster flag found for ${profiles::proxmox::params::pve_cluster}, not attempting to join":
+ }
+ }
+ }
+}
diff --git a/site/profiles/manifests/proxmox/clusterjoin.pp b/site/profiles/manifests/proxmox/clusterjoin.pp
new file mode 100644
index 0000000..7ab3ea5
--- /dev/null
+++ b/site/profiles/manifests/proxmox/clusterjoin.pp
@@ -0,0 +1,74 @@
+# profiles::proxmox::clusterjoin
+class profiles::proxmox::clusterjoin {
+
+ # include params class
+ include profiles::proxmox::params
+
+ # localise some vars
+ $clusterinit_master = $profiles::proxmox::params::pve_clusterinit_master
+ $clustername = $profiles::proxmox::params::pve_cluster
+ $membersrole = $profiles::proxmox::params::pve_members_role
+ $root_password = $profiles::proxmox::params::root_password
+
+ # query puppetdb for list of cluster members
+ $members_array = sort(query_nodes(
+ "enc_role='${membersrole}' and \
+ country='${facts['country']}' and \
+ region='${facts['region']}' and \
+ pve_cluster.cluster_name='${clustername}'",
+ 'networking.fqdn'
+ ))
+
+ # check if the pve kernerl is running
+ if $facts['kernelrelease'] == $profiles::proxmox::params::pve_kernel_release {
+
+ # if this is the cluster master
+ if $clusterinit_master {
+
+ # there are no cluster members in puppetdb
+ if empty($members_array) {
+
+ # and this host isnt already in a cluster by itself
+ if ! $facts['pve_cluster'] {
+
+ # initialise a cluster
+ exec {'pve_init_cluster':
+ command => "/usr/bin/pvecm create ${clustername}",
+ unless => 'pvecm status',
+ timeout => 60,
+ }
+ }
+ }
+ }
+
+ # for non-masters
+ if ! $clusterinit_master {
+
+ # if there are already members of the cluster
+ if !empty($members_array) {
+
+ # and this host isnt already in a cluster
+ if ! $facts['pve_cluster'] {
+
+ # create an expect script to join the cluster
+ file { '/usr/local/bin/join_pvecluster.expect':
+ ensure => file,
+ owner => 'root',
+ mode => '0755',
+ content => template('profiles/proxmox/join_pvecluster.erb'),
+ }
+
+ exec { 'pve_join_cluster':
+ command => "/usr/local/bin/join_pvecluster.expect '${root_password.unwrap}' '${members_array[0]}'",
+ require => [File['/usr/local/bin/join_pvecluster.expect'], Package['expect']],
+ unless => "/usr/bin/pvesh nodes | grep -q '${facts['networking']['hostname']}'",
+ user => 'root',
+ }
+ }
+ } else {
+ notify { "No initialised cluster found for ${clustername}, not attempting to join":
+ }
+ }
+ }
+ }
+}
diff --git a/site/profiles/manifests/proxmox/config.pp b/site/profiles/manifests/proxmox/config.pp
new file mode 100644
index 0000000..0edc8d1
--- /dev/null
+++ b/site/profiles/manifests/proxmox/config.pp
@@ -0,0 +1,19 @@
+# profiles::proxmox::config
+class profiles::proxmox::config {
+
+ # include params class
+ include profiles::proxmox::params
+
+ # localise some vars
+ $clusterinit_master = $profiles::proxmox::params::pve_clusterinit_master
+
+ # create pve_facts file
+ file {'/opt/puppetlabs/facter/facts.d/pve_facts.yaml':
+ ensure => 'file',
+ owner => 'root',
+ group => 'root',
+ mode => '0600',
+ content => template('profiles/proxmox/pve_facts.yaml.erb')
+ }
+
+}
diff --git a/site/profiles/manifests/proxmox/init.pp b/site/profiles/manifests/proxmox/init.pp
new file mode 100644
index 0000000..1d90b3d
--- /dev/null
+++ b/site/profiles/manifests/proxmox/init.pp
@@ -0,0 +1,17 @@
+# proxmox::
+class profiles::proxmox::init {
+
+ #include profiles::proxmox::params
+ include profiles::proxmox::repos
+ include profiles::proxmox::install
+ include profiles::proxmox::clusterjoin
+ include profiles::proxmox::ceph
+ include profiles::proxmox::config
+ include profiles::proxmox::weblb
+
+ Class['profiles::proxmox::repos']
+ -> Class['profiles::proxmox::install']
+ -> Class['profiles::proxmox::clusterjoin']
+ -> Class['profiles::proxmox::ceph']
+ -> Class['profiles::proxmox::config']
+}
diff --git a/site/profiles/manifests/proxmox/install.pp b/site/profiles/manifests/proxmox/install.pp
new file mode 100644
index 0000000..4cfdba2
--- /dev/null
+++ b/site/profiles/manifests/proxmox/install.pp
@@ -0,0 +1,58 @@
+# profiles::proxmox::install
+class profiles::proxmox::install {
+
+ # include params class
+ include profiles::proxmox::params
+
+ # install the pve kernel
+ package { 'proxmox-default-kernel':
+ ensure => $profiles::proxmox::params::pve_kernel_version,
+ notify => Reboot['after_run'],
+ require => Apt::Source['proxmox'],
+ }
+
+ # reboot into the new kernel
+ reboot { 'after_run':
+ apply => finished,
+ }
+
+ if $facts['kernelrelease'] == $profiles::proxmox::params::pve_kernel_release {
+
+ # install pve
+ ensure_packages($profiles::proxmox::params::pve_packages_install, { ensure => 'present', require => Apt::Source['proxmox']})
+
+ # remove the old linux kernel metapackage
+ ensure_packages($profiles::proxmox::params::pve_packages_remove, { ensure => 'absent' })
+
+ # install ceph package if requested
+ if $profiles::proxmox::params::pve_ceph_install {
+ ensure_packages($profiles::proxmox::params::pve_packages_ceph, { ensure => 'present', require => Apt::Source['ceph'] })
+ }
+
+ # cleanup the old kernel packages
+ exec { 'remove-linux-kernel-packages':
+ command => '/usr/bin/apt-get purge -y $(/usr/bin/dpkg --list | /bin/grep "linux-image-6.1" | /usr/bin/awk \'{ print $2 }\')',
+ onlyif => '/usr/bin/dpkg --list | /bin/grep -q "linux-image-6.1"',
+ path => ['/usr/bin', '/bin', '/sbin'],
+ refreshonly => true,
+ }
+
+ # update grup
+ exec { 'update-grub':
+ command => '/usr/sbin/update-grub',
+ path => ['/usr/bin', '/bin', '/sbin'],
+ refreshonly => true,
+ }
+
+ # update grub after removing kernel packages only
+ Exec['remove-linux-kernel-packages'] ~> Exec['update-grub']
+
+ # prepare for SDN
+ file_line { 'source-network-interfaces-d':
+ path => '/etc/network/interfaces',
+ line => 'source /etc/network/interfaces.d/*',
+ match => '^source /etc/network/interfaces.d/\*$',
+ append_on_no_match => true,
+ }
+ }
+}
diff --git a/site/profiles/manifests/proxmox/params.pp b/site/profiles/manifests/proxmox/params.pp
new file mode 100644
index 0000000..17e69ce
--- /dev/null
+++ b/site/profiles/manifests/proxmox/params.pp
@@ -0,0 +1,44 @@
+# profiles::proxmox::params
+class profiles::proxmox::params (
+ Sensitive[String] $root_password = Sensitive(lookup('profiles::accounts::root::password')),
+ String $pve_members_role = 'roles::infra::proxmox::node',
+ String $pve_kernel_version = '1.0.1',
+ String $pve_kernel_release = '6.5.13-5-pve',
+ String $pve_cluster = "${::facts['country']}-${::facts['region']}",
+ Boolean $pve_clusterinit_master = false,
+ Boolean $pve_ceph_repos = false,
+ Boolean $pve_ceph_install = false,
+ Boolean $pve_ceph_mon = false,
+ Boolean $pve_ceph_mgr = false,
+ Boolean $pve_ceph_osd = false,
+ String $pve_ceph_release = 'quincy',
+ Integer $pve_ceph_size = 3,
+ Integer $pve_ceph_minsize = 2,
+ Variant[
+ Undef,
+ Stdlib::IP::Address::V4::CIDR
+ ] $pve_ceph_network = undef,
+
+ Array $pve_packages_install = [
+ 'proxmox-ve',
+ 'postfix',
+ 'open-iscsi',
+ 'frr-pythontools',
+ 'ksm-control-daemon'
+ ],
+ Array $pve_packages_remove = [
+ 'os-prober',
+ 'linux-image-amd64'
+ ],
+ Array $pve_packages_ceph = [
+ 'ceph',
+ 'ceph-common',
+ 'ceph-fuse',
+ 'ceph-mds',
+ 'ceph-volume',
+ 'gdisk',
+ 'nvme-cli'
+ ],
+ Stdlib::Port $pve_webport = 8006,
+){
+}
diff --git a/site/profiles/manifests/proxmox/repos.pp b/site/profiles/manifests/proxmox/repos.pp
new file mode 100644
index 0000000..0378fa4
--- /dev/null
+++ b/site/profiles/manifests/proxmox/repos.pp
@@ -0,0 +1,37 @@
+# profiles::proxmox::repos
+class profiles::proxmox::repos {
+
+ # include params class
+ include profiles::proxmox::params
+
+ $codename = $facts['os']['distro']['codename']
+
+ exec { 'download-proxmox-gpg-key':
+ command => "/usr/bin/wget https://enterprise.proxmox.com/debian/proxmox-release-${codename}.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-${codename}.gpg",
+ creates => "/etc/apt/trusted.gpg.d/proxmox-release-${codename}.gpg",
+ path => ['/usr/bin', '/bin'],
+ require => File['/etc/apt/trusted.gpg.d/'],
+ }
+
+ file { '/etc/apt/trusted.gpg.d/':
+ ensure => 'directory',
+ }
+
+ apt::source { 'proxmox':
+ location => 'http://download.proxmox.com/debian/pve',
+ repos => 'pve-no-subscription',
+ include => {
+ src => false,
+ },
+ }
+
+ if $profiles::proxmox::params::pve_ceph_repos {
+ apt::source { 'ceph':
+ location => "http://download.proxmox.com/debian/ceph-${profiles::proxmox::params::pve_ceph_release}",
+ repos => 'no-subscription',
+ include => {
+ src => false,
+ },
+ }
+ }
+}
diff --git a/site/profiles/manifests/proxmox/weblb.pp b/site/profiles/manifests/proxmox/weblb.pp
new file mode 100644
index 0000000..a1bd2c0
--- /dev/null
+++ b/site/profiles/manifests/proxmox/weblb.pp
@@ -0,0 +1,33 @@
+# profiles::proxmox::weblb
+class profiles::proxmox::weblb {
+
+ # include params class
+ include profiles::proxmox::params
+
+ # export haproxy balancemember
+ profiles::haproxy::balancemember { "${facts['networking']['fqdn']}_${profiles::proxmox::params::pve_webport}}":
+ service => "be_${facts['country']}${facts['region']}pve_web",
+ ports => [$profiles::proxmox::params::pve_webport],
+ options => [
+ "cookie ${facts['networking']['hostname']}",
+ 'ssl',
+ 'verify none',
+ 'check',
+ 'inter 2s',
+ 'rise 3',
+ 'fall 2',
+ ]
+ }
+ profiles::haproxy::balancemember { "${facts['networking']['fqdn']}_${profiles::proxmox::params::pve_webport}_api2}":
+ service => "be_${facts['country']}${facts['region']}pve_api",
+ ports => [$profiles::proxmox::params::pve_webport],
+ options => [
+ 'ssl',
+ 'verify none',
+ 'check',
+ 'inter 2s',
+ 'rise 3',
+ 'fall 2',
+ ]
+ }
+}
diff --git a/site/profiles/manifests/puppet/agent.pp b/site/profiles/manifests/puppet/agent.pp
index 0c2122e..76164c1 100644
--- a/site/profiles/manifests/puppet/agent.pp
+++ b/site/profiles/manifests/puppet/agent.pp
@@ -4,11 +4,6 @@ class profiles::puppet::agent (
String $puppet_version = 'latest',
) {
- # Ensure the puppet-agent package is installed and locked to a specific version
- package { 'puppet-agent':
- ensure => $puppet_version,
- }
-
# if puppet-version is anything other than latest, set a versionlock
$puppet_versionlock_ensure = $puppet_version ? {
'latest' => 'absent',
@@ -18,9 +13,29 @@ class profiles::puppet::agent (
'latest' => undef,
default => $puppet_version,
}
- yum::versionlock{'puppet-agent':
- ensure => $puppet_versionlock_ensure,
- version => $puppet_versionlock_version,
+
+ case $facts['os']['family'] {
+ 'RedHat': {
+ # Ensure the puppet-agent package is installed and locked to a specific version
+ package { 'puppet-agent':
+ ensure => $puppet_version,
+ require => Yumrepo['puppet'],
+ }
+
+ # versionlock puppet-agent
+ yum::versionlock{'puppet-agent':
+ ensure => $puppet_versionlock_ensure,
+ version => $puppet_versionlock_version,
+ }
+ }
+ 'Debian': {
+ # Ensure the puppet-agent package is installed and locked to a specific version
+ package { 'puppet-agent':
+ ensure => $puppet_version,
+ require => Class['profiles::apt::puppet7'],
+ }
+ }
+ default: {}
}
# Ensure the puppet service is running
diff --git a/site/profiles/manifests/puppet/autosign.pp b/site/profiles/manifests/puppet/autosign.pp
index 0c75d25..b154aea 100644
--- a/site/profiles/manifests/puppet/autosign.pp
+++ b/site/profiles/manifests/puppet/autosign.pp
@@ -4,35 +4,6 @@
# based on specified subnet ranges and domain patterns.
# It is useful in environments where nodes are dynamically provisioned and
# require automatic certificate signing without manual intervention.
-#
-# Parameters:
-# - `subnet_ranges`: An array of IP subnet ranges in CIDR notation.
-# Nodes with IP addresses within these ranges will have their
-# certificates autosigned.
-# Default: []
-# Example: ['198.18.17.0/24']
-#
-# - `domains`: An array of domain patterns.
-# Nodes with hostnames matching these patterns will have their
-# certificates autosigned.
-# Default: []
-# Example: ['*.main.unkin.net', '*.secondary.unkin.net']
-#
-# - `nodes`: An array of specific node names.
-# Nodes with hostnames matching these will have their
-# certificates autosigned.
-# Default: []
-# Example: ['somenode.main.unkin.net', 'othernode.secondary.unkin.net']
-# Usage:
-#
-# To include this class with custom parameters:
-# class { 'profiles::puppet::autosign':
-# subnet_ranges => ['198.18.17.0/24', '198.18.18.0/24'],
-# domains => ['*.main.unkin.net', '*.dev.unkin.net'],
-# nodes => ['somenode.main.unkin.net', 'othernode.dev.unkin.net'],
-# }
-#
-# Alternatively, configure subnet ranges and domains through Hiera.
class profiles::puppet::autosign (
Array[Stdlib::IP::Address::V4::CIDR] $subnet_ranges = [],
Array[String[1]] $domains = [],
diff --git a/site/profiles/manifests/puppet/client.pp b/site/profiles/manifests/puppet/client.pp
index 973f621..aa3444c 100644
--- a/site/profiles/manifests/puppet/client.pp
+++ b/site/profiles/manifests/puppet/client.pp
@@ -4,7 +4,7 @@
#
# site/profile/manifests/puppet/client.pp
class profiles::puppet::client (
- String $dns_alt_names = $trusted['certname'],
+ Array $dns_alt_names = [$trusted['certname']],
String $server = 'puppetmaster',
String $ca_server = 'puppetca',
String $environment = 'develop',
@@ -14,14 +14,21 @@ class profiles::puppet::client (
Boolean $usecacheonfailure = false,
) {
- # Assuming you want to manage puppet.conf with this profile
- file { '/etc/puppetlabs/puppet/puppet.conf':
- ensure => 'present',
- content => template('profiles/puppet/client/puppet.conf.erb'),
- owner => 'root',
- group => 'root',
- mode => '0644',
- notify => Service['puppet'],
+ # dont manage puppet.conf if this is a puppetmaster
+ if $facts['enc_role'] != 'roles::infra::puppet::master' {
+
+
+ $dns_alt_names_string = join(sort($dns_alt_names), ',')
+
+ # Assuming you want to manage puppet.conf with this profile
+ file { '/etc/puppetlabs/puppet/puppet.conf':
+ ensure => 'present',
+ content => template('profiles/puppet/client/puppet.conf.erb'),
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ notify => Service['puppet'],
+ }
}
}
diff --git a/site/profiles/manifests/puppet/cobbler_enc.pp b/site/profiles/manifests/puppet/cobbler_enc.pp
new file mode 100644
index 0000000..a3e9708
--- /dev/null
+++ b/site/profiles/manifests/puppet/cobbler_enc.pp
@@ -0,0 +1,76 @@
+# Class: profiles::puppet::cobbler_enc
+#
+# This will deploy the cobbler-enc tool for puppetmasters
+#
+# wrapper class for python, pip and venv
+class profiles::puppet::cobbler_enc (
+ Stdlib::Host $cobbler_hostname,
+ Enum['http','https'] $cobbler_scheme = 'https',
+ String $script_name = 'cobbler-enc',
+ Stdlib::AbsolutePath $base_path = "/opt/${script_name}",
+ Stdlib::AbsolutePath $venv_path = "${base_path}/venv",
+ String $owner = 'root',
+ String $group = 'root',
+ Boolean $systempkgs = false,
+ String $version = 'system',
+ Array[String[1]] $packages = ['sys','requests','pyyaml'],
+ Stdlib::AbsolutePath $trusted_ca_cert = '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem'
+){
+
+ # set the cobbler url, required for the erb template
+ $cobbler_base_url = "${cobbler_scheme}://${cobbler_hostname}"
+
+ if $::facts['python3_version'] {
+
+ $python_version = $version ? {
+ 'system' => $::facts['python3_version'],
+ default => $version,
+ }
+
+ # ensure the base_path exists
+ file { $base_path:
+ ensure => directory,
+ mode => '0755',
+ owner => $owner,
+ group => $group,
+ }
+
+ # create a venv
+ python::pyvenv { $venv_path :
+ ensure => present,
+ version => $python_version,
+ systempkgs => $systempkgs,
+ venv_dir => $venv_path,
+ owner => $owner,
+ group => $group,
+ require => File[$base_path],
+ }
+
+ # install the required pip packages
+ $packages.each |String $package| {
+ python::pip { "${venv_path}_${package}":
+ ensure => present,
+ pkgname => $package,
+ virtualenv => $venv_path,
+ }
+ }
+
+ # create the script from a template
+ file { "${base_path}/${script_name}":
+ ensure => file,
+ mode => '0755',
+ content => template("profiles/puppet/server/${script_name}.erb"),
+ require => [
+ Python::Pyvenv[$venv_path],
+ Package['python3.11']
+ ],
+ }
+
+ # create symbolic link in $PATH
+ file { "/usr/local/bin/${script_name}":
+ ensure => 'link',
+ target => "${base_path}/${script_name}",
+ require => File["${base_path}/${script_name}"],
+ }
+ }
+}
diff --git a/site/profiles/manifests/puppet/enc.pp b/site/profiles/manifests/puppet/enc.pp
index dad9d11..fcfeec7 100644
--- a/site/profiles/manifests/puppet/enc.pp
+++ b/site/profiles/manifests/puppet/enc.pp
@@ -4,43 +4,12 @@
# systemd service and timer to keep the repository updated every minute.
# The Git package is installed if not present, and the repository at the given
# location will always reflect the state of the remote Git repository.
-#
-# Parameters:
-# - enc_repo: The URL of the Git repository to clone.
-#
-# Actions:
-# - Ensures the Git package is installed.
-# - Ensures the /opt/puppetlabs/enc directory is a clone of the given Git repository.
-# - Creates a helper script '/opt/puppetlabs/bin/git_update' for updating the Git repository.
-# - Creates a systemd service and timer that runs the git update script every minute.
-#
-# Usage:
-# Directly include the class in your node definitions or classify your nodes
-# using an ENC or Hiera.
-# Example:
-# node 'puppet.example.com' {
-# class { 'profiles::puppet::enc':
-# enc_repo => 'https://github.com/user/repo.git',
-# }
-# }
-#
-# Requirements:
-# - The 'puppet-vcsrepo' module should be installed on your puppetmaster.
-# - The 'puppet-systemd' module should be installed on your puppetmaster.
-# - '/opt/puppetlabs/bin/' directory must exist and be writable.
-# - Puppet master must have access to the specified Git URL.
-#
-# Limitations:
-# This is designed to work on Unix-like systems only.
-#
class profiles::puppet::enc (
String $repo,
String $release = 'master',
Boolean $force = false,
) {
- include profiles::packages::git
-
vcsrepo { '/opt/puppetlabs/enc':
ensure => latest,
provider => git,
diff --git a/site/profiles/manifests/puppet/eyaml.pp b/site/profiles/manifests/puppet/eyaml.pp
new file mode 100644
index 0000000..093e9c2
--- /dev/null
+++ b/site/profiles/manifests/puppet/eyaml.pp
@@ -0,0 +1,41 @@
+# profiles::puppet::eyaml
+class profiles::puppet::eyaml (
+ String $privatekey = '',
+ String $publickey = '',
+) {
+
+ # create the /var/lib/puppet/keys directory
+ file { '/var/lib/puppet':
+ ensure => 'directory',
+ owner => 'puppet',
+ group => 'root',
+ mode => '0755',
+ }
+ file { '/var/lib/puppet/keys':
+ ensure => 'directory',
+ owner => 'puppet',
+ group => 'root',
+ mode => '0755',
+ require => File['/var/lib/puppet']
+ }
+ # manage the eyaml private key
+ file { '/var/lib/puppet/keys/private_key.pkcs7.pem':
+ ensure => 'file',
+ owner => 'puppet',
+ group => 'root',
+ mode => '0400',
+ content => Sensitive($privatekey),
+ before => Service['puppetserver'],
+ require => File['/var/lib/puppet/keys'],
+ }
+ # manage the eyaml private key
+ file { '/var/lib/puppet/keys/public_key.pkcs7.pem':
+ ensure => 'file',
+ owner => 'puppet',
+ group => 'root',
+ mode => '0400',
+ content => Sensitive($publickey),
+ before => Service['puppetserver'],
+ require => File['/var/lib/puppet/keys'],
+ }
+}
diff --git a/site/profiles/manifests/puppet/g10k.pp b/site/profiles/manifests/puppet/g10k.pp
index 617190b..3a2af5e 100644
--- a/site/profiles/manifests/puppet/g10k.pp
+++ b/site/profiles/manifests/puppet/g10k.pp
@@ -5,40 +5,12 @@
# The latest release of g10k is downloaded from GitHub and placed into '/opt/puppetlabs/bin'.
# Additionally, it creates a helper script to easily run g10k with the appropriate configuration.
# It also creates a systemd service and timer that runs the g10k script every minute.
-#
-# Parameters: None
-#
-# Actions:
-# - Downloads the latest g10k release from GitHub.
-# - Extracts the download and places the executable in '/opt/puppetlabs/bin'.
-# - Creates a helper script '/opt/puppetlabs/bin/puppet-g10k' for easy usage of g10k.
-# - Creates a systemd service and timer that runs the g10k script every minute.
-#
-# Usage:
-# Directly including the class in your node definitions or classify your nodes
-# using an ENC or Hiera.
-# Example:
-# node 'puppet.example.com' {
-# include profiles::puppet::g10k
-# }
-#
-# Requirements:
-# - The 'puppet-archive' module should be installed in your puppetmaster.
-# - The 'puppet-systemd' module should be installed on your puppetmaster.
-# - '/opt/puppetlabs/bin/' directory must exist and be writable.
-# - Puppet master must have access to the GitHub URL.
-#
-# Limitations:
-# This is designed to work on Unix-like systems only.
class profiles::puppet::g10k (
String $bin_path,
String $cfg_path,
String $environments_path,
String $default_environment,
){
- package { 'unzip':
- ensure => installed,
- }
archive { '/tmp/g10k.zip':
ensure => present,
@@ -47,6 +19,7 @@ class profiles::puppet::g10k (
extract_path => '/opt/puppetlabs/bin',
creates => '/opt/puppetlabs/bin/g10k',
cleanup => true,
+ require => Package['unzip']
}
file { '/opt/puppetlabs/bin/puppet-g10k':
diff --git a/site/profiles/manifests/puppet/gems.pp b/site/profiles/manifests/puppet/gems.pp
new file mode 100644
index 0000000..b7a9369
--- /dev/null
+++ b/site/profiles/manifests/puppet/gems.pp
@@ -0,0 +1,12 @@
+# profiles::puppet::gems
+class profiles::puppet::gems (
+ Array $puppet = [],
+){
+ # install puppetmaster gems
+ $puppet.each | $pgem | {
+ package { $pgem:
+ ensure => installed,
+ provider => 'puppet_gem',
+ }
+ }
+}
diff --git a/site/profiles/manifests/puppet/puppetboard.pp b/site/profiles/manifests/puppet/puppetboard.pp
index 0085eb5..08b49aa 100644
--- a/site/profiles/manifests/puppet/puppetboard.pp
+++ b/site/profiles/manifests/puppet/puppetboard.pp
@@ -8,7 +8,7 @@ class profiles::puppet::puppetboard (
Integer $reports_count = 40,
Boolean $offline_mode = true,
String $default_environment = '*',
- String $puppetdb_host = lookup('profiles::puppet::puppetdb::puppetdb_host'),
+ String $puppetdb_host = lookup('puppetdbapi'),
Stdlib::AbsolutePath $basedir = '/opt/puppetboard',
Stdlib::Absolutepath $virtualenv_dir = "${basedir}/venv",
Stdlib::Absolutepath $settings_file = "${basedir}/settings.py",
@@ -18,8 +18,9 @@ class profiles::puppet::puppetboard (
String $gunicorn_bind_prefix = 'http://',
Integer $gunicorn_workers = 1,
Integer $gunicorn_threads = 4,
- String $nginx_vhost = 'puppetboard.main.unkin.net',
- Integer $nginx_port = 80,
+ Stdlib::Port $nginx_port = 80,
+ Stdlib::Host $nginx_vhost = 'puppetboard.main.unkin.net',
+ Array[Stdlib::Host] $nginx_aliases = [],
#String[1] $secret_key = "${fqdn_rand_string(32)}",
) {
@@ -98,10 +99,12 @@ class profiles::puppet::puppetboard (
# ensure the nginx service is managed
class { 'nginx': }
+ $nginx_server_names = unique([$nginx_vhost] + $nginx_aliases)
+
# create the nginx vhost
nginx::resource::server { $nginx_vhost:
listen_port => $nginx_port,
- server_name => [$nginx_vhost],
+ server_name => $nginx_server_names,
proxy => "${gunicorn_bind_prefix}${gunicorn_bind}",
proxy_set_header => [
'Host $http_host',
@@ -120,4 +123,39 @@ class profiles::puppet::puppetboard (
server => $nginx_vhost,
location_alias => "${virtualenv_dir}/lib/python${python_version}/site-packages/puppetboard/static",
}
+
+ # export haproxy balancemember
+ profiles::haproxy::balancemember { "${facts['networking']['fqdn']}_${nginx_port}}":
+ service => 'be_puppetboard',
+ ports => [$nginx_port],
+ options => [
+ "cookie ${facts['networking']['hostname']}",
+ 'check',
+ 'inter 2s',
+ 'rise 3',
+ 'fall 2',
+ ]
+ }
+ #@@haproxy::balancermember { "${facts['networking']['fqdn']}_${nginx_port}}":
+ # listening_service => 'be_puppetboard',
+ # ports => [$nginx_port],
+ # server_names => $facts['networking']['hostname'],
+ # ipaddresses => $facts['networking']['ip'],
+ # options => [
+ # "cookie ${facts['networking']['hostname']}",
+ # 'check',
+ # 'inter 2s',
+ # 'rise 3',
+ # 'fall 2',
+ # ]
+ #}
+
+ # if selinux is defined, manage it
+ if $::facts['os']['selinux']['config_mode'] == 'enforcing' {
+
+ # call the nginx selinux class
+ class { 'profiles::selinux::nginx':
+ require => Class['Nginx'],
+ }
+ }
}
diff --git a/site/profiles/manifests/puppet/puppetca.pp b/site/profiles/manifests/puppet/puppetca.pp
new file mode 100644
index 0000000..e94ecad
--- /dev/null
+++ b/site/profiles/manifests/puppet/puppetca.pp
@@ -0,0 +1,56 @@
+# Class: profiles::puppet::puppetca
+#
+# This class manages Puppet CA
+class profiles::puppet::puppetca (
+ Boolean $allow_subject_alt_names = false,
+ Boolean $allow_authorization_extensions = false,
+ Boolean $enable_infra_crl = false,
+ Boolean $is_puppetca = false,
+) {
+
+ # manage the ca.cfg file
+ file { '/etc/puppetlabs/puppetserver/conf.d/ca.conf':
+ ensure => 'file',
+ owner => 'root',
+ group => 'root',
+ mode => '0644',
+ content => template('profiles/puppet/puppet_ca.cfg.erb'),
+ notify => Service['puppetserver'],
+ }
+
+ # manage the crl file
+ if $is_puppetca {
+ # export the puppet crl.pem
+ @@file { '/etc/puppetlabs/puppet/ssl/crl.pem':
+ ensure => file,
+ content => file('/etc/puppetlabs/puppet/ssl/crl.pem'),
+ tag => 'crl_pem_export',
+ }
+ }else{
+ # import the puppet crl.pem
+ File <<| tag == 'crl_pem_export' |>> {
+ require => Service['puppetserver'],
+ }
+ }
+
+ # register the PuppetCA service with consul
+ if $is_puppetca {
+ consul::service { 'puppetca':
+ service_name => 'puppetca',
+ tags => ['ca', 'puppet', 'ssl'],
+ address => $facts['networking']['ip'],
+ port => 8140,
+ checks => [
+ {
+ id => 'puppetca_https_check',
+ name => 'PuppetCA HTTPS Check',
+ http => "https://${facts['networking']['fqdn']}:8140/status/v1/simple",
+ method => 'GET',
+ tls_skip_verify => true,
+ interval => '10s',
+ timeout => '1s',
+ }
+ ],
+ }
+ }
+}
diff --git a/site/profiles/manifests/puppet/puppetdb_api.pp b/site/profiles/manifests/puppet/puppetdb_api.pp
index fa51753..8c2177e 100644
--- a/site/profiles/manifests/puppet/puppetdb_api.pp
+++ b/site/profiles/manifests/puppet/puppetdb_api.pp
@@ -1,21 +1,45 @@
# configure the puppetdb api service
class profiles::puppet::puppetdb_api (
- String $postgres_host = lookup('profiles::puppet::puppetdb::postgres_host'),
+ String $postgres_host = lookup('puppetdbsql'),
String $listen_address = $facts['networking']['ip'],
+ Stdlib::Absolutepath $java_bin = '/usr/bin/java',
+ Hash $java_args = {},
) {
- class { 'puppetdb::server':
- database_host => $postgres_host,
- manage_firewall => false,
- ssl_listen_address => $listen_address,
- listen_address => $listen_address,
+ # wait for enc_role to match the required role
+ if $facts['enc_role'] == 'roles::infra::puppetdb::api' {
+ class { 'java':
+ package => 'java-11-openjdk-devel',
+ before => Class['puppetdb::server'],
+ }
+
+ class { 'puppetdb::server':
+ database_host => $postgres_host,
+ manage_firewall => false,
+ ssl_listen_address => $listen_address,
+ listen_address => $listen_address,
+ java_bin => $java_bin,
+ java_args => $java_args,
+ }
+
+ contain ::puppetdb::server
+
+ class { 'prometheus::puppetdb_exporter':
+ puppetdb_url => "http://${listen_address}:8080/pdb/query",
+ export_scrape_job => true,
+ }
+
+ # export haproxy balancemember
+ profiles::haproxy::balancemember { "${facts['networking']['fqdn']}_8080":
+ service => 'be_puppetdbapi',
+ ports => [8080],
+ options => [
+ "cookie ${facts['networking']['hostname']}",
+ 'check',
+ 'inter 2s',
+ 'rise 3',
+ 'fall 2',
+ ]
+ }
}
-
- contain ::puppetdb::server
-
- class { 'prometheus::puppetdb_exporter':
- puppetdb_url => "http://${listen_address}:8080/pdb/query",
- export_scrape_job => true,
- }
-
}
diff --git a/site/profiles/manifests/puppet/puppetdb_sql.pp b/site/profiles/manifests/puppet/puppetdb_sql.pp
index 2d80d30..1765003 100644
--- a/site/profiles/manifests/puppet/puppetdb_sql.pp
+++ b/site/profiles/manifests/puppet/puppetdb_sql.pp
@@ -1,6 +1,6 @@
# configure the puppetdb sql service
class profiles::puppet::puppetdb_sql (
- String $puppetdb_host = lookup('profiles::puppet::puppetdb::puppetdb_host'),
+ String $puppetdb_host = lookup('puppetdbsql'),
String $listen_address = $facts['networking']['ip'],
) {
@@ -24,4 +24,12 @@ class profiles::puppet::puppetdb_sql (
contain ::puppetdb::database::postgresql
+ # create the postgresql::server::config_entry resources
+ $pg_config_entries = lookup('postgresql_config_entries', Hash[String, Data], 'hash', {})
+ $pg_config_entries.each |String $key, Data $value| {
+ postgresql::server::config_entry { $key:
+ ensure => 'present',
+ value => $value,
+ }
+ }
}
diff --git a/site/profiles/manifests/puppet/puppetmaster.pp b/site/profiles/manifests/puppet/puppetmaster.pp
index 9819d5e..6ce7ca5 100644
--- a/site/profiles/manifests/puppet/puppetmaster.pp
+++ b/site/profiles/manifests/puppet/puppetmaster.pp
@@ -2,63 +2,37 @@
#
# This class manages the puppetmaster using the ghoneycutt-puppet module.
# It manages the server settings in the puppet.conf file.
-#
-# Parameters: None
-#
-# Actions:
-# - Sets up the server, main, agent, and master sections in the puppet.conf file
-#
-# Usage:
-# Directly include the class in your node definitions or classify your nodes
-# using an ENC or Hiera.
-# Example:
-# node 'puppet.example.com' {
-# include profiles::puppet::puppetmaster
-# }
-#
-# Requirements:
-# - The 'ghoneycutt/puppet' module should be installed in your Puppet master.
-# - Puppet master must have access to the necessary directories.
-#
-# Limitations:
-# This is designed to work on Unix-like systems.
class profiles::puppet::puppetmaster (
- String $puppetdb_host = lookup('profiles::puppet::puppetdb::puppetdb_host'),
+ Optional[Stdlib::Fqdn] $puppetdb_host = lookup('puppetdbapi', Optional[Stdlib::Fqdn], 'first', undef),
) {
- include profiles::puppet::r10k
- include profiles::puppet::g10k
- include profiles::puppet::enc
- include profiles::puppet::autosign
- class { 'puppetdb::master::config':
- puppetdb_server => $puppetdb_host,
- manage_storeconfigs => false,
+ if $facts['enc_role'] == 'roles::infra::puppet::master' {
+
+ include profiles::puppet::r10k
+ include profiles::puppet::g10k
+ include profiles::puppet::enc
+ include profiles::puppet::cobbler_enc
+ include profiles::puppet::autosign
+ include profiles::puppet::gems
+ include profiles::helpers::certmanager
+ include profiles::puppet::server
+ include profiles::puppet::puppetca
+ include profiles::puppet::eyaml
+
+ class { 'puppetdb::master::config':
+ puppetdb_server => $puppetdb_host,
+ manage_storeconfigs => false,
+ }
+
+ Package['puppetserver']
+ -> Class['profiles::puppet::gems']
+ -> Class['profiles::puppet::r10k']
+ -> Class['profiles::puppet::g10k']
+ -> Class['profiles::puppet::enc']
+ -> Class['profiles::puppet::cobbler_enc']
+ -> Class['profiles::puppet::autosign']
+ -> Class['puppetdb::master::config']
+ -> Class['profiles::puppet::server']
}
- class { 'profiles::puppet::server':
- vardir => '/opt/puppetlabs/server/data/puppetserver',
- logdir => '/var/log/puppetlabs/puppetserver',
- rundir => '/var/run/puppetlabs/puppetserver',
- pidfile => '/var/run/puppetlabs/puppetserver/puppetserver.pid',
- codedir => '/etc/puppetlabs/code',
- dns_alt_names => [
- 'prodinf01n01.main.unkin.net',
- 'puppet.main.unkin.net',
- 'puppetca.main.unkin.net',
- 'puppetmaster.main.unkin.net',
- 'puppet',
- 'puppetca',
- 'puppetmaster',
- ],
- server => 'prodinf01n01.main.unkin.net',
- node_terminus => 'exec',
- external_nodes => '/opt/puppetlabs/bin/enc',
- autosign => '/etc/puppetlabs/puppet/autosign.conf',
- default_manifest => '/etc/puppetlabs/code/environments/develop/manifests',
- default_environment => 'develop',
- storeconfigs => true,
- storeconfigs_backend => 'puppetdb',
- reports => 'puppetdb',
- usecacheonfailure => false,
- }
}
diff --git a/site/profiles/manifests/puppet/r10k.pp b/site/profiles/manifests/puppet/r10k.pp
index 402f49a..e366953 100644
--- a/site/profiles/manifests/puppet/r10k.pp
+++ b/site/profiles/manifests/puppet/r10k.pp
@@ -4,41 +4,10 @@
# systemd service and timer to keep the repository updated every minute.
# The Git package is installed if not present, and the repository at the given
# location will always reflect the state of the remote Git repository.
-#
-# Parameters:
-# - r10k_repo: The URL of the Git repository to clone.
-#
-# Actions:
-# - Ensures the Git package is installed.
-# - Ensures the /etc/puppetlabs/r10k directory is a clone of the given Git repository.
-# - Creates a helper script '/opt/puppetlabs/bin/puppet-r10k' for updating the Git repository.
-# - Creates a systemd service and timer that runs the git update script every minute.
-#
-# Usage:
-# Directly include the class in your node definitions or classify your nodes
-# using an enc or Hiera.
-# Example:
-# node 'puppet.example.com' {
-# class { 'profiles::puppet::r10k':
-# r10k_repo => 'https://github.com/user/repo.git',
-# }
-# }
-#
-# Requirements:
-# - The 'puppet-vcsrepo' module should be installed on your puppetmaster.
-# - The 'puppet-systemd' module should be installed on your puppetmaster.
-# - '/opt/puppetlabs/bin/' directory must exist and be writable.
-# - Puppet master must have access to the specified Git URL.
-#
-# Limitations:
-# This is designed to work on Unix-like systems only.
-#
class profiles::puppet::r10k (
String $r10k_repo,
){
- include profiles::packages::git
-
vcsrepo { '/etc/puppetlabs/r10k':
ensure => latest,
provider => git,
diff --git a/site/profiles/manifests/puppet/server.pp b/site/profiles/manifests/puppet/server.pp
index 7f0aec5..771d41a 100644
--- a/site/profiles/manifests/puppet/server.pp
+++ b/site/profiles/manifests/puppet/server.pp
@@ -1,36 +1,33 @@
# Class: profiles::puppet::server
#
# This class manages Puppet server's configuration and service.
-#
-# Parameters:
-# vardir - Directory path for variable data.
-# logdir - Directory path for logs.
-# rundir - Directory path for run-time data.
-# pidfile - File path for the PID file.
-# codedir - Directory path for code data.
-# dns_alt_names - Array of alternate DNS names for the server.
-# server - Server's name.
-# node_terminus - Node terminus.
-# external_nodes - Path to the external node classifier script.
-# autosign - Path to the autosign script.
-#
class profiles::puppet::server (
- String $vardir,
- String $logdir,
- String $rundir,
- String $pidfile,
- String $codedir,
- Array[String[1]] $dns_alt_names,
- String $server,
- String $node_terminus,
- String $external_nodes,
- String $autosign,
- String $default_manifest,
- String $default_environment,
- Boolean $storeconfigs,
- String $storeconfigs_backend,
- String $reports,
- Boolean $usecacheonfailure,
+ Stdlib::Absolutepath $vardir = '/opt/puppetlabs/server/data/puppetserver',
+ Stdlib::Absolutepath $logdir = '/var/log/puppetlabs/puppetserver',
+ Stdlib::Absolutepath $rundir = '/var/run/puppetlabs/puppetserver',
+ Stdlib::Absolutepath $pidfile = '/var/run/puppetlabs/puppetserver/puppetserver.pid',
+ Stdlib::Absolutepath $codedir = '/etc/puppetlabs/code',
+ Array[String] $dns_alt_names = [
+ $facts['networking']['fqdn'],
+ $facts['networking']['hostname'],
+ ],
+ Stdlib::Fqdn $agent_server = 'puppetmaster',
+ Stdlib::Fqdn $report_server = $agent_server,
+ Stdlib::Fqdn $ca_server = 'puppetca',
+ String $node_terminus = 'exec',
+ String $external_nodes = '/opt/cobbler-enc/cobbler-enc',
+ String $default_environment = 'develop',
+ String $environment = 'develop',
+ Stdlib::Absolutepath $autosign = '/etc/puppetlabs/puppet/autosign.conf',
+ Stdlib::Absolutepath $default_manifest = "${codedir}/environments/${default_environment}/manifests",
+ String $reports = 'puppetdb',
+ Boolean $storeconfigs = true,
+ String $storeconfigs_backend = 'puppetdb',
+ Boolean $usecacheonfailure = false,
+ Boolean $report = true,
+ Integer $runinterval = 1800,
+ Integer $runtimeout = 3600,
+ Boolean $show_diff = true,
) {
file { '/etc/puppetlabs/puppet/puppet.conf':
@@ -44,8 +41,15 @@ class profiles::puppet::server (
'rundir' => $rundir,
'pidfile' => $pidfile,
'codedir' => $codedir,
- 'dns_alt_names' => join($dns_alt_names, ','),
- 'server' => $server,
+ 'dns_alt_names' => join(sort($dns_alt_names), ','),
+ 'server' => $agent_server,
+ 'ca_server' => $ca_server,
+ 'environment' => $environment,
+ 'report' => $report,
+ 'runinterval' => $runinterval,
+ 'runtimeout' => $runtimeout,
+ 'show_diff' => $show_diff,
+ 'report_server' => $report_server,
'node_terminus' => $node_terminus,
'external_nodes' => $external_nodes,
'autosign' => $autosign,
@@ -66,4 +70,3 @@ class profiles::puppet::server (
hasrestart => true,
}
}
-
diff --git a/site/profiles/manifests/reposync/autosyncer.pp b/site/profiles/manifests/reposync/autosyncer.pp
index 04393cd..5271ec2 100644
--- a/site/profiles/manifests/reposync/autosyncer.pp
+++ b/site/profiles/manifests/reposync/autosyncer.pp
@@ -10,7 +10,7 @@ class profiles::reposync::autosyncer (
group => 'root',
mode => '0755',
content => template('profiles/reposync/autosyncer.erb'),
- require => Class['profiles::packages::reposync'],
+ require => Package['createrepo'],
}
# daily autosyncr service/timer
diff --git a/site/profiles/manifests/reposync/repos.pp b/site/profiles/manifests/reposync/repos.pp
index 046e404..0be17f7 100644
--- a/site/profiles/manifests/reposync/repos.pp
+++ b/site/profiles/manifests/reposync/repos.pp
@@ -4,7 +4,7 @@ define profiles::reposync::repos (
String $description,
String $osname,
String $release,
- Stdlib::HTTPUrl $gpgkey,
+ Stdlib::Filesource $gpgkey,
String $arch = 'x86_64',
String $repo_owner = 'root',
String $repo_group = 'root',
diff --git a/site/profiles/manifests/reposync/syncer.pp b/site/profiles/manifests/reposync/syncer.pp
index 6f20996..3be81d8 100644
--- a/site/profiles/manifests/reposync/syncer.pp
+++ b/site/profiles/manifests/reposync/syncer.pp
@@ -1,7 +1,6 @@
# setup a reposync syncer
class profiles::reposync::syncer {
- include profiles::packages::reposync
include profiles::reposync::autosyncer
include profiles::reposync::autopromoter
include profiles::reposync::webserver
@@ -14,10 +13,13 @@ class profiles::reposync::syncer {
mode => '0755',
}
file { '/etc/reposync/conf.d':
- ensure => directory,
- owner => 'root',
- group => 'root',
- mode => '0755',
+ ensure => directory,
+ owner => 'root',
+ group => 'root',
+ mode => '0755',
+ purge => true,
+ recurse => true,
+ force => true,
}
# get a list of repos as a hash, and iterate through them
diff --git a/site/profiles/manifests/reposync/webserver.pp b/site/profiles/manifests/reposync/webserver.pp
index 9321db1..b75782d 100644
--- a/site/profiles/manifests/reposync/webserver.pp
+++ b/site/profiles/manifests/reposync/webserver.pp
@@ -1,23 +1,120 @@
# setup a reposync webserver
class profiles::reposync::webserver (
String $www_root = '/data/repos/snap',
+ String $cache_root = '/data/repos/cache',
String $nginx_vhost = 'repos.main.unkin.net',
- Integer $nginx_port = 80,
+ Stdlib::Port $nginx_port = 80,
+ Stdlib::Port $nginx_ssl_port = 443,
Boolean $favicon = true,
- Boolean $selinux = true,
+ Enum['http','https','both'] $nginx_listen_mode = 'http',
+ Enum['puppet', 'vault'] $nginx_cert_type = 'vault'
) {
- class { 'nginx': }
+ # 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
+ }
+ }
- # create the nginx vhost
- nginx::resource::server { $nginx_vhost:
- listen_port => $nginx_port,
- server_name => [$nginx_vhost],
- use_default_location => true,
- access_log => "/var/log/nginx/${nginx_vhost}_access.log",
- error_log => "/var/log/nginx/${nginx_vhost}_error.log",
- www_root => $www_root,
- autoindex => 'on',
+ # 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
+ }
+ }
+
+ # define the default parameters for the nginx server
+ $defaults = {
+ 'listen_port' => $listen_port,
+ 'server_name' => [$nginx_vhost],
+ 'use_default_location' => true,
+ 'access_log' => "/var/log/nginx/${nginx_vhost}_access.log",
+ 'error_log' => "/var/log/nginx/${nginx_vhost}_error.log",
+ 'www_root' => $www_root,
+ 'autoindex' => 'on',
+ 'ssl' => $enable_ssl,
+ 'ssl_cert' => $ssl_cert,
+ 'ssl_key' => $ssl_key,
+ 'ssl_port' => $listen_ssl_port,
+ }
+
+ # merge the hashes conditionally
+ $nginx_parameters = merge($defaults, $extras_hash)
+
+ # manage the nginx class
+ class { 'nginx':
+ proxy_cache_path => {
+ "${cache_root}/debian" => 'debian:128m',
+ },
+ proxy_cache_levels => '1:2',
+ proxy_cache_keys_zone => 'debian:128m',
+ proxy_cache_max_size => '30000m',
+ proxy_cache_inactive => '60d',
+ proxy_temp_path => "${cache_root}/tmp",
+ }
+
+ # create the nginx vhost with the merged parameters
+ create_resources('nginx::resource::server', { $nginx_vhost => $nginx_parameters })
+
+ # cache debian packages from upstream
+ nginx::resource::location { "${nginx_vhost}-debian":
+ ensure => present,
+ ssl => true,
+ ssl_only => false,
+ location => '/debian',
+ server => $nginx_vhost,
+ proxy => 'http://mirror.gsl.icu/debian',
+ }
+
+ nginx::resource::location { "${nginx_vhost}-debian_pool":
+ ensure => present,
+ ssl => true,
+ ssl_only => false,
+ location => '/debian/pool',
+ server => $nginx_vhost,
+ proxy => 'http://mirror.gsl.icu/debian/pool',
+ proxy_cache => 'debian',
+ proxy_cache_valid => [
+ '200 302 1440h',
+ '404 1m'
+ ],
}
if $favicon {
@@ -39,10 +136,7 @@ class profiles::reposync::webserver (
order => 10,
}
- if $selinux {
-
- # include packages that are required
- include profiles::packages::selinux
+ if $::facts['os']['selinux']['config_mode'] == 'enforcing' {
# set httpd_sys_content_t to all files under the www_root
selinux::fcontext { $www_root:
@@ -51,6 +145,13 @@ class profiles::reposync::webserver (
pathspec => "${www_root}(/.*)?",
}
+ # set httpd_sys_rw_content_t to all files under the cache_root
+ selinux::fcontext { $cache_root:
+ ensure => 'present',
+ seltype => 'httpd_sys_rw_content_t',
+ pathspec => "${cache_root}(/.*)?",
+ }
+
# make sure we can connect to port 80
selboolean { 'httpd_can_network_connect':
persistent => true,
@@ -63,5 +164,12 @@ class profiles::reposync::webserver (
refreshonly => true,
subscribe => Selinux::Fcontext[$www_root],
}
+
+ exec { "restorecon_${cache_root}":
+ path => ['/bin', '/usr/bin', '/sbin', '/usr/sbin'],
+ command => "restorecon -Rv ${cache_root}",
+ refreshonly => true,
+ subscribe => Selinux::Fcontext[$cache_root],
+ }
}
}
diff --git a/site/profiles/manifests/selinux/mysqld.pp b/site/profiles/manifests/selinux/mysqld.pp
index 2c31e82..8a5d3b0 100644
--- a/site/profiles/manifests/selinux/mysqld.pp
+++ b/site/profiles/manifests/selinux/mysqld.pp
@@ -7,8 +7,6 @@ class profiles::selinux::mysqld (
Boolean $selinuxuser_mysql_connect_enabled = true,
String $selinux_mode = 'enforcing',
){
- # include packages that are required
- include profiles::packages::selinux
# setenforce
class { 'profiles::selinux::setenforce':
diff --git a/site/profiles/manifests/selinux/nginx.pp b/site/profiles/manifests/selinux/nginx.pp
new file mode 100644
index 0000000..25d47f6
--- /dev/null
+++ b/site/profiles/manifests/selinux/nginx.pp
@@ -0,0 +1,20 @@
+# profiles::selinux::nginx
+# selinux settings for nginx
+class profiles::selinux::nginx (
+ Boolean $persistent = true,
+ Boolean $httpd_can_network_connect = true,
+ String $selinux_mode = 'enforcing',
+){
+
+ # setenforce
+ class { 'profiles::selinux::setenforce':
+ mode => $selinux_mode,
+ }
+
+ # make sure we can connect to network resources
+ selboolean { 'httpd_can_network_connect':
+ persistent => $persistent,
+ value => $httpd_can_network_connect,
+ }
+}
+
diff --git a/site/profiles/manifests/selinux/setenforce.pp b/site/profiles/manifests/selinux/setenforce.pp
index fa2c753..309ea71 100644
--- a/site/profiles/manifests/selinux/setenforce.pp
+++ b/site/profiles/manifests/selinux/setenforce.pp
@@ -3,7 +3,8 @@ class profiles::selinux::setenforce (
Enum['enforcing', 'permissive', 'disabled'] $mode = 'enforcing',
) {
class { 'selinux':
- mode => $mode,
+ mode => $mode,
+ require => Package['policycoreutils']
}
}
diff --git a/site/profiles/manifests/sql/galera_member.pp b/site/profiles/manifests/sql/galera_member.pp
index d79c28a..24fab57 100644
--- a/site/profiles/manifests/sql/galera_member.pp
+++ b/site/profiles/manifests/sql/galera_member.pp
@@ -30,7 +30,6 @@ class profiles::sql::galera_member (
Boolean $package_manage = true,
String $package_name = 'mariadb-server',
Boolean $epel_needed = false,
- Boolean $selinux = true,
Boolean $manage_repo = true,
) {
@@ -48,7 +47,7 @@ class profiles::sql::galera_member (
}
# if it is, find hosts, sort them so they dont cause changes every run
- $servers_array = sort(query_nodes("enc_role='${galera_members_role}'", 'networking.fqdn'))
+ $servers_array = sort(query_nodes("enc_role='${galera_members_role}' and region='${facts['region']}'", 'networking.fqdn'))
# else use provided array from params
}else{
@@ -59,10 +58,10 @@ class profiles::sql::galera_member (
if length($servers_array) >= 3 {
# if selinux is defined, manage it
- if $selinux {
+ if $::facts['os']['selinux']['config_mode'] == 'enforcing' {
# set permissive on first run, as we need mariadb installed/started at a custom path before adding fcontext
- if $::facts['mariadb_acti'] { $selinux_mode = 'enforcing' }else{ $selinux_mode = 'permissive' }
+ if $::facts['mariadb_active'] { $selinux_mode = 'enforcing' }else{ $selinux_mode = 'permissive' }
# call the mysqld selinux class
class { 'profiles::selinux::mysqld':
@@ -104,7 +103,8 @@ class profiles::sql::galera_member (
'binlog_format' => 'ROW',
'default-storage-engine' => 'innodb',
'query_cache_size' => '0',
- 'query_cache_type' => '0'
+ 'query_cache_type' => '0',
+ 'bind-address' => $local_ip,
}
}
$default_override_options_galera = {
@@ -212,4 +212,5 @@ class profiles::sql::galera_member (
}else{
notice("${title} requires the servers_array to have 3 or more, currently it is ${length($servers_array)}.")
}
+
}
diff --git a/site/profiles/manifests/storage/datavol.pp b/site/profiles/manifests/storage/datavol.pp
new file mode 100644
index 0000000..ecc9a9d
--- /dev/null
+++ b/site/profiles/manifests/storage/datavol.pp
@@ -0,0 +1,75 @@
+# profiles::storage::datavol
+#
+# This define manages the creation of a logical volume using the `lvm::volume` definition.
+#
+# Parameters:
+# $ensure - Ensure whether the logical volume is present or not. Defaults to 'present'.
+# $vg - Volume group name. No default.
+# $pv - Physical volume, typically the disk or partition device path. No default.
+# $fstype - Filesystem type for the logical volume. Defaults to 'ext3'.
+# $size - Size of the logical volume. undef = 100%FREE. Changing $size to cause a resize.
+#
+define profiles::storage::datavol (
+ Enum['present', 'absent'] $ensure = 'present',
+ Enum['ext2', 'ext3', 'ext4', 'xfs', 'btrfs'] $fstype = 'xfs',
+ String $vg = 'datavg',
+ String $pv = '/dev/vdb',
+ String $lv = 'data',
+ String $owner = 'root',
+ String $group = 'root',
+ Stdlib::Filemode $mode = '0755',
+ Stdlib::Absolutepath $mount = '/data',
+ Optional[Variant[Pattern[/^\d+(M|G|T|P)$/], Integer]] $size = undef,
+ Array[Enum[
+ 'defaults', 'ro', 'rw', 'sync', 'async',
+ 'noatime', 'nodiratime', 'noexec', 'nosuid',
+ 'nodev', 'remount', 'auto', 'noauto'
+ ]] $mount_options = ['noatime', 'nodiratime'],
+) {
+
+ # Ensure the physical volume exists
+ physical_volume { $pv:
+ ensure => $ensure,
+ before => Volume_group[$vg],
+ }
+
+ # Ensure the volume group exists
+ volume_group { $vg:
+ ensure => $ensure,
+ physical_volumes => [$pv],
+ before => Logical_volume[$lv],
+ }
+
+ # Ensure the logical volume exists
+ logical_volume { $lv:
+ ensure => $ensure,
+ volume_group => $vg,
+ size => $size,
+ before => Filesystem["/dev/${vg}/${lv}"],
+ }
+
+ # Ensure the filesystem is created on the logical volume
+ filesystem { "/dev/${vg}/${lv}":
+ ensure => $ensure,
+ fs_type => $fstype,
+ require => Logical_volume[$lv],
+ before => Mount[$mount],
+ }
+
+ # Ensure the mountpath exists
+ file { $mount:
+ ensure => directory,
+ owner => $owner,
+ group => $group,
+ mode => $mode,
+ }
+
+ # Ensure the logical volume is mounted at the desired location
+ mount { $mount:
+ ensure => $ensure,
+ device => "/dev/${vg}/${lv}",
+ fstype => $fstype,
+ options => $mount_options.join(','),
+ require => Filesystem["/dev/${vg}/${lv}"],
+ }
+}
diff --git a/site/profiles/manifests/vault/server.pp b/site/profiles/manifests/vault/server.pp
new file mode 100644
index 0000000..d07e8ba
--- /dev/null
+++ b/site/profiles/manifests/vault/server.pp
@@ -0,0 +1,92 @@
+# profiles::vault::server
+class profiles::vault::server (
+ Boolean $members_lookup = false,
+ Variant[
+ String,
+ Undef
+ ] $members_role = undef,
+ Array $vault_servers = [],
+ Enum[
+ 'archive',
+ 'repo'
+ ] $install_method = 'archive',
+ Boolean $tls_disable = false,
+ Stdlib::Port $client_port = 8200,
+ Stdlib::Port $cluster_port = 8201,
+ Boolean $manage_storage_dir = false,
+ Stdlib::Absolutepath $data_dir = '/opt/vault',
+ Stdlib::Absolutepath $bin_dir = '/usr/bin',
+){
+
+ # set a datacentre/cluster name
+ $vault_cluster = "${::facts['country']}-${::facts['region']}"
+
+ # if lookup is enabled, find all the hosts in the specified role and create the servers_array
+ if $members_lookup and $members_role != undef {
+
+ # if it is, find hosts, sort them so they dont cause changes every run
+ $servers_array = sort(query_nodes("enc_role='${members_role}' and region='${::facts['region']}'", 'networking.fqdn'))
+
+ # else use provided array from params
+ }else{
+ $servers_array = $vault_servers
+ }
+
+ # configure vault if servers_array isnt empty
+ if ! $servers_array.empty() {
+
+ # set http scheme
+ $http_scheme = $tls_disable ? {
+ true => 'http',
+ false => 'https'
+ }
+
+ # create vault urls
+ $server_urls = $servers_array.map |$fqdn| {
+ {
+ leader_api_addr => "${http_scheme}://${fqdn}:${client_port}",
+ leader_client_cert_file => '/etc/pki/tls/vault/certificate.crt',
+ leader_client_key_file => '/etc/pki/tls/vault/private.key',
+ leader_ca_cert_file => '/etc/pki/tls/certs/ca-bundle.crt',
+ }
+ }
+
+ class { 'vault':
+ install_method => $install_method,
+ manage_storage_dir => $manage_storage_dir,
+ enable_ui => true,
+ storage => {
+ raft => {
+ node_id => $::facts['networking']['fqdn'],
+ path => $data_dir,
+ retry_join => $server_urls,
+ }
+ },
+ api_addr => "${http_scheme}://${::facts['networking']['fqdn']}:${client_port}",
+ extra_config => {
+ cluster_addr => "${http_scheme}://${::facts['networking']['fqdn']}:${cluster_port}",
+ },
+ listener => [
+ {
+ tcp => {
+ address => "127.0.0.1:${client_port}",
+ cluster_address => "127.0.0.1:${cluster_port}",
+ tls_disable => true,
+ }
+ },
+ {
+ tcp => {
+ address => "${::facts['networking']['ip']}:${client_port}",
+ cluster_address => "${::facts['networking']['ip']}:${cluster_port}",
+ tls_disable => $tls_disable,
+ tls_cert_file => '/etc/pki/tls/vault/certificate.crt',
+ tls_key_file => '/etc/pki/tls/vault/private.key',
+ }
+ }
+ ]
+ }
+
+ # include classes to manage vault
+ include profiles::vault::unseal
+ }
+}
diff --git a/site/profiles/manifests/vault/unseal.pp b/site/profiles/manifests/vault/unseal.pp
new file mode 100644
index 0000000..cff32a1
--- /dev/null
+++ b/site/profiles/manifests/vault/unseal.pp
@@ -0,0 +1,37 @@
+# profiles::vault::unseal
+class profiles::vault::unseal (
+ Array[String] $unseal_keys = lookup('vault::unseal_keys', Array[String], 'first', []),
+ Variant[
+ Stdlib::HTTPSUrl,
+ Stdlib::HTTPUrl
+ ] $vault_address = 'http://127.0.0.1:8200',
+){
+
+ # deploy the unseal keys file
+ file { '/etc/vault/unseal_keys':
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0600',
+ content => Sensitive(template('profiles/vault/unseal_keys.erb')),
+ require => Class['vault'],
+ }
+
+ # deploy the unseal script
+ file { '/usr/local/bin/vault-unseal.sh':
+ ensure => file,
+ owner => 'root',
+ group => 'root',
+ mode => '0750',
+ content => template('profiles/vault/vault_unseal.sh.erb'),
+ }
+
+ # create systemd service unit
+ systemd::unit_file { 'vault-unseal.service':
+ content => template('profiles/vault/vault-unseal.service.erb'),
+ active => true,
+ enable => true,
+ require => File['/usr/local/bin/vault-unseal.sh'],
+ subscribe => [Service['vault'],File['/etc/vault/unseal_keys']],
+ }
+}
diff --git a/site/profiles/manifests/yum/base.pp b/site/profiles/manifests/yum/base.pp
deleted file mode 100644
index df86cd0..0000000
--- a/site/profiles/manifests/yum/base.pp
+++ /dev/null
@@ -1,92 +0,0 @@
-# Class: profiles::yum::base
-#
-# This class manages the 'base', extras' and 'appstream' yum
-# repositories for a system, based on the provided list of managed repositories.
-#
-# Parameters:
-# -----------
-# - $managed_repos: An array containing the names of the repositories to be
-# managed. This can include 'base', 'extras',
-# and 'appstream'.
-#
-# - $baseurl: The base URL for the yum repositories. This should be the root
-# URL of your yum mirror server.
-#
-# Actions:
-# --------
-# - Sets up the 'base', extras', and 'appstream' yum repositories
-# as specified in the $managed_repos parameter, all using the provided baseurl.
-#
-# - Each repo configuration includes the baseurl parameterized with the OS
-# release version and architecture, and specifies the GPG key.
-#
-# Example usage:
-# --------------
-# To use this class with the default parameters:
-# class { 'profiles::yum::base':
-# managed_repos => ['base', 'extras', 'appstream'],
-# baseurl => 'http://mylocalmirror.com/yum',
-# }
-#
-class profiles::yum::base (
- Array[String] $managed_repos,
- String $baseurl,
- Enum[
- 'daily',
- 'weekly',
- 'monthly'
- ] $snapshot = 'daily',
-) {
- $release = $facts['os']['release']['full']
- $basearch = $facts['os']['architecture']
-
- if 'base' in $managed_repos {
- yumrepo { 'base':
- name => 'base',
- descr => 'base repository',
- target => '/etc/yum.repos.d/base.repo',
- baseurl => "${baseurl}/${release}/BaseOS-${snapshot}/${basearch}/os/",
- gpgkey => "${baseurl}/${release}/BaseOS-${snapshot}/${basearch}/os/RPM-GPG-KEY-${facts['os']['name']}",
- }
- }
-
- if 'extras' in $managed_repos {
- yumrepo { 'extras':
- name => 'extras',
- descr => 'extras repository',
- target => '/etc/yum.repos.d/extras.repo',
- baseurl => "${baseurl}/${release}/extras-${snapshot}/${basearch}/os/",
- gpgkey => "${baseurl}/${release}/extras-${snapshot}/${basearch}/os/RPM-GPG-KEY-${facts['os']['name']}",
- }
- }
-
- if 'appstream' in $managed_repos {
- yumrepo { 'appstream':
- name => 'appstream',
- descr => 'appstream repository',
- target => '/etc/yum.repos.d/appstream.repo',
- baseurl => "${baseurl}/${release}/AppStream-${snapshot}/${basearch}/os/",
- gpgkey => "${baseurl}/${release}/AppStream-${snapshot}/${basearch}/os/RPM-GPG-KEY-${facts['os']['name']}",
- }
- }
-
- if 'powertools' in $managed_repos {
- yumrepo { 'powertools':
- name => 'powertools',
- descr => 'powertools repository',
- target => '/etc/yum.repos.d/powertools.repo',
- baseurl => "${baseurl}/${release}/PowerTools-${snapshot}/${basearch}/os/",
- gpgkey => "${baseurl}/${release}/PowerTools-${snapshot}/${basearch}/os/RPM-GPG-KEY-${facts['os']['name']}",
- }
- }
-
- if 'highavailability' in $managed_repos {
- yumrepo { 'highavailability':
- name => 'highavailability',
- descr => 'highavailability repository',
- target => '/etc/yum.repos.d/highavailability.repo',
- baseurl => "${baseurl}/${release}/HighAvailability-${snapshot}/${basearch}/os/",
- gpgkey => "${baseurl}/${release}/HighAvailability-${snapshot}/${basearch}/os/RPM-GPG-KEY-${facts['os']['name']}",
- }
- }
-}
diff --git a/site/profiles/manifests/yum/epel.pp b/site/profiles/manifests/yum/epel.pp
deleted file mode 100644
index 575e099..0000000
--- a/site/profiles/manifests/yum/epel.pp
+++ /dev/null
@@ -1,48 +0,0 @@
-# Class: profiles::yum::epel
-#
-# This class manages the EPEL yum repository for the system.
-#
-# Parameters:
-# -----------
-# - $baseurl: The base URL for the EPEL yum repository. This should be the root
-# URL of your EPEL mirror server.
-#
-# Actions:
-# --------
-# - Checks the OS release version.
-#
-# - If the release version is 7, 8, or 9, it sets up the 'epel' yum repository
-#
-# - If the release version is not supported, it raises an error.
-#
-# Example usage:
-# --------------
-# To use this class with the default parameters:
-# include profiles::yum::epel
-#
-# To specify a custom base URL:
-# class { 'profiles::yum::epel':
-# baseurl => 'http://mylocalmirror.com/yum',
-# }
-class profiles::yum::epel (
- Array[String] $managed_repos,
- String $baseurl,
- Enum[
- 'daily',
- 'weekly',
- 'monthly'
- ] $snapshot = 'daily',
-) {
- $release = $facts['os']['release']['major']
- $basearch = $facts['os']['architecture']
-
- if 'epel' in $managed_repos {
- yumrepo { 'epel':
- name => 'epel',
- descr => 'epel repository',
- target => '/etc/yum.repos.d/epel.repo',
- baseurl => "${baseurl}/${release}/Everything-${snapshot}/${basearch}/os/",
- gpgkey => "${baseurl}/${release}/Everything-${snapshot}/${basearch}/os/RPM-GPG-KEY-EPEL-${release}",
- }
- }
-}
diff --git a/site/profiles/manifests/yum/global.pp b/site/profiles/manifests/yum/global.pp
index 119230e..a9fbef5 100644
--- a/site/profiles/manifests/yum/global.pp
+++ b/site/profiles/manifests/yum/global.pp
@@ -1,48 +1,7 @@
# Class: profiles::yum::global
-#
-# This class manages global YUM configurations and optionally includes the
-# base and EPEL yum repository profiles based on the content of the
-# $managed_repos parameter, which is an array of repository names.
-#
-# Parameters:
-# -----------
-# - $managed_repos: An array of repository names that the Puppet agent should
-# manage. This parameter is mandatory and the class will
-# fail if it is not provided via hieradata.
-# Example: ['base', 'updates', 'extras', 'appstream']
-#
-# Actions:
-# --------
-# - Configures global YUM settings, including keeping the kernel development
-# packages and cleaning old kernels.
-#
-# - Establishes default parameters for any YUM repositories managed by Puppet.
-# This includes the repository file location, the repository description,
-# and enabling the repository and GPG checks.
-#
-# - Depending on the content of the $managed_repos parameter, it includes the
-# profiles::yum::base and/or profiles::yum::epel classes.
-#
-# - Manages all .repo files under /etc/yum.repos.d. All the repositories listed
-# in $managed_repos will have their corresponding .repo files preserved. Any
-# .repo file that is not listed in $managed_repos will be removed.
-#
-# - Creates and maintains a /etc/yum.repos.d/.managed file that lists all the
-# .repo files that should be managed by Puppet.
-#
-# Example usage:
-# --------------
-# To use this class, include the class and configure hieradata:
-# include profiles::yum::global
-#
-# profiles::yum::managed_repos:
-# - 'base'
-# - 'extras'
-# - 'appstream'
-#
class profiles::yum::global (
- Array[String] $managed_repos = lookup('profiles::yum::managed_repos'),
- Boolean $purge = true,
+ Hash $repos = {},
+ Boolean $purge = true,
){
class { 'yum':
keep_kernel_devel => true,
@@ -52,39 +11,34 @@ class profiles::yum::global (
},
}
- Yumrepo {
- ensure => 'present',
- enabled => 1,
- gpgcheck => 1,
- mirrorlist => 'absent',
- }
-
+ # purge all yum repos not defined by puppet
resources { 'yumrepo':
purge => $purge,
}
- # Generate the content for the .managed file
- $managed_file_content = $managed_repos.map |$repo_name| { "${repo_name}.repo" }.join("\n")
+ # download all gpg keys if a repo defines it
+ $repos.each |$name, $repo| {
+ if $repo['gpgkey'] {
+ $key_url = $repo['gpgkey']
+ $key_file = "/etc/pki/rpm-gpg/${name}-gpg-key"
- # Create the .managed file
- file { '/etc/yum.repos.d/.managed':
- ensure => file,
- content => $managed_file_content,
+ exec { "download_gpg_key_${name}":
+ command => "curl -s -o ${key_file} ${key_url} && rpm --import ${key_file}",
+ path => ['/bin', 'usr/bin'],
+ creates => $key_file,
+ before => Yumrepo[$name],
+ }
+ }
}
- # Setup base repos
- class { 'profiles::yum::base':
- managed_repos => $managed_repos,
- }
+ # create repos
+ create_resources('yumrepo', $repos)
- # Setup epel if included in managed_repos
- class { 'profiles::yum::epel':
- managed_repos => $managed_repos,
- }
-
- # Setup puppet7 if included in managed_repos
- class { 'profiles::yum::puppet7':
- managed_repos => $managed_repos,
+ # makecache if changes made to repos
+ exec {'dnf_makecache':
+ command => 'dnf makecache -q',
+ path => ['/usr/bin', '/bin'],
+ refreshonly => true,
}
# setup dnf-autoupdate
diff --git a/site/profiles/manifests/yum/mariadb.pp b/site/profiles/manifests/yum/mariadb.pp
deleted file mode 100644
index df3d71e..0000000
--- a/site/profiles/manifests/yum/mariadb.pp
+++ /dev/null
@@ -1,24 +0,0 @@
-# Class: profiles::yum::mariadb
-#
-# This class manages the mariadb yum repository for the system.
-#
-class profiles::yum::mariadb (
- String $baseurl = 'http://repos.main.unkin.net',
- String $version = '11.2',
- Enum[
- 'daily',
- 'weekly',
- 'monthly'
- ] $snapshot = 'daily',
-) {
- $release = $facts['os']['release']['major']
- $basearch = $facts['os']['architecture']
-
- yumrepo { 'mariadb':
- name => 'mariadb',
- descr => 'mariadb repository',
- target => '/etc/yum.repos.d/mariadb.repo',
- baseurl => "${baseurl}/mariadb/${version}/el${release}-${snapshot}/${basearch}/os/",
- gpgkey => "${baseurl}/mariadb/${version}/el${release}-${snapshot}/${basearch}/os/RPM-GPG-KEY-MariaDB",
- }
-}
diff --git a/site/profiles/manifests/yum/puppet7.pp b/site/profiles/manifests/yum/puppet7.pp
deleted file mode 100644
index 2733ff2..0000000
--- a/site/profiles/manifests/yum/puppet7.pp
+++ /dev/null
@@ -1,58 +0,0 @@
-# Class: profiles::yum::epel
-#
-# This class manages the puppet7 yum repository for the system.
-#
-# Parameters:
-# -----------
-# - $baseurl: The base URL for the puppet7 yum repository. This should be the root
-# URL of your puppet7 mirror server.
-#
-# Actions:
-# --------
-# - Checks the OS release version.
-#
-# - If the release version is 7, 8, or 9, it sets up the 'puppet7' yum repository
-# and installs the puppet7 release RPM from the provided baseurl.
-#
-# - If the release version is not supported, it raises an error.
-#
-# - The repo configuration includes the baseurl parameterized with the OS
-# release version and architecture, and specifies the GPG key.
-#
-# Example usage:
-# --------------
-# To use this class with the default parameters:
-# include profiles::yum::puppet7
-#
-# To specify a custom base URL:
-# class { 'profiles::yum::puppet7':
-# baseurl => 'http://mylocalmirror.com/yum',
-# }
-class profiles::yum::puppet7 (
- Array[String] $managed_repos,
- String $baseurl = 'http://yum.puppet.com',
-) {
- $releasever = $facts['os']['release']['major']
- $basearch = $facts['os']['architecture']
-
- if 'puppet7' in $managed_repos {
- if ($releasever in [7,8,9]) {
- $source = "${baseurl}/puppet7-release-el-${releasever}.noarch.rpm"
-
- yum::install { 'puppet-release-el':
- ensure => present,
- source => $source,
- }
- } else {
- err("Unsupported OS release ${releasever}")
- }
-
- yumrepo { 'puppet7':
- name => 'puppet7',
- descr => 'puppet7 repository',
- target => '/etc/yum.repos.d/puppet7.repo',
- baseurl => "${baseurl}/puppet/el/${releasever}/${basearch}/",
- gpgkey => "${baseurl}/RPM-GPG-KEY-puppet",
- }
- }
-}
diff --git a/site/profiles/templates/base/facts/custom_facts.yaml.erb b/site/profiles/templates/base/facts/custom_facts.yaml.erb
new file mode 100644
index 0000000..e4b3895
--- /dev/null
+++ b/site/profiles/templates/base/facts/custom_facts.yaml.erb
@@ -0,0 +1,3 @@
+---
+enc_role: <%= @enc_role[0] %>
+enc_env: <%= @enc_env %>
diff --git a/site/profiles/templates/base/hosts.erb b/site/profiles/templates/base/hosts.erb
index 45bf0d2..c41ef08 100644
--- a/site/profiles/templates/base/hosts.erb
+++ b/site/profiles/templates/base/hosts.erb
@@ -1,15 +1,10 @@
# /etc/hosts file managed by Puppet
# The following lines are desirable for IPv4 capable hosts
-127.0.0.1 <%= @fqdn %> <%= @hostname %>
+<%= @facts['networking']['ip'] %> <%= @fqdn %> <%= @hostname %>
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4
-# The following lines are desirable for IPv6 capable hosts
-::1 <%= @fqdn %> <%= @hostname %>
-::1 localhost.localdomain localhost
-::1 localhost6.localdomain6 localhost6
-
<% @additional_hosts.each do |host| -%>
<%= host['ip'] %> <%= host['hostname'] %> <%= host['aliases'].join(' ') if host['aliases'] %>
<% end -%>
diff --git a/site/profiles/templates/base/motd/motd.erb b/site/profiles/templates/base/motd/motd.erb
index 7ca06df..6e2f7df 100644
--- a/site/profiles/templates/base/motd/motd.erb
+++ b/site/profiles/templates/base/motd/motd.erb
@@ -1,6 +1,6 @@
<%
# calculate padding for the longest word
-max_length = ['fqdn:', 'os:', 'role:', 'branch:', 'addr:', 'nic:'].max_by(&:length).length
+max_length = ['fqdn:', 'os:', 'role:', 'branch:', 'addr:', 'nic:', 'location:', 'env:'].max_by(&:length).length
# helper lambda to right-align text
align = ->(word) { word.ljust(max_length) }
%>
@@ -10,4 +10,6 @@ align = ->(word) { word.ljust(max_length) }
<%= align.call('branch:') %> <%= @enc_env %>
<%= align.call('addr:') %> <%= @addr %>
<%= align.call('nic:') %> <%= @nic %>
+<%= align.call('location:') %> <%= @location %>
+<%= align.call('env:') %> <%= @env %>
diff --git a/site/profiles/templates/base/scripts/puppetwrapper.py.erb b/site/profiles/templates/base/scripts/puppetwrapper.py.erb
index 57ca8b1..809fd71 100644
--- a/site/profiles/templates/base/scripts/puppetwrapper.py.erb
+++ b/site/profiles/templates/base/scripts/puppetwrapper.py.erb
@@ -11,7 +11,7 @@ def main():
if index + 1 < len(args): # Check if there's another argument after "-E"
environment_value = args[index + 1]
# Replace \ and - with _
- modified_environment_value = environment_value.replace("\\", "_").replace("-", "_").replace("/","_")
+ modified_environment_value = environment_value.replace("\\", "_").replace("-", "_").replace("/","_").replace(".","_")
args[index + 1] = modified_environment_value
# Construct the full puppet command with the modified args
diff --git a/site/profiles/templates/cobbler/debmirror.conf.erb b/site/profiles/templates/cobbler/debmirror.conf.erb
new file mode 100644
index 0000000..9c66ca1
--- /dev/null
+++ b/site/profiles/templates/cobbler/debmirror.conf.erb
@@ -0,0 +1,79 @@
+# Puppet managed config for debmirror
+
+# The config file is a perl script so take care to follow perl syntax.
+# Any setting in /etc/debmirror.conf overrides these defaults and
+# ~/.debmirror.conf overrides those again. Take only what you need.
+#
+# The syntax is the same as on the command line and variable names
+# loosely match option names. If you don't recognize something here
+# then just stick to the command line.
+#
+# Options specified on the command line override settings in the config
+# files.
+
+# Location of the local mirror (use with care)
+# $mirrordir="/path/to/mirrordir"
+
+# Output options
+$verbose=0;
+$progress=0;
+$debug=0;
+
+# Download options
+$host="ftp.debian.org";
+$user="anonymous";
+$passwd="anonymous@";
+$remoteroot="debian";
+$download_method="ftp";
+# @dists="sid";
+@sections="main,main/debian-installer,contrib,non-free,non-free-firmware";
+# @arches="i386";
+# @ignores="";
+# @excludes="";
+# @includes="";
+# @excludes_deb_section="";
+# @limit_priority="";
+$omit_suite_symlinks=0;
+$skippackages=0;
+# @rsync_extra="doc,tools";
+$i18n=0;
+$getcontents=0;
+$do_source=1;
+$max_batch=0;
+
+# @di_dists="dists";
+# @di_archs="arches";
+
+# Save mirror state between runs; value sets validity of cache in days
+$state_cache_days=0;
+
+# Security/Sanity options
+$ignore_release_gpg=0;
+$ignore_release=0;
+$check_md5sums=0;
+$ignore_small_errors=0;
+
+# Cleanup
+$cleanup=0;
+$post_cleanup=1;
+
+# Locking options
+$timeout=300;
+
+# Rsync options
+$rsync_batch=200;
+$rsync_options="-aIL --partial";
+
+# FTP/HTTP options
+$passive=0;
+# $proxy="http://proxy:port/";
+
+# Dry run
+$dry_run=0;
+
+# Don't keep diff files but use them
+$diff_mode="use";
+
+# The config file must return true or perl complains.
+# Always copy this.
+1;
diff --git a/site/profiles/templates/cobbler/httpd_ssl.conf.erb b/site/profiles/templates/cobbler/httpd_ssl.conf.erb
new file mode 100644
index 0000000..9b95ba5
--- /dev/null
+++ b/site/profiles/templates/cobbler/httpd_ssl.conf.erb
@@ -0,0 +1,203 @@
+# managed by puppet
+#
+# When we also provide SSL we have to listen to the
+# standard HTTPS port in addition.
+#
+Listen 443 https
+
+##
+## SSL Global Context
+##
+## All SSL configuration in this context applies both to
+## the main server and all SSL-enabled virtual hosts.
+##
+
+# Pass Phrase Dialog:
+# Configure the pass phrase gathering process.
+# The filtering dialog program (`builtin' is a internal
+# terminal dialog) has to provide the pass phrase on stdout.
+SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
+
+# Inter-Process Session Cache:
+# Configure the SSL Session Cache: First the mechanism
+# to use and second the expiring timeout (in seconds).
+SSLSessionCache shmcb:/run/httpd/sslcache(512000)
+SSLSessionCacheTimeout 300
+
+#
+# Use "SSLCryptoDevice" to enable any supported hardware
+# accelerators. Use "openssl engine -v" to list supported
+# engine names. NOTE: If you enable an accelerator and the
+# server does not start, consult the error logs and ensure
+# your accelerator is functioning properly.
+#
+SSLCryptoDevice builtin
+#SSLCryptoDevice ubsec
+
+##
+## SSL Virtual Host Context
+##
+
+
+
+# General setup for the virtual host, inherited from global configuration
+#DocumentRoot "/var/www/html"
+#ServerName www.example.com:443
+
+# Use separate log files for the SSL virtual host; note that LogLevel
+# is not inherited from httpd.conf.
+ErrorLog logs/ssl_error_log
+TransferLog logs/ssl_access_log
+LogLevel warn
+
+# SSL Engine Switch:
+# Enable/Disable SSL for this virtual host.
+SSLEngine on
+
+# List the protocol versions which clients are allowed to connect with.
+# The OpenSSL system profile is used by default. See
+# update-crypto-policies(8) for more details.
+#SSLProtocol all -SSLv3
+#SSLProxyProtocol all -SSLv3
+
+# User agents such as web browsers are not configured for the user's
+# own preference of either security or performance, therefore this
+# must be the prerogative of the web server administrator who manages
+# cpu load versus confidentiality, so enforce the server's cipher order.
+SSLHonorCipherOrder on
+
+# SSL Cipher Suite:
+# List the ciphers that the client is permitted to negotiate.
+# See the mod_ssl documentation for a complete list.
+# The OpenSSL system profile is configured by default. See
+# update-crypto-policies(8) for more details.
+SSLCipherSuite PROFILE=SYSTEM
+SSLProxyCipherSuite PROFILE=SYSTEM
+
+# Point SSLCertificateFile at a PEM encoded certificate. If
+# the certificate is encrypted, then you will be prompted for a
+# pass phrase. Note that restarting httpd will prompt again. Keep
+# in mind that if you have both an RSA and a DSA certificate you
+# can configure both in parallel (to also allow the use of DSA
+# ciphers, etc.)
+# Some ECC cipher suites (http://www.ietf.org/rfc/rfc4492.txt)
+# require an ECC certificate which can also be configured in
+# parallel.
+SSLCertificateFile <%= @httpd_ssl_certificate %>
+
+# Server Private Key:
+# If the key is not combined with the certificate, use this
+# directive to point at the key file. Keep in mind that if
+# you've both a RSA and a DSA private key you can configure
+# both in parallel (to also allow the use of DSA ciphers, etc.)
+# ECC keys, when in use, can also be configured in parallel
+SSLCertificateKeyFile <%= @httpd_ssl_privatekey %>
+
+# Server Certificate Chain:
+# Point SSLCertificateChainFile at a file containing the
+# concatenation of PEM encoded CA certificates which form the
+# certificate chain for the server certificate. Alternatively
+# the referenced file can be the same as SSLCertificateFile
+# when the CA certificates are directly appended to the server
+# certificate for convenience.
+#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
+
+# Certificate Authority (CA):
+# Set the CA certificate verification path where to find CA
+# certificates for client authentication or alternatively one
+# huge file containing all of them (file must be PEM encoded)
+#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
+
+# Client Authentication (Type):
+# Client certificate verification type and depth. Types are
+# none, optional, require and optional_no_ca. Depth is a
+# number which specifies how deeply to verify the certificate
+# issuer chain before deciding the certificate is not valid.
+#SSLVerifyClient require
+#SSLVerifyDepth 10
+
+# Access Control:
+# With SSLRequire you can do per-directory access control based
+# on arbitrary complex boolean expressions containing server
+# variable checks and other lookup directives. The syntax is a
+# mixture between C and Perl. See the mod_ssl documentation
+# for more details.
+#
+#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
+# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
+# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
+# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
+# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \
+# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
+#
+
+# SSL Engine Options:
+# Set various options for the SSL engine.
+# o FakeBasicAuth:
+# Translate the client X.509 into a Basic Authorisation. This means that
+# the standard Auth/DBMAuth methods can be used for access control. The
+# user name is the `one line' version of the client's X.509 certificate.
+# Note that no password is obtained from the user. Every entry in the user
+# file needs this password: `xxj31ZMTZzkVA'.
+# o ExportCertData:
+# This exports two additional environment variables: SSL_CLIENT_CERT and
+# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
+# server (always existing) and the client (only existing when client
+# authentication is used). This can be used to import the certificates
+# into CGI scripts.
+# o StdEnvVars:
+# This exports the standard SSL/TLS related `SSL_*' environment variables.
+# Per default this exportation is switched off for performance reasons,
+# because the extraction step is an expensive operation and is usually
+# useless for serving static content. So one usually enables the
+# exportation for CGI and SSI requests only.
+# o StrictRequire:
+# This denies access when "SSLRequireSSL" or "SSLRequire" applied even
+# under a "Satisfy any" situation, i.e. when it applies access is denied
+# and no other module can change it.
+# o OptRenegotiate:
+# This enables optimized SSL connection renegotiation handling when SSL
+# directives are used in per-directory context.
+#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
+
+ SSLOptions +StdEnvVars
+
+
+ SSLOptions +StdEnvVars
+
+
+# SSL Protocol Adjustments:
+# The safe and default but still SSL/TLS standard compliant shutdown
+# approach is that mod_ssl sends the close notify alert but doesn't wait for
+# the close notify alert from client. When you need a different shutdown
+# approach you can use one of the following variables:
+# o ssl-unclean-shutdown:
+# This forces an unclean shutdown when the connection is closed, i.e. no
+# SSL close notify alert is sent or allowed to be received. This violates
+# the SSL/TLS standard but is needed for some brain-dead browsers. Use
+# this when you receive I/O errors because of the standard approach where
+# mod_ssl sends the close notify alert.
+# o ssl-accurate-shutdown:
+# This forces an accurate shutdown when the connection is closed, i.e. a
+# SSL close notify alert is sent and mod_ssl waits for the close notify
+# alert of the client. This is 100% SSL/TLS standard compliant, but in
+# practice often causes hanging connections with brain-dead browsers. Use
+# this only for browsers where you know that their SSL implementation
+# works correctly.
+# Notice: Most problems of broken clients are also related to the HTTP
+# keep-alive facility, so you usually additionally want to disable
+# keep-alive for those clients, too. Use variable "nokeepalive" for this.
+# Similarly, one has to force some clients to use HTTP/1.0 to workaround
+# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
+# "force-response-1.0" for this.
+BrowserMatch "MSIE [2-5]" \
+ nokeepalive ssl-unclean-shutdown \
+ downgrade-1.0 force-response-1.0
+
+# Per-Server Logging:
+# The home of a custom SSL log file. Use this when you want a
+# compact non-error SSL logfile on a virtual host basis.
+CustomLog logs/ssl_request_log \
+ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
+
+
diff --git a/site/profiles/templates/cobbler/main.ipxe.erb b/site/profiles/templates/cobbler/main.ipxe.erb
new file mode 100644
index 0000000..386d262
--- /dev/null
+++ b/site/profiles/templates/cobbler/main.ipxe.erb
@@ -0,0 +1,47 @@
+#!ipxe
+dhcp
+
+# Some menu defaults
+set menu-timeout 5000
+set submenu-timeout ${menu-timeout}
+set menu-default cobbler
+
+:start
+menu iPXE boot menu
+item --gap -- ----------------------------- Cobbler ------------------------------------
+item cobbler Cobbler (kickstart or boot from disk)
+item --gap -- ------------------------- Advanced options -------------------------------
+item --key s shell Drop to iPXE shell
+item --key r reboot Reboot
+item
+item --key x exit Exit iPXE and continue BIOS boot
+choose --timeout ${menu-timeout} --default ${menu-default} selected || goto cancel
+set menu-timeout 0
+goto ${selected}
+
+:cancel
+echo You cancelled the menu, dropping you to a shell
+
+:no_system
+echo No system configuration found for MAC address ${mac}
+goto exit
+
+:shell
+echo Type 'exit' to get the back to the menu
+shell
+set menu-timeout 0
+set submenu-timeout 0
+goto start
+
+:reboot
+reboot
+
+:exit
+exit
+
+###
+### Custom menu entries
+###
+
+:cobbler
+chain --autofree http://${next-server}/cblr/svc/op/gpxe/mac/${net0/mac} || goto no_system
diff --git a/site/profiles/templates/cobbler/settings.yaml.erb b/site/profiles/templates/cobbler/settings.yaml.erb
new file mode 100644
index 0000000..1869444
--- /dev/null
+++ b/site/profiles/templates/cobbler/settings.yaml.erb
@@ -0,0 +1,466 @@
+# Cobbler settings file
+
+# Restart cobblerd and run "cobbler sync" after making changes.
+# This config file is in YAML 1.2 format; see "http://yaml.org".
+
+# If "true", Cobbler will allow insertions of system records that duplicate the "--dns-name" information of other system
+# records. In general, this is undesirable and should be left "false".
+allow_duplicate_hostnames: false
+
+# If "true", Cobbler will allow insertions of system records that duplicate the ip address information of other system
+# records. In general, this is undesirable and should be left "false".
+allow_duplicate_ips: false
+
+# If "true", Cobbler will allow insertions of system records that duplicate the MAC address information of other system
+# records. In general, this is undesirable.
+allow_duplicate_macs: false
+
+# If "true", Cobbler will allow settings to be changed dynamically without a restart of the cobblerd daemon. You can
+# only change this variable by manually editing the settings file, and you MUST restart cobblerd after changing it.
+allow_dynamic_settings: false
+
+# By default, installs are *not* set to send installation logs to the Cobbler server. With "anamon_enabled", automatic
+# installation templates may use the "pre_anamon" snippet to allow remote live monitoring of their installations from
+# the Cobbler server. Installation logs will be stored under "/var/log/cobbler/anamon/".
+# NOTE: This does allow an xmlrpc call to send logs to this directory, without authentication, so enable only if you are
+# ok with this limitation.
+anamon_enabled: false
+
+# If using "authn_pam" in the "modules.conf", this can be configured to change the PAM service authentication will be
+# tested against.
+# The default value is "login".
+authn_pam_service: "login"
+
+# How long the authentication token is valid for, in seconds.
+auth_token_expiration: 3600
+
+# This is a directory of files that Cobbler uses to make templating easier. See the Wiki for more information. Changing
+# this directory should not be required.
+autoinstall_snippets_dir: /var/lib/cobbler/snippets
+autoinstall_templates_dir: /var/lib/cobbler/templates
+
+# location of templates used for boot loader config generation
+boot_loader_conf_template_dir: "/etc/cobbler/boot_loader_conf"
+
+# Email out a report when Cobbler finishes installing a system.
+# enabled: set to true to turn this feature on
+# sender: optional
+# email: which addresses to email
+# smtp_server: used to specify another server for an MTA
+# subject: use the default subject unless overridden
+build_reporting_enabled: false
+build_reporting_sender: ""
+build_reporting_email: [ 'root@localhost' ]
+build_reporting_smtp_server: "localhost"
+build_reporting_subject: ""
+build_reporting_ignorelist: []
+
+# If cache_enabled is true, a cache will keep converted records in memory to make checking them faster. This helps with
+# use cases like writing out large numbers of records. There is a known issue with cache and remote XMLRPC API calls.
+# If you will use Cobbler with config management or infrastructure-as-code tools such as Terraform, it is recommended
+# to disable by setting to false.
+cache_enabled: true
+
+# Cheetah-language autoinstall templates can import Python modules. While this is a useful feature, it is not safe to
+# allow them to import anything they want. This whitelists which modules can be imported through Cheetah. Users can
+# expand this as needed but should never allow modules such as subprocess or those that allow access to the filesystem
+# as Cheetah templates are evaluated by cobblerd as code.
+cheetah_import_whitelist:
+ - "random"
+ - "re"
+ - "time"
+ - "netaddr"
+
+# Default "createrepo_flags" to use for new repositories. If you have createrepo >= 0.4.10, consider
+# "-c cache --update -C", which can dramatically improve your "cobbler reposync" time. "-s sha" enables working with
+# Fedora repos from F11/F12 from EL-4 or EL-5 without python-hashlib installed (which is not available on EL-4)
+createrepo_flags: "-c cache -s sha"
+
+# if no autoinstall template is specified to profile add, use this template
+default_autoinstall: /var/lib/cobbler/templates/default.ks
+
+# configure all installed systems to use these nameservers by default
+# unless defined differently in the profile. For DHCP configurations
+# you probably do /not/ want to supply this.
+default_name_servers: []
+default_name_servers_search: []
+
+# if using the authz_ownership module (see the Wiki), objects
+# created without specifying an owner are assigned to this
+# owner and/or group. Can be a comma seperated list.
+default_ownership:
+ - "admin"
+
+# Cobbler has various sample automatic installation templates stored
+# in /var/lib/cobbler/templates/. This controls
+# what install (root) password is set up for those
+# systems that reference this variable. The factory
+# default is "cobbler" and Cobbler check will warn if
+# this is not changed.
+# The simplest way to change the password is to run
+# openssl passwd -1
+# and put the output between the "" below.
+default_password_crypted: "<%= @default_password_crypted %>"
+
+# the default template type to use in the absence of any
+# other detected template. If you do not specify the template
+# with '#template=' on the first line of your
+# templates/snippets, Cobbler will assume try to use the
+# following template engine to parse the templates.
+#
+# Current valid values are: cheetah, jinja2
+default_template_type: "cheetah"
+
+# for libvirt based installs in koan, if no virt bridge
+# is specified, which bridge do we try? For EL 4/5 hosts
+# this should be xenbr0, for all versions of Fedora, try
+# "virbr0". This can be overriden on a per-profile
+# basis or at the koan command line though this saves
+# typing to just set it here to the most common option.
+default_virt_bridge: xenbr0
+
+# use this as the default disk size for virt guests (GB)
+default_virt_file_size: 5
+
+# use this as the default memory size for virt guests (MB)
+default_virt_ram: 512
+
+# if koan is invoked without --virt-type and no virt-type
+# is set on the profile/system, what virtualization type
+# should be assumed? Values: xenpv, xenfv, qemu, vmware
+# (NOTE: this does not change what virt_type is chosen by import)
+default_virt_type: xenpv
+
+# enable gPXE booting? Enabling this option will cause Cobbler
+# to copy the undionly.kpxe file to the tftp root directory,
+# and if a profile/system is configured to boot via gpxe it will
+# chain load off pxelinux.0.
+# Default: false
+enable_gpxe: false
+
+# controls whether Cobbler will add each new profile entry to the default
+# PXE boot menu. This can be over-ridden on a per-profile
+# basis when adding/editing profiles with --enable-menu=false/true. Users
+# should ordinarily leave this setting enabled unless they are concerned
+# with accidental reinstalls from users who select an entry at the PXE
+# boot menu. Adding a password to the boot menus templates
+# may also be a good solution to prevent unwanted reinstallations
+enable_menu: true
+
+# change this port if Apache is not running plaintext on port
+# 80. Most people can leave this alone.
+http_port: 80
+
+# kernel options that should be present in every Cobbler installation.
+# kernel options can also be applied at the distro/profile/system
+# level.
+kernel_options: {}
+
+# configuration options if using the authn_ldap module. See the
+# the Wiki for details. This can be ignored if you are not using
+# LDAP for WebUI/XMLRPC authentication.
+ldap_server: "ldap.example.com"
+ldap_base_dn: "DC=example,DC=com"
+ldap_port: 389
+ldap_tls: true
+ldap_anonymous_bind: true
+ldap_search_bind_dn: ''
+ldap_search_passwd: ''
+ldap_search_prefix: 'uid='
+ldap_tls_cacertfile: ''
+ldap_tls_keyfile: ''
+ldap_tls_certfile: ''
+
+# Cobbler has a feature that allows for integration with config management
+# systems such as Puppet. The following parameters work in conjunction with
+# --mgmt-classes and are described in further detail at:
+# https://github.com/cobbler/cobbler/wiki/Using-cobbler-with-a-configuration-management-system
+mgmt_classes: []
+mgmt_parameters:
+ from_cobbler: true
+
+# if enabled, this setting ensures that puppet is installed during
+# machine provision, a client certificate is generated and a
+# certificate signing request is made with the puppet master server
+puppet_auto_setup: false
+
+# when puppet starts on a system after installation it needs to have
+# its certificate signed by the puppet master server. Enabling the
+# following feature will ensure that the puppet server signs the
+# certificate after installation if the puppet master server is
+# running on the same machine as Cobbler. This requires
+# puppet_auto_setup above to be enabled
+sign_puppet_certs_automatically: false
+
+# location of the puppet executable, used for revoking certificates
+puppetca_path: "/usr/bin/puppet"
+
+# when a puppet managed machine is reinstalled it is necessary to
+# remove the puppet certificate from the puppet master server before a
+# new certificate is signed (see above). Enabling the following
+# feature will ensure that the certificate for the machine to be
+# installed is removed from the puppet master server if the puppet
+# master server is running on the same machine as Cobbler. This
+# requires puppet_auto_setup above to be enabled
+remove_old_puppet_certs_automatically: false
+
+# choose a --server argument when running puppetd/puppet agent during autoinstall
+#puppet_server: 'puppet'
+
+# let Cobbler know that you're using a newer version of puppet
+# choose version 3 to use: 'puppet agent'; version 2 uses status quo: 'puppetd'
+#puppet_version: 2
+
+# choose whether to enable puppet parameterized classes or not.
+# puppet versions prior to 2.6.5 do not support parameters
+puppet_parameterized_classes: true
+
+# set to true to enable Cobbler's DHCP management features.
+# the choice of DHCP management engine is in /etc/cobbler/modules.conf
+manage_dhcp: false
+
+# set to true to enable Cobbler's DNS management features.
+# the choice of DNS mangement engine is in /etc/cobbler/modules.conf
+manage_dns: false
+
+# set to path of bind chroot to create bind-chroot compatible bind
+# configuration files. This should be automatically detected.
+bind_chroot_path: ""
+
+# set to the ip address of the master bind DNS server for creating secondary
+# bind configuration files
+bind_master: 127.0.0.1
+
+# set to true to enable Cobbler's TFTP management features.
+# the choice of TFTP mangement engine is in /etc/cobbler/modules.conf
+manage_tftpd: true
+
+# This variable contains the location of the tftpboot directory. If this directory is not present Cobbler does not
+# start.
+# Default: /var/lib/tftpboot
+tftpboot_location: "/var/lib/tftpboot"
+
+# set to true to enable Cobbler's RSYNC management features.
+manage_rsync: false
+
+# if using BIND (named) for DNS management in /etc/cobbler/modules.conf
+# and manage_dns is enabled (above), this lists which zones are managed
+# See the Wiki (https://github.com/cobbler/cobbler/wiki/Dns-management) for more info
+manage_forward_zones: []
+manage_reverse_zones: []
+
+# if using Cobbler with manage_dhcp, put the IP address
+# of the Cobbler server here so that PXE booting guests can find it
+# if you do not set this correctly, this will be manifested in TFTP open timeouts.
+next_server: <%= @next_server %>
+
+# settings for power management features. optional.
+# see https://github.com/cobbler/cobbler/wiki/Power-management to learn more
+# choices (refer to codes.py):
+# apc_snmp bladecenter bullpap drac ether_wake ilo integrity
+# ipmilan lpar rsa virsh wti
+power_management_default_type: 'ipmilan'
+
+# if this setting is set to true, Cobbler systems that pxe boot
+# will request at the end of their installation to toggle the
+# --netboot-enabled record in the Cobbler system record. This eliminates
+# the potential for a PXE boot loop if the system is set to PXE
+# first in it's BIOS order. Enable this if PXE is first in your BIOS
+# boot order, otherwise leave this disabled. See the manpage
+# for --netboot-enabled.
+pxe_just_once: <%= @pxe_just_once %>
+
+# if this setting is set to one, triggers will be executed when systems
+# will request to toggle the --netboot-enabled record at the end of their installation.
+nopxe_with_triggers: true
+
+# This setting is only used by the code that supports using Spacewalk/Satellite
+# authentication within Cobbler Web and Cobbler XMLRPC.
+redhat_management_server: "xmlrpc.rhn.redhat.com"
+
+# if using authn_spacewalk in modules.conf to let Cobbler authenticate
+# against Satellite/Spacewalk's auth system, by default it will not allow per user
+# access into Cobbler Web and Cobbler XMLRPC.
+# in order to permit this, the following setting must be enabled HOWEVER
+# doing so will permit all Spacewalk/Satellite users of certain types to edit all
+# of Cobbler's configuration.
+# these roles are: config_admin and org_admin
+# users should turn this on only if they want this behavior and
+# do not have a cross-multi-org seperation concern. If you have
+# a single org in your satellite, it's probably safe to turn this
+# on and then you can use CobblerWeb alongside a Satellite install.
+redhat_management_permissive: false
+
+# specify the default Red Hat authorization key to use to register
+# system. If left blank, no registration will be attempted. Similarly
+# you can set the --redhat-management-key to blank on any system to
+# keep it from trying to register.
+redhat_management_key: ""
+
+# if set to true, allows /usr/bin/cobbler-register (part of the koan package)
+# to be used to remotely add new Cobbler system records to Cobbler.
+# this effectively allows for registration of new hardware from system
+# records.
+register_new_installs: false
+
+# Flags to use for yum's reposync. If your version of yum reposync
+# does not support -l, you may need to remove that option.
+reposync_flags: "-l -n -d"
+
+# Flags to use for rysync's reposync. If flag 'a' is used then createrepo
+# is not ran after the rsync
+reposync_rsync_flags: "-rltDv --copy-unsafe-links"
+
+# when DHCP and DNS management are enabled, Cobbler sync can automatically
+# restart those services to apply changes. The exception for this is
+# if using ISC for DHCP, then omapi eliminates the need for a restart.
+# omapi, however, is experimental and not recommended for most configurations.
+# If DHCP and DNS are going to be managed, but hosted on a box that
+# is not on this server, disable restarts here and write some other
+# script to ensure that the config files get copied/rsynced to the destination
+# box. This can be done by modifying the restart services trigger.
+# Note that if manage_dhcp and manage_dns are disabled, the respective
+# parameter will have no effect. Most users should not need to change
+# this.
+restart_dns: true
+restart_dhcp: true
+
+# install triggers are scripts in /var/lib/cobbler/triggers/install
+# that are triggered in autoinstall pre and post sections. Any
+# executable script in those directories is run. They can be used
+# to send email or perform other actions. They are currently
+# run as root so if you do not need this functionality you can
+# disable it, though this will also disable "cobbler status" which
+# uses a logging trigger to audit install progress.
+run_install_triggers: true
+
+# enables a trigger which version controls all changes to /var/lib/cobbler
+# when add, edit, or sync events are performed. This can be used
+# to revert to previous database versions, generate RSS feeds, or for
+# other auditing or backup purposes. "git" and "hg" are currently suported,
+# but git is the recommend SCM for use with this feature.
+scm_track_enabled: false
+scm_track_mode: "git"
+scm_track_author: "cobbler "
+scm_push_script: "/bin/true"
+
+# this is the address of the Cobbler server -- as it is used
+# by systems during the install process, it must be the address
+# or hostname of the system as those systems can see the server.
+# if you have a server that appears differently to different subnets
+# (dual homed, etc), you need to read the --server-override section
+# of the manpage for how that works.
+server: <%= @server %>
+
+# If set to true, all commands will be forced to use the localhost address
+# instead of using the above value which can force commands like
+# cobbler sync to open a connection to a remote address if one is in the
+# configuration and would traceback.
+client_use_localhost: false
+
+# If set to "true", all commands to the API (not directly to the XMLRPC server) will go over HTTPS instead of plaintext.
+# Be sure to change the "http_port" setting to the correct value for the web server.
+client_use_https: false
+
+# Should new profiles for virtual machines default to auto booting with the physical host when the physical host
+# reboots? This can be overridden on each profile or system object.
+virt_auto_boot: true
+
+# Cobbler's web directory. Don't change this setting -- see the Wiki on "Relocating your Cobbler install" if your "/var"
+# partition is not large enough.
+webdir: "/var/www/cobbler"
+
+# Directories that will not get wiped and recreated on a "cobbler sync".
+webdir_whitelist:
+ - misc
+ - web
+ - webui
+ - localmirror
+ - repo_mirror
+ - distro_mirror
+ - images
+ - links
+ - pub
+ - repo_profile
+ - repo_system
+ - svc
+ - rendered
+ - .link_cache
+
+# Cobbler's public XMLRPC listens on this port. Change this only
+# if absolutely needed, as you'll have to start supplying a new
+# port option to koan if it is not the default.
+xmlrpc_port: 25151
+
+# "cobbler repo add" commands set Cobbler up with repository
+# information that can be used during autoinstall and is automatically
+# set up in the Cobbler autoinstall templates. By default, these
+# are only available at install time. To make these repositories
+# usable on installed systems (since Cobbler makes a very convenient
+# mirror) set this to true. Most users can safely set this to true. Users
+# who have a dual homed Cobbler server, or are installing laptops that
+# will not always have access to the Cobbler server may wish to leave
+# this as false. In that case, the Cobbler mirrored yum repos are still
+# accessable at http://cobbler.example.org/cblr/repo_mirror and yum
+# configuration can still be done manually. This is just a shortcut.
+yum_post_install_mirror: true
+
+# the default yum priority for all the distros. This is only used if yum-priorities plugin is used.
+# 1=maximum
+# Tweak with caution!
+yum_distro_priority: 1
+
+# Flags to use for yumdownloader. Not all versions may support
+# --resolve.
+yumdownloader_flags: "--resolve"
+
+# sort and indent JSON output to make it more human-readable
+serializer_pretty_json: false
+
+# replication rsync options for distros, autoinstalls, snippets set to override default value of "-avzH"
+replicate_rsync_options: "-avzH"
+
+# replication rsync options for repos set to override default value of "-avzH"
+replicate_repo_rsync_options: "-avzH"
+
+# always write DHCP entries, regardless if netboot is enabled
+always_write_dhcp_entries: false
+
+# External proxy - used by: reposync", "signature update"
+# Eg: "http://192.168.1.1:8080" (HTTP), "https://192.168.1.1:8443" (HTTPS)
+proxy_url_ext: ""
+
+# Internal proxy - used by systems to reach Cobbler for templates
+# Eg: proxy_url_int: "http://10.0.0.1:8080"
+proxy_url_int: ""
+
+# This is a directory of files that Cobbler uses to include
+# files into Jinja2 templates
+jinja2_includedir: "/var/lib/cobbler/jinja2"
+
+# Up to now, cobblerd used $server's IP address instead of the DNS name in autoinstallation
+# file settings (pxelinux.cfg files) to save bytes, which seemed required for S/390 systems.
+# This behavior can have negative impact on installs with multi-homed Cobbler servers, because
+# not all of the IP addresses may be reachable during system install.
+# This behavior was now made conditional, with default being "off".
+convert_server_to_ip: false
+
+# Leftover settings
+bootloaders_dir: "/var/lib/cobbler/loaders"
+buildisodir: "/var/cache/cobbler/buildiso"
+cobbler_master: ""
+default_virt_disk_driver: "raw"
+grubconfig_dir: "/var/lib/cobbler/grub_config"
+iso_template_dir: "/etc/cobbler/iso"
+
+# Puppet
+puppet_server: ""
+puppet_version: 2
+
+# Signatures
+signature_path: "/var/lib/cobbler/distro_signatures.json"
+signature_url: "https://cobbler.github.io/signatures/3.0.x/latest.json"
+
+# Include other configuration snippets. Overwriting a key from this file in a childfile will overwrite the value from
+# this file.
+include: [ "/etc/cobbler/settings.d/*.settings" ]
diff --git a/site/profiles/templates/haproxy/certificate.list.erb b/site/profiles/templates/haproxy/certificate.list.erb
new file mode 100644
index 0000000..85c8efa
--- /dev/null
+++ b/site/profiles/templates/haproxy/certificate.list.erb
@@ -0,0 +1,3 @@
+<% @certificates.each do |item| %>
+<%= item %>
+<% end %>
diff --git a/site/profiles/templates/helpers/certmanager.erb b/site/profiles/templates/helpers/certmanager.erb
new file mode 100644
index 0000000..7266fde
--- /dev/null
+++ b/site/profiles/templates/helpers/certmanager.erb
@@ -0,0 +1,102 @@
+#!<%= @venv_path %>/bin/python
+
+import argparse
+import requests
+import json
+import os
+import yaml
+from zipfile import ZipFile
+
+# remove this after certs are generated everywhere
+requests.packages.urllib3.disable_warnings()
+
+def load_config(config_path):
+ with open(config_path, 'r') as file:
+ config = yaml.safe_load(file)
+ return config['vault']
+
+def authenticate_approle(vault_config):
+ url = f"{vault_config['addr']}/v1/auth/{vault_config['approle_path']}/login"
+ payload = {
+ "role_id": vault_config['role_id'],
+ }
+ response = requests.post(url, json=payload, verify=False)
+ if response.status_code == 200:
+ auth_response = response.json()
+ return auth_response['auth']['client_token']
+ else:
+ print(f"Error authenticating with AppRole: {response.text}")
+ return None
+
+def request_certificate(common_name, alt_names, ip_sans, expiry_days, vault_config):
+ # Authenticate using AppRole and get a token
+ client_token = authenticate_approle(vault_config)
+ if not client_token:
+ print("Failed to authenticate with Vault using AppRole.")
+ return None
+
+ url = f"{vault_config['addr']}/v1/{vault_config['mount_point']}/issue/{vault_config['role_name']}"
+ headers = {'X-Vault-Token': client_token}
+ payload = {
+ "common_name": common_name,
+ "alt_names": ",".join(alt_names),
+ "ip_sans": ",".join(ip_sans),
+ "ttl": f"{expiry_days}d"
+ }
+ response = requests.post(url, headers=headers, json=payload, verify=False)
+ if response.status_code == 200:
+ return response.json()
+ else:
+ print(f"Error requesting certificate: {response.text}")
+ return None
+
+def save_cert_files(certificate_response, common_name, compress, config, json_output):
+ base_path = config.get('output_path', '.')
+ cert_dir = os.path.join(base_path, common_name)
+ if json_output:
+ import json
+ output = {
+ 'certificate': certificate_response['data']['certificate'],
+ 'private_key': certificate_response['data']['private_key'],
+ 'full_chain': certificate_response['data']['issuing_ca'] + "\n" + certificate_response['data']['certificate'],
+ }
+ print(json.dumps(output))
+ elif not compress:
+ os.makedirs(cert_dir, exist_ok=True)
+ with open(os.path.join(cert_dir, "certificate.crt"), "w") as cert_file:
+ cert_file.write(certificate_response['data']['certificate'])
+ with open(os.path.join(cert_dir, "private.key"), "w") as key_file:
+ key_file.write(certificate_response['data']['private_key'])
+ with open(os.path.join(cert_dir, "full_chain.crt"), "w") as full_chain_file:
+ full_chain_file.write(certificate_response['data']['issuing_ca'] + "\n" + certificate_response['data']['certificate'])
+ else:
+ zip_name = f"{os.path.join(base_path, common_name)}.zip"
+ with ZipFile(zip_name, 'w') as zipf:
+ zipf.writestr("certificate.crt", certificate_response['data']['certificate'])
+ zipf.writestr("private.key", certificate_response['data']['private_key'])
+ zipf.writestr("full_chain.crt", certificate_response['data']['issuing_ca'] + "\n" + certificate_response['data']['certificate'])
+
+def main(config_file):
+ config = load_config(config_file)
+ parser = argparse.ArgumentParser(description='Request and retrieve a certificate from Vault.')
+ parser.add_argument('common_name', type=str, help='Common Name for the certificate')
+ parser.add_argument('-a', '--alt-names', type=str, default='', help='Comma-separated alternative names for the certificate')
+ parser.add_argument('-i', '--ip-sans', type=str, default='', help='Comma-separated IP Subject Alternative Names for the certificate')
+ parser.add_argument('-e', '--expiry-days', type=int, default=365, help='Validity of the certificate in days (default: 365)')
+ parser.add_argument('-c', '--compress', action='store_true', help='Compress the certificate, key, and full chain into a zip file')
+ parser.add_argument('--json', action='store_true', help='Output results in JSON format')
+ args = parser.parse_args()
+ alt_names = [name.strip() for name in args.alt_names.split(',') if name]
+ ip_sans = [ip.strip() for ip in args.ip_sans.split(',') if ip]
+ certificate_response = request_certificate(args.common_name, alt_names, ip_sans, args.expiry_days, config)
+ if certificate_response:
+ if args.json:
+ save_cert_files(certificate_response, args.common_name, args.compress, config, True)
+ else:
+ save_cert_files(certificate_response, args.common_name, args.compress, config, False)
+ else:
+ print("Failed to obtain certificate.")
+
+if __name__ == "__main__":
+ config_file = '<%= @config_path %>'
+ main(config_file)
diff --git a/site/profiles/templates/helpers/certmanager_config.yaml.erb b/site/profiles/templates/helpers/certmanager_config.yaml.erb
new file mode 100644
index 0000000..1b3e1ed
--- /dev/null
+++ b/site/profiles/templates/helpers/certmanager_config.yaml.erb
@@ -0,0 +1,7 @@
+vault:
+ addr: '<%= @vault_config['addr'] %>'
+ role_id: '<%= @vault_config['role_id'] %>'
+ approle_path: '<%= @vault_config['approle_path'] %>'
+ mount_point: '<%= @vault_config['mount_point'] %>'
+ role_name: '<%= @vault_config['role_name'] %>'
+output_path: '<%= @vault_config['output_path'] %>'
diff --git a/site/profiles/templates/helpers/node_lookup.erb b/site/profiles/templates/helpers/node_lookup.erb
index 7596821..deeb39e 100644
--- a/site/profiles/templates/helpers/node_lookup.erb
+++ b/site/profiles/templates/helpers/node_lookup.erb
@@ -3,6 +3,7 @@ import requests
import sys
import argparse
import json
+import os
def build_query(node=None, fact_name=None, match=None, show_role=False):
query_filters = []
@@ -23,14 +24,27 @@ def build_query(node=None, fact_name=None, match=None, show_role=False):
return json.dumps(["and"] + query_filters)
def query_puppetdb(query):
- url = 'http://puppetdb:8080/pdb/query/v4/facts'
+ url = 'http://puppetdbapi.service.consul:8080/pdb/query/v4/facts'
response = requests.get(url, params={'query': query})
process_response(response)
-def process_response(response):
+def process_response(response, count_only=False):
if response.status_code == 200:
- for fact in response.json():
- print(f"{fact['certname']} {fact['value']}")
+ try:
+ response_data = response.json()
+ except ValueError:
+ print("Error decoding JSON response")
+ return
+
+ if count_only:
+ fact_counter = Counter(fact['value'] for fact in response_data)
+ for fact_value, count in fact_counter.items():
+ print(f"{fact_value}: {count}")
+ else:
+ facts = [f"{fact['certname']} {fact['value']}" for fact in response_data]
+ facts.sort()
+ for fact in facts:
+ print(fact)
else:
print(f"Error querying PuppetDB: HTTP {response.status_code}")
print("Response content:", response.text)
@@ -45,6 +59,7 @@ def main():
parser.add_argument("-R", "--role", action="store_true", help="Show the role for matched hosts")
parser.add_argument("-F", "--fact", help="Specify a fact name")
parser.add_argument("-m", "--match", help="Simple pattern match for the value")
+ parser.add_argument("-C", "--count", action="store_true", help="Show count of rows with the same fact")
args = parser.parse_args()
diff --git a/site/profiles/templates/minio/minio.service.erb b/site/profiles/templates/minio/minio.service.erb
new file mode 100644
index 0000000..efaddbe
--- /dev/null
+++ b/site/profiles/templates/minio/minio.service.erb
@@ -0,0 +1,38 @@
+[Unit]
+Description=Minio
+Documentation=https://docs.minio.io
+Wants=network-online.target
+After=network-online.target
+After=syslog.target network.target
+AssertFileIsExecutable=<%= @installation_directory %>/minio
+
+[Service]
+WorkingDirectory=<%= @installation_directory %>
+
+User=<%= @owner %>
+Group=<%= @group %>
+
+PermissionsStartOnly=true
+
+EnvironmentFile=<%= @configuration_file_path %>
+ExecStart=<%= @installation_directory %>/minio server $MINIO_OPTS --address <%= @listen_ip %>:<%= @listen_port %> $MINIO_DEPLOYMENT_DEFINITION
+
+StandardOutput=journal
+StandardError=inherit
+
+# Specifies the maximum file descriptor number that can be opened by this process
+LimitNOFILE=65536
+
+# Disable timeout logic and wait until process is stopped
+TimeoutStopSec=0
+
+# SIGTERM signal is used to stop Minio
+KillSignal=SIGTERM
+
+SendSIGKILL=no
+
+SuccessExitStatus=0
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/site/profiles/templates/minio/minio_facts.yaml.erb b/site/profiles/templates/minio/minio_facts.yaml.erb
new file mode 100644
index 0000000..bc205b0
--- /dev/null
+++ b/site/profiles/templates/minio/minio_facts.yaml.erb
@@ -0,0 +1,17 @@
+# minio_facts.yaml
+minio_user: '<%= @owner %>'
+minio_group: '<%= @group %>'
+minio_pool: '<%= @minio_pool %>'
+minio_datadir: '<%= @datadir %>'
+minio_confdir: '<%= @confdir %>'
+minio_homedir: '<%= @homedir %>'
+minio_bindir: '<%= @bindir %>'
+minio_region: '<%= @minio_region %>'
+minio_members: <%= @minio_members %>
+minio_blockdev_count: <%= @blockdev_count %>
+<% unless @blockdev.empty? -%>
+minio_blockdevs:
+<% @blockdev.each do |device| -%>
+ - '<%= device %>'
+<% end -%>
+<% end -%>
diff --git a/site/profiles/templates/pki/vaultcaroot.pem.erb b/site/profiles/templates/pki/vaultcaroot.pem.erb
new file mode 100644
index 0000000..8a92884
--- /dev/null
+++ b/site/profiles/templates/pki/vaultcaroot.pem.erb
@@ -0,0 +1,91 @@
+# unkin.net Intermediate Authority drw1
+-----BEGIN CERTIFICATE-----
+MIIDrDCCApSgAwIBAgIUAyjDayxDtmvXzttcT1jUg9KU08swDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAxMJdW5raW4ubmV0MB4XDTI0MDIyNTExMDI0NloXDTI5MDIy
+MzExMDMxNlowKzEpMCcGA1UEAxMgdW5raW4ubmV0IEludGVybWVkaWF0ZSBBdXRo
+b3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCft5vNuV0S+WPN
+qIm8N09yQcWUjK7S5LeWqFi2sYvxB3PZIsbGF4oB5QQKbHOvwSp+/70gQ0HeyBpq
+yS3bVJK/OYMQXbYj+wpS8FXd1WeD5XphAEPV/vfWixQWOHLm4A+yjVbyFiaD4Z8e
+0/cvi48WPp3uzyVFW12U/XRZ/eHF4psJ1tsNt8e1JcAsAmRXUr1R0JgKNDBJsu2Q
+2EPa6MqRpJVKfI4cvOYM3XyXN5pCogAJaleg+TMdZ3wCQljTBpojzX947Ky1Yosa
+GtZ2tNes8cpq3mzHqH8fms89H1JBPttOCVJXwK1sEdwkXYh6aktUDGkjppvaG013
+eSx/LDFvAgMBAAGjgd4wgdswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
+Af8wHQYDVR0OBBYEFEMfNj+VqQQF2XHJm1qK0RhCZxnRMB8GA1UdIwQYMBaAFCqI
+QnrNBzDWmM1YryAlmIbAnwLPMEAGCCsGAQUFBwEBBDQwMjAwBggrBgEFBQcwAoYk
+aHR0cDovLzEyNy4wLjAuMTo4MjAwL3YxL3BraV9yb290L2NhMDYGA1UdHwQvMC0w
+K6ApoCeGJWh0dHA6Ly8xMjcuMC4wLjE6ODIwMC92MS9wa2lfcm9vdC9jcmwwDQYJ
+KoZIhvcNAQELBQADggEBALMGlMJ7twlrBkBJLBgDmF7+Q5rpiHz9zBhLU8fh0HiR
+dhqe3yJcO87o3CrCiQXqtWHGy4Ogl2QvastKKhFBIcwp8BBXxzp68HG+SIJAzWau
+val0pncs/2V3TIk1iOXLY7YXDm6x4ND+iUz5rmILs/0q82S3iAbro4IckinfmGjI
+7En8eg7VRv8z2FL51+giov5zqH7NT3TjvYZzf20EKHmOlyZhAboktNxVpoj4cAGl
+iUW3GFSva8F6VS49I9pejBFJUQeIILz5jeTEdzG643DnujjjNqw8ad3ivakBYD1G
+YxGhYmLfh5RmESCeAgBbLQgRa1vNz1YYWhjn4OP0KKs=
+-----END CERTIFICATE-----
+
+# unkin.net Intermediate Authority syd1
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgIULZAR/QcvAnxdi04S6bXhNeazozYwDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAxMJdW5raW4ubmV0MB4XDTI0MDQyNzExMzcyMloXDTI5MDQy
+NjExMzc1MlowKzEpMCcGA1UEAxMgdW5raW4ubmV0IEludGVybWVkaWF0ZSBBdXRo
+b3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDq0ZU2DnuYW5s
+E3lPjVe2Ns6cPu64yx1GLVqB5VbOUs71ThRjPjvEwE98YtGMza8ok0CQSqS2qX8z
+vnMbnVCaWKjCnem/dtQtB+8WCu5uQuNHhwqxgw1tD/klAkVLWGgTPDEgasvjDMkc
+sW8in/BhtrV9YA/lQGpge+j9/MFXhlnvaLCPybFifPRX9Yc5CcnhSzLSzFPO4PJx
+VH4Qu9eByyKHMTvgcCy6p9qjjzz+8dtAlxeIsgfTEdvtfCPowsF+v2XooutTsJt0
+xUDvUDu4xV6tVCEOYRA2cZHkLRBhV289M0hocHrsGqMmA1+j0skwwt/6UkVHqlCT
+mitItX+RAgMBAAGjgewwgekwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
+Af8wHQYDVR0OBBYEFEp/+grAdVqRSeb9xJjSeZYNW32MMB8GA1UdIwQYMBaAFBqc
+v6Y+hfHt4EjgKa/uoQGEHTknMEcGCCsGAQUFBwEBBDswOTA3BggrBgEFBQcwAoYr
+aHR0cHM6Ly92YXVsdC5zZXJ2dWNlLmNvbnN1bC92MS9wa2lfcm9vdC9jYTA9BgNV
+HR8ENjA0MDKgMKAuhixodHRwczovL3ZhdWx0LnNlcnZpY2UuY29uc3VsL3YxL3Br
+aV9yb290L2NybDANBgkqhkiG9w0BAQsFAAOCAQEAM0FS8tscZe7yly/gM7jO6lx5
+muMFusifjUIrcQGnZBkoECeuUVPNTs3e/Th+XaxjCnmSpqSNT3z9Irr6Hhxf7n03
+4+hpF3G0bf1yh4DRex/0ua3szvgo91RwyKVQM1BHIA1PwdF8csO+LT4FTMILzo4U
+DdSVvDEIaxYYQCDNfAD81n+8lmFbabupfsKbkSTR+sNTS+TMnLpN8YwSXdB0e+RU
+eEZRNVu0jKmbE8U/66Sc33YLe6cxbCclHA+G4giGwEP+lYZk+rFjmr6ci9bj5yyN
+Sznr7xdW0ofOdACAQFFy5KTZqCDjIrvk12vUn4bSsXmWVIQEd+jPx6wuxD/rSw==
+-----END CERTIFICATE-----
+
+# unkin.net drw1
+-----BEGIN CERTIFICATE-----
+MIIDLzCCAhegAwIBAgIUeXJ+O/IJWu4Fl4+KdZl5r166SokwDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAxMJdW5raW4ubmV0MB4XDTI0MDIyNTExMDEwNVoXDTM0MDIy
+MjExMDEzNFowFDESMBAGA1UEAxMJdW5raW4ubmV0MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAzKFwXIKAkavv5RgGUEzGQIgys1Uw97RBp4aE7glT++hs
+60WSwKBRr+sk7zdL3LGMK/xClTIBt3eFJ2RMxEf/N/qLPoA1JqOzsHua1nXCR1sA
+puP5HVfrS6YvfsXGpqJywX7tfaqk+7+Mq4Bbp22+JXmgBpfcQhCy9CNRd8gaLM67
+LaznQEcmeurdqvqeUxSMUsymeLLSi2+Fx+M9bPiYYXvK3Hu7k7VVsDPamglBsZaG
+QC7Up7ZD1h+UaweK/lC5v8HkW6xZ8OWZBEm0F6XFRIRRbroFTZXniAUu60FpoCCD
+Ga9AfUrAAIWFQjd0iJ2fgzbX1qeLozKn1T/oMAiKhQIDAQABo3kwdzAOBgNVHQ8B
+Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUKohCes0HMNaYzViv
+ICWYhsCfAs8wHwYDVR0jBBgwFoAUKohCes0HMNaYzVivICWYhsCfAs8wFAYDVR0R
+BA0wC4IJdW5raW4ubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCBVjvJIAp3AtEhRO/V
+wYtF/t6ntSKs8limCGnHHvJDvUJGkIP5ihCDQYviNyYIf7CrtRUmYzzOmwA4OEjq
+cwxrdRynqkUz8jeRL2Ljc1kEs5A4rY2X8EtoUaCu4p55wm7Bh/m2lYASHHMpuza8
+CR2DtlSQR8/x9gFKzAZO6rOw89qqU34p/cf7DlymDACjJr0QmhLa5IQMSj8ObsbT
+c9sb9NXMFTsFkuCrkF5iLmeDZgmgyJNXkzFEh3TPeL15jKBXSJOHsBe8j3E3VMWS
+YOL0pDU1XzfJedKGzX3LxvK6aUuBbtgaf/PW3IYX3KToolqfB30H2AO6Q/3LBl8M
+aN8H
+-----END CERTIFICATE-----
+
+# unkin.net syd1
+-----BEGIN CERTIFICATE-----
+MIIDLzCCAhegAwIBAgIUIDADwsHIrQ8dfncpechBdIUCQdIwDQYJKoZIhvcNAQEL
+BQAwFDESMBAGA1UEAxMJdW5raW4ubmV0MB4XDTI0MDQyNzExMjcwMloXDTM0MDQy
+NTExMjczMlowFDESMBAGA1UEAxMJdW5raW4ubmV0MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEA3ENPv7R7gCUJAg8Q4hB2LEZSdvbK155YbcrguLDDnu6m
+2fkJn8jYMMW3Z6/+Y04ouGwi6sKup8ggTb217sY+dC4IUZjotDPAhruxfXVQAh0v
+Yr3RYoxVDrm4nRSFLo1RA4Qt+1KK299mHGQf9iAiwbsFp5mDrJT9uz15FE2uWmbK
+8/onMyJC4fnkMihVN6NIgTtjpHYNm5aAJwxoWldTopgF0ucb7X3XVPNbKAmd3Avd
+lsOo6m751zSZ0HvJOxgRSy7lvPzMuUfCQsOcmI4O4+Z2FL4Y7p+T9DvWkciC7L3i
+tBiK30fPfGKNpWaof1ONCcPQNjMwWcEFXqSiWUOXkwIDAQABo3kwdzAOBgNVHQ8B
+Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGpy/pj6F8e3gSOAp
+r+6hAYQdOScwHwYDVR0jBBgwFoAUGpy/pj6F8e3gSOApr+6hAYQdOScwFAYDVR0R
+BA0wC4IJdW5raW4ubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQA5xocILzuvD+R2Iub1
+UnTdcVpgNcxJmESz0eX4UrkcBmddtuFINXvDTv5//XTFs78LsVVSf00xZ+2C62Xe
+xRdCdluHN8VDCAKulP4XJY1BiZ7im0v+iMgPDKhq4OXb86WFYI/8J6uRm7oIAwj1
+zhhKxMimkzli+yHB8ipL15W7l68CMUgmOjFA+EG6sbfadFpQTX/h6TVj3FQPkU/p
+UJEm2XjlGNAKGJrNRU47PM4vRDv5Joyowp9zv/pHFXvUJladaJupMKRJQVWQz1US
+EXE67rawG79s3vm8dDolnbli/IhPHtjDRIprxAwrMs5tt9cY0xsRkFBZVcAOjrpb
+4gqd
+-----END CERTIFICATE-----
diff --git a/site/profiles/templates/proxmox/join_pvecluster.erb b/site/profiles/templates/proxmox/join_pvecluster.erb
new file mode 100644
index 0000000..378b95d
--- /dev/null
+++ b/site/profiles/templates/proxmox/join_pvecluster.erb
@@ -0,0 +1,11 @@
+#!/usr/bin/expect -f
+set timeout -1
+set password [lindex $argv 0]
+set ip [lindex $argv 1]
+
+spawn pvecm add $ip
+expect "Please enter superuser (root) password for"
+send "$password\r"
+expect "The authenticity of host"
+send "yes\r"
+expect eof
diff --git a/site/profiles/templates/proxmox/pve_facts.yaml.erb b/site/profiles/templates/proxmox/pve_facts.yaml.erb
new file mode 100644
index 0000000..7b3362e
--- /dev/null
+++ b/site/profiles/templates/proxmox/pve_facts.yaml.erb
@@ -0,0 +1,2 @@
+---
+pve_clusterinit_master: <%= @clusterinit_master %>
diff --git a/site/profiles/templates/puppet/client/puppet.conf.erb b/site/profiles/templates/puppet/client/puppet.conf.erb
index e7a86c6..40874c6 100644
--- a/site/profiles/templates/puppet/client/puppet.conf.erb
+++ b/site/profiles/templates/puppet/client/puppet.conf.erb
@@ -1,5 +1,5 @@
[main]
-dns_alt_names = <%= @dns_alt_names %>
+dns_alt_names = <%= @dns_alt_names_string %>
[agent]
server = <%= @server %>
diff --git a/site/profiles/templates/puppet/puppet_ca.cfg.erb b/site/profiles/templates/puppet/puppet_ca.cfg.erb
new file mode 100644
index 0000000..a119784
--- /dev/null
+++ b/site/profiles/templates/puppet/puppet_ca.cfg.erb
@@ -0,0 +1,10 @@
+certificate-authority: {
+ # allow CA to sign certificate requests that have subject alternative names.
+ allow-subject-alt-names: <%= @allow_subject_alt_names %>
+
+ # allow CA to sign certificate requests that have authorization extensions.
+ allow-authorization-extensions: <%= @allow_authorization_extensions %>
+
+ # enable the separate CRL for Puppet infrastructure nodes
+ enable-infra-crl: <%= @enable_infra_crl %>
+}
diff --git a/site/profiles/templates/puppet/server/cobbler-enc.erb b/site/profiles/templates/puppet/server/cobbler-enc.erb
new file mode 100644
index 0000000..27dd30e
--- /dev/null
+++ b/site/profiles/templates/puppet/server/cobbler-enc.erb
@@ -0,0 +1,46 @@
+#!<%= @venv_path %>/bin/python
+"""
+External Node Classifier (ENC) for Puppet.
+
+If the environment specified in the YAML file is 'testing',
+the environment is not included in the output.
+"""
+
+import sys
+import yaml
+import requests
+
+def fetch_enc_data(cobbler_url: str, hostname: str) -> str:
+ """
+ Fetches and modifies ENC data from a given URL to ensure classes are in list format.
+ """
+ url = f"{cobbler_url}/cblr/svc/op/puppet/hostname/{hostname}"
+ try:
+ response = requests.get(url, verify='<%= @trusted_ca_cert %>')
+ response.raise_for_status()
+ except requests.RequestException as e:
+ sys.exit(f"Request failed: {e}")
+
+ data = yaml.safe_load(response.text)
+ data["parameters"] = data.get("parameters", {})
+
+ # Ensure 'classes' is in the desired list format
+ if "classes" in data:
+ if isinstance(data["classes"], dict):
+ data["parameters"]["enc_role"] = list(data["classes"].keys())
+ data["classes"] = list(data["classes"].keys())
+ else:
+ data["parameters"]["enc_role"] = list(data["classes"])
+ data["classes"] = list(data["classes"])
+
+ if "environment" in data:
+ data["parameters"]["enc_env"] = data["environment"]
+ if data["environment"] == "testing":
+ del data["environment"]
+
+ return yaml.dump(data)
+
+if __name__ == "__main__":
+ if len(sys.argv) != 2:
+ sys.exit(f"Usage: {sys.argv[0]} ")
+ print(fetch_enc_data("<%= @cobbler_base_url %>", sys.argv[1]))
diff --git a/site/profiles/templates/puppet/server/puppet.conf.epp b/site/profiles/templates/puppet/server/puppet.conf.epp
index 226346d..dbb93ee 100644
--- a/site/profiles/templates/puppet/server/puppet.conf.epp
+++ b/site/profiles/templates/puppet/server/puppet.conf.epp
@@ -10,9 +10,16 @@ dns_alt_names = <%= $dns_alt_names %>
[agent]
server = <%= $server %>
+ca_server = <%= $ca_server %>
+environment = <%= $environment %>
+report = <%= $report %>
+report_server = <%= $report_server %>
+runinterval = <%= $runinterval %>
+runtimeout = <%= $runtimeout %>
+show_diff = <%= $show_diff %>
[master]
-node_terminus = exec
+node_terminus = <%= $node_terminus %>
external_nodes = <%= $external_nodes %>
autosign = <%= $autosign %>
default_manifest = <%= $default_manifest %>
diff --git a/site/profiles/templates/reposync/autosyncer.erb b/site/profiles/templates/reposync/autosyncer.erb
index cd6c963..0cc2551 100644
--- a/site/profiles/templates/reposync/autosyncer.erb
+++ b/site/profiles/templates/reposync/autosyncer.erb
@@ -26,7 +26,7 @@ download_gpg_key() {
local filename=$(basename "$gpgkeyurl")
# Download GPG key to the specified path with the filename from the URL
- wget -q -O "${basepath}/live/${reponame}/${filename}" "$gpgkeyurl" || {
+ curl -s --create-dirs -o "${basepath}/live/${reponame}/${filename}" "$gpgkeyurl" || {
echo "Failed to download GPG key from $gpgkeyurl"
}
}
@@ -89,6 +89,6 @@ for conf in /etc/reposync/conf.d/*.conf; do
create_repo_metadata "${snap_path}"
# Update selinux
- restorecon <%= @basepath %>
+ restorecon -R ${snap_path}
done
diff --git a/site/profiles/templates/vault/unseal_keys.erb b/site/profiles/templates/vault/unseal_keys.erb
new file mode 100644
index 0000000..0ee4751
--- /dev/null
+++ b/site/profiles/templates/vault/unseal_keys.erb
@@ -0,0 +1,3 @@
+<% @unseal_keys.each do |key| -%>
+<%= key %>
+<% end -%>
diff --git a/site/profiles/templates/vault/vault-unseal.service.erb b/site/profiles/templates/vault/vault-unseal.service.erb
new file mode 100644
index 0000000..83b0e1a
--- /dev/null
+++ b/site/profiles/templates/vault/vault-unseal.service.erb
@@ -0,0 +1,14 @@
+[Unit]
+Description=Unseal Vault Service
+After=vault.service network.target
+Requires=vault.service
+PartOf=vault.service
+
+[Service]
+Type=oneshot
+ExecStart=/usr/local/bin/vault-unseal.sh
+RemainAfterExit=yes
+User=root
+
+[Install]
+WantedBy=multi-user.target
diff --git a/site/profiles/templates/vault/vault_unseal.sh.erb b/site/profiles/templates/vault/vault_unseal.sh.erb
new file mode 100644
index 0000000..5e4d5aa
--- /dev/null
+++ b/site/profiles/templates/vault/vault_unseal.sh.erb
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+# Script to unseal Vault
+
+VAULT_ADDR='<%= @vault_address %>'
+UNSEAL_KEYS_FILE='/etc/vault/unseal_keys'
+
+# Check if Vault is sealed
+is_sealed=$(curl -s ${VAULT_ADDR}/v1/sys/seal-status | jq -r '.sealed')
+if [ "$is_sealed" != "true" ]; then
+ echo "Vault is already unsealed."
+ exit 0
+fi
+
+# Retrieve unseal keys from plaintext file
+unseal_keys=$(cat "$UNSEAL_KEYS_FILE")
+
+# Loop through the unseal keys and use them to unseal Vault
+for key in $unseal_keys; do
+ curl --request PUT --data '{"key": "'$key'"}' $VAULT_ADDR/v1/sys/unseal
+done
+
+echo "Vault has been unsealed."
diff --git a/site/roles/manifests/base.pp b/site/roles/manifests/base.pp
index d6a7fa2..371974f 100644
--- a/site/roles/manifests/base.pp
+++ b/site/roles/manifests/base.pp
@@ -1,6 +1,11 @@
# a role to deploy the base system
# work in progress
class roles::base {
- include profiles::defaults
- include profiles::base
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ }
}
diff --git a/site/roles/manifests/infra/cobbler/server.pp b/site/roles/manifests/infra/cobbler/server.pp
new file mode 100644
index 0000000..5ffd2a6
--- /dev/null
+++ b/site/roles/manifests/infra/cobbler/server.pp
@@ -0,0 +1,11 @@
+# cobbler server profile
+class roles::infra::cobbler::server {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::base
+ include profiles::base::datavol
+ include profiles::cobbler::init
+ }
+}
diff --git a/site/roles/manifests/infra/db/redis.pp b/site/roles/manifests/infra/db/redis.pp
new file mode 100644
index 0000000..af3bfce
--- /dev/null
+++ b/site/roles/manifests/infra/db/redis.pp
@@ -0,0 +1,10 @@
+# a role to deploy a redis node
+class roles::infra::db::redis {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ }
+}
diff --git a/site/roles/manifests/infra/dhcp/server.pp b/site/roles/manifests/infra/dhcp/server.pp
new file mode 100644
index 0000000..1a27e17
--- /dev/null
+++ b/site/roles/manifests/infra/dhcp/server.pp
@@ -0,0 +1,11 @@
+# dhcp server profile
+class roles::infra::dhcp::server {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::dhcp::server
+ }
+}
diff --git a/site/roles/manifests/infra/dns/master.pp b/site/roles/manifests/infra/dns/master.pp
index e5d50de..fbf5192 100644
--- a/site/roles/manifests/infra/dns/master.pp
+++ b/site/roles/manifests/infra/dns/master.pp
@@ -2,7 +2,12 @@
# defines a dns server with master-only zones
#
class roles::infra::dns::master {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
include profiles::defaults
include profiles::base
include profiles::dns::master
+ }
}
diff --git a/site/roles/manifests/infra/dns/resolver.pp b/site/roles/manifests/infra/dns/resolver.pp
index 606ca9f..3277cad 100644
--- a/site/roles/manifests/infra/dns/resolver.pp
+++ b/site/roles/manifests/infra/dns/resolver.pp
@@ -2,7 +2,12 @@
# defines a dns server with forward-only zones
#
class roles::infra::dns::resolver {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
include profiles::defaults
include profiles::base
include profiles::dns::resolver
+ }
}
diff --git a/site/roles/manifests/infra/git/gitea.pp b/site/roles/manifests/infra/git/gitea.pp
new file mode 100644
index 0000000..a11e842
--- /dev/null
+++ b/site/roles/manifests/infra/git/gitea.pp
@@ -0,0 +1,14 @@
+# a role to deploy the puppetboard
+class roles::infra::git::gitea {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::base::datavol
+ if $facts['enc_role'] == 'roles::infra::git::gitea' {
+ include profiles::gitea::init
+ }
+ }
+}
diff --git a/site/roles/manifests/infra/halb/haproxy.pp b/site/roles/manifests/infra/halb/haproxy.pp
new file mode 100644
index 0000000..87a2d41
--- /dev/null
+++ b/site/roles/manifests/infra/halb/haproxy.pp
@@ -0,0 +1,11 @@
+# a role to deploy a haproxy node
+class roles::infra::halb::haproxy {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::haproxy::server
+ }
+}
diff --git a/site/roles/manifests/infra/metrics/grafana.pp b/site/roles/manifests/infra/metrics/grafana.pp
index 4d9176a..a73d7a5 100644
--- a/site/roles/manifests/infra/metrics/grafana.pp
+++ b/site/roles/manifests/infra/metrics/grafana.pp
@@ -1,6 +1,11 @@
# a role to deploy a grafana service
class roles::infra::metrics::grafana {
- include profiles::defaults
- include profiles::base
- include profiles::metrics::grafana
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::metrics::grafana
+ }
}
diff --git a/site/roles/manifests/infra/metrics/prometheus.pp b/site/roles/manifests/infra/metrics/prometheus.pp
index d3dd8ea..1b2ee1c 100644
--- a/site/roles/manifests/infra/metrics/prometheus.pp
+++ b/site/roles/manifests/infra/metrics/prometheus.pp
@@ -1,7 +1,12 @@
# a role to deploy a prometheus server
class roles::infra::metrics::prometheus {
- include profiles::defaults
- include profiles::base
- include profiles::base::datavol
- include profiles::metrics::server
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::base::datavol
+ include profiles::metrics::server
+ }
}
diff --git a/site/roles/manifests/infra/ntp/server.pp b/site/roles/manifests/infra/ntp/server.pp
index cfc685d..4ff34f3 100644
--- a/site/roles/manifests/infra/ntp/server.pp
+++ b/site/roles/manifests/infra/ntp/server.pp
@@ -1,6 +1,11 @@
# a role to deploy a ntp server
class roles::infra::ntp::server {
- include profiles::defaults
- include profiles::base
- include profiles::ntp::server
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::ntp::server
+ }
}
diff --git a/site/roles/manifests/infra/ovirt/engine.pp b/site/roles/manifests/infra/ovirt/engine.pp
new file mode 100644
index 0000000..1e998f3
--- /dev/null
+++ b/site/roles/manifests/infra/ovirt/engine.pp
@@ -0,0 +1,10 @@
+# role to manage ovirt management engine nodes
+class roles::infra::ovirt::engine {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ }
+}
diff --git a/site/roles/manifests/infra/ovirt/node.pp b/site/roles/manifests/infra/ovirt/node.pp
new file mode 100644
index 0000000..026a25f
--- /dev/null
+++ b/site/roles/manifests/infra/ovirt/node.pp
@@ -0,0 +1,11 @@
+# role to manage ovirt hypervisor nodes
+class roles::infra::ovirt::node {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::ovirt::node
+ }
+}
diff --git a/site/roles/manifests/infra/proxmox/node.pp b/site/roles/manifests/infra/proxmox/node.pp
new file mode 100644
index 0000000..ccf41b6
--- /dev/null
+++ b/site/roles/manifests/infra/proxmox/node.pp
@@ -0,0 +1,11 @@
+# manage the installation of a proxmox node
+class roles::infra::proxmox::node {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::proxmox::init
+ }
+}
diff --git a/site/roles/manifests/infra/puppet/master.pp b/site/roles/manifests/infra/puppet/master.pp
index 01e8877..c29ab7a 100644
--- a/site/roles/manifests/infra/puppet/master.pp
+++ b/site/roles/manifests/infra/puppet/master.pp
@@ -1,7 +1,12 @@
# a role to deploy the puppetmaster
# work in progress
class roles::infra::puppet::master {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
include profiles::defaults
include profiles::base
include profiles::puppet::puppetmaster
}
+}
diff --git a/site/roles/manifests/infra/puppetboard/server.pp b/site/roles/manifests/infra/puppetboard/server.pp
index 4742810..e2d772d 100644
--- a/site/roles/manifests/infra/puppetboard/server.pp
+++ b/site/roles/manifests/infra/puppetboard/server.pp
@@ -1,6 +1,11 @@
# a role to deploy the puppetboard
class roles::infra::puppetboard::server {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
include profiles::defaults
include profiles::base
include profiles::puppet::puppetboard
}
+}
diff --git a/site/roles/manifests/infra/puppetdb/api.pp b/site/roles/manifests/infra/puppetdb/api.pp
index 65bee4c..7d50c47 100644
--- a/site/roles/manifests/infra/puppetdb/api.pp
+++ b/site/roles/manifests/infra/puppetdb/api.pp
@@ -1,6 +1,11 @@
# a role to deploy the puppetdb api service
class roles::infra::puppetdb::api {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
include profiles::defaults
include profiles::base
include profiles::puppet::puppetdb_api
}
+}
diff --git a/site/roles/manifests/infra/puppetdb/sql.pp b/site/roles/manifests/infra/puppetdb/sql.pp
index 97ebc96..7f13859 100644
--- a/site/roles/manifests/infra/puppetdb/sql.pp
+++ b/site/roles/manifests/infra/puppetdb/sql.pp
@@ -1,6 +1,11 @@
# a role to deploy the puppetdb postgresql service
class roles::infra::puppetdb::sql {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
include profiles::defaults
include profiles::base
include profiles::puppet::puppetdb_sql
}
+}
diff --git a/site/roles/manifests/infra/reposync/syncer.pp b/site/roles/manifests/infra/reposync/syncer.pp
index 8c5a613..9c41fe3 100644
--- a/site/roles/manifests/infra/reposync/syncer.pp
+++ b/site/roles/manifests/infra/reposync/syncer.pp
@@ -1,7 +1,12 @@
# a role to deploy a packagerepo
class roles::infra::reposync::syncer {
- include profiles::defaults
- include profiles::base
- include profiles::base::datavol
- include profiles::reposync::syncer
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::base::datavol
+ include profiles::reposync::syncer
+ }
}
diff --git a/site/roles/manifests/infra/sql/galera.pp b/site/roles/manifests/infra/sql/galera.pp
index a116c8c..2628f81 100644
--- a/site/roles/manifests/infra/sql/galera.pp
+++ b/site/roles/manifests/infra/sql/galera.pp
@@ -1,7 +1,15 @@
# a role to deploy a mariadb galera node
class roles::infra::sql::galera {
- include profiles::defaults
- include profiles::base
- include profiles::base::datavol
- include profiles::sql::galera_member
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::base::datavol
+
+ if $facts['enc_role'] == 'roles::infra::sql::galera' {
+ include profiles::sql::galera_member
+ }
+ }
}
diff --git a/site/roles/manifests/infra/storage/consul.pp b/site/roles/manifests/infra/storage/consul.pp
new file mode 100644
index 0000000..143b167
--- /dev/null
+++ b/site/roles/manifests/infra/storage/consul.pp
@@ -0,0 +1,12 @@
+# a role to deploy a consul node
+class roles::infra::storage::consul {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::base::datavol
+ include profiles::consul::server
+ }
+}
diff --git a/site/roles/manifests/infra/storage/edgecache.pp b/site/roles/manifests/infra/storage/edgecache.pp
new file mode 100644
index 0000000..7d9d655
--- /dev/null
+++ b/site/roles/manifests/infra/storage/edgecache.pp
@@ -0,0 +1,12 @@
+# a role to deploy an edgecache
+class roles::infra::storage::edgecache {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::base::datavol
+ include profiles::edgecache::init
+ }
+}
diff --git a/site/roles/manifests/infra/storage/minio.pp b/site/roles/manifests/infra/storage/minio.pp
new file mode 100644
index 0000000..d436e8e
--- /dev/null
+++ b/site/roles/manifests/infra/storage/minio.pp
@@ -0,0 +1,11 @@
+# a role to deploy a minio node
+class roles::infra::storage::minio {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::minio::server
+ }
+}
diff --git a/site/roles/manifests/infra/storage/vault.pp b/site/roles/manifests/infra/storage/vault.pp
new file mode 100644
index 0000000..9e11b14
--- /dev/null
+++ b/site/roles/manifests/infra/storage/vault.pp
@@ -0,0 +1,12 @@
+# a role to deploy a vault node
+class roles::infra::storage::vault {
+ if $facts['firstrun'] {
+ include profiles::defaults
+ include profiles::firstrun::init
+ }else{
+ include profiles::defaults
+ include profiles::base
+ include profiles::base::datavol
+ include profiles::vault::server
+ }
+}