From 254c9f1358a451a753273e1cb601d57f94966309 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Wed, 22 Nov 2023 18:29:42 +1100 Subject: [PATCH 1/2] feat: configure grafana - create grafana class - configure database with db export, and db parameters --- hieradata/roles/infra/metrics/grafana.yaml | 2 + site/profiles/manifests/metrics/grafana.pp | 58 +++++++++++++++++++ site/roles/manifests/infra/metrics/grafana.pp | 1 + 3 files changed, 61 insertions(+) create mode 100644 hieradata/roles/infra/metrics/grafana.yaml create mode 100644 site/profiles/manifests/metrics/grafana.pp diff --git a/hieradata/roles/infra/metrics/grafana.yaml b/hieradata/roles/infra/metrics/grafana.yaml new file mode 100644 index 0000000..a61c689 --- /dev/null +++ b/hieradata/roles/infra/metrics/grafana.yaml @@ -0,0 +1,2 @@ +--- +#profile::metrics::grafana diff --git a/site/profiles/manifests/metrics/grafana.pp b/site/profiles/manifests/metrics/grafana.pp new file mode 100644 index 0000000..1025589 --- /dev/null +++ b/site/profiles/manifests/metrics/grafana.pp @@ -0,0 +1,58 @@ +# profiles::metrics::grafana +class profiles::metrics::grafana ( + Integer $http_port = 8080, + String $app_mode = 'production', + Boolean $allow_sign_up = false, + Boolean $mysql_backend = true, + String $mysql_host = '127.0.0.1:3306', + String $mysql_user = 'grafana', + Sensitive $mysql_pass = 'grafana', + Sensitive $mysql_name = 'grafana', + +) { + + # set the fqdn + $fqdn = $::facts['networking']['fqdn'] + + # when using mysql backend + if $mysql_backend { + + # create a db for grafana + @@mysql::db { "mydb_${fqdn}": + user => $mysql_user, + password => $mysql_pass, + dbname => $mysql_name, + host => $fqdn, + grant => ['SELECT', 'UPDATE'], + #tag => $domain, + } + + $database_config = { + type => 'mysql', + host => $mysql_host, + name => $mysql_name, + user => $mysql_user, + password => $mysql_pass.unwrap, + } + + $sensitive_database_config = Sensitive($database_config) + } + + # build the grafana config hash + $cfg = { + app_mode => $app_mode, + server => { + http_port => $http_port, + }, + database => $sensitive_database_config, + users => { + allow_sign_up => $allow_sign_up, + }, + } + + # deploy grafana + class { 'grafana': + cfg => $cfg, + } + +} diff --git a/site/roles/manifests/infra/metrics/grafana.pp b/site/roles/manifests/infra/metrics/grafana.pp index db6f757..4d9176a 100644 --- a/site/roles/manifests/infra/metrics/grafana.pp +++ b/site/roles/manifests/infra/metrics/grafana.pp @@ -2,4 +2,5 @@ class roles::infra::metrics::grafana { include profiles::defaults include profiles::base + include profiles::metrics::grafana } -- 2.47.3 From 62cac63f110f601fc9e9215e096b5ea1b4d97b78 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 16 Jun 2024 00:41:02 +1000 Subject: [PATCH 2/2] feat: add database generation to grafana - ensure a database, user and credential is created for each grafana node - ensure all databases for a region are included in a mariadb cluster - refine params with stdlib types --- hieradata/common.yaml | 3 ++ .../au/region/syd1/infra/sql/galera.eyaml | 2 + .../au/region/syd1/infra/sql/galera.yaml | 11 +++++ hieradata/roles/infra/metrics/grafana.yaml | 49 ++++++++++++++++++- hieradata/roles/infra/storage/consul.yaml | 6 +++ site/profiles/manifests/metrics/grafana.pp | 41 ++++++++++------ site/profiles/manifests/puppet/puppetca.pp | 4 ++ site/profiles/manifests/sql/galera_member.pp | 15 ++++++ .../templates/metrics/grafana.service.erb | 49 +++++++++++++++++++ 9 files changed, 163 insertions(+), 17 deletions(-) create mode 100644 hieradata/country/au/region/syd1/infra/sql/galera.eyaml create mode 100644 site/profiles/templates/metrics/grafana.service.erb diff --git a/hieradata/common.yaml b/hieradata/common.yaml index e8169f7..314920a 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -117,6 +117,9 @@ lookup_options: ssh::server::options: merge: strategy: deep + mysql::db: + merge: + strategy: deep facts_path: '/opt/puppetlabs/facter/facts.d' diff --git a/hieradata/country/au/region/syd1/infra/sql/galera.eyaml b/hieradata/country/au/region/syd1/infra/sql/galera.eyaml new file mode 100644 index 0000000..6904b7f --- /dev/null +++ b/hieradata/country/au/region/syd1/infra/sql/galera.eyaml @@ -0,0 +1,2 @@ +--- +mysql::db::grafana::pass: ENC[PKCS7,MIIBiQYJKoZIhvcNAQcDoIIBejCCAXYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAozi1vFf9KfwsGSdxXvhOWRn9Vqbr9AZ+cVJuIOmmLVZMRP4AJkkNgCCly+o1pxtMiU8EISUQuBWCBHUi+u2Y1YAjIABzTa2K+PCU7qqkdrJaxvKqmmKS7C/CWFKp1stYvYIvIofyvl9Q854nMcpvxQKL0PBGh3rIaUHHV3L0PH1UDLqL5j6OPXaNvKL4UzwMDDIVAd7F5yMbtSx2PT23pBLbPYsbG1jRx7pUS/d1ZE9E8h3OA2jxW/CBf68Sb2Xlrh7IAB/6RiLLpIsUyRMv9zrbPrMuKg/q5lzO0i9fejh5z3Z3YkdnhH61doUT/RSjAjz3JrWDGxomOSK0y8TxjjBMBgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCg1kVqFs/mf4r+6EI32b8qgCBm6cL3JhVzj3Btit9D8VYU8mQcrIaXJZ3qF31zJMzCkw==] diff --git a/hieradata/country/au/region/syd1/infra/sql/galera.yaml b/hieradata/country/au/region/syd1/infra/sql/galera.yaml index 9c4119c..d84ef52 100644 --- a/hieradata/country/au/region/syd1/infra/sql/galera.yaml +++ b/hieradata/country/au/region/syd1/infra/sql/galera.yaml @@ -2,3 +2,14 @@ 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 + +mysql::db: + grafana: + name: grafana + user: grafana + password: "%{alias('mysql::db::grafana::pass')}" + grant: + - SELECT + - INSERT + - UPDATE + - DELETE diff --git a/hieradata/roles/infra/metrics/grafana.yaml b/hieradata/roles/infra/metrics/grafana.yaml index a61c689..826065d 100644 --- a/hieradata/roles/infra/metrics/grafana.yaml +++ b/hieradata/roles/infra/metrics/grafana.yaml @@ -1,2 +1,49 @@ --- -#profile::metrics::grafana +hiera_include: + - profiles::nginx::simpleproxy + +profiles::metrics::grafana::mysql_host: "mariadb-%{facts.environment}.service.%{facts.country}-%{facts.region}.consul" +profiles::metrics::grafana::mysql_port: 3306 + +# additional altnames +profiles::pki::vault::alt_names: + - grafana.main.unkin.net + - grafana.service.consul + - grafana.query.consul + - "grafana.service.%{facts.country}-%{facts.region}.consul" + +profiles::ssh::sign::principals: + - grafana.main.unkin.net + - grafana.service.consul + - grafana.query.consul + +consul::services: + grafana: + service_name: 'grafana' + tags: + - 'grafana' + - 'metrics' + address: "%{facts.networking.ip}" + port: 443 + checks: + - id: 'Grafana_https_check' + name: 'Grafana 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: grafana + disposition: write + +# manage a simple nginx reverse proxy +profiles::nginx::simpleproxy::nginx_vhost: 'grafana.query.consul' +profiles::nginx::simpleproxy::nginx_aliases: + - grafana.main.unkin.net + - grafana.service.consul + - grafana.query.consul + - "grafana.service.%{facts.country}-%{facts.region}.consul" +profiles::nginx::simpleproxy::proxy_port: 8080 +profiles::nginx::simpleproxy::proxy_path: '/' diff --git a/hieradata/roles/infra/storage/consul.yaml b/hieradata/roles/infra/storage/consul.yaml index 2902de3..53abf8f 100644 --- a/hieradata/roles/infra/storage/consul.yaml +++ b/hieradata/roles/infra/storage/consul.yaml @@ -83,3 +83,9 @@ profiles::consul::prepared_query::rules: service_failover_n: 3 service_only_passing: true ttl: 10 + grafana: + ensure: 'present' + service_name: 'grafana' + service_failover_n: 3 + service_only_passing: true + ttl: 10 diff --git a/site/profiles/manifests/metrics/grafana.pp b/site/profiles/manifests/metrics/grafana.pp index 1025589..c7cd7ab 100644 --- a/site/profiles/manifests/metrics/grafana.pp +++ b/site/profiles/manifests/metrics/grafana.pp @@ -1,13 +1,14 @@ # profiles::metrics::grafana class profiles::metrics::grafana ( - Integer $http_port = 8080, + Stdlib::Port $http_port = 8080, String $app_mode = 'production', Boolean $allow_sign_up = false, Boolean $mysql_backend = true, - String $mysql_host = '127.0.0.1:3306', String $mysql_user = 'grafana', - Sensitive $mysql_pass = 'grafana', - Sensitive $mysql_name = 'grafana', + String $mysql_name = 'grafana', + String $mysql_pass = fqdn_rand_string(16), + Stdlib::Host $mysql_host = '127.0.0.1', + Stdlib::Port $mysql_port = 3306, ) { @@ -17,25 +18,27 @@ class profiles::metrics::grafana ( # when using mysql backend if $mysql_backend { - # create a db for grafana - @@mysql::db { "mydb_${fqdn}": - user => $mysql_user, - password => $mysql_pass, - dbname => $mysql_name, - host => $fqdn, - grant => ['SELECT', 'UPDATE'], - #tag => $domain, + @@mysql_user { "${mysql_user}@${facts['networking']['fqdn']}": + ensure => present, + password_hash => mysql::password(fqdn_rand_string(16)), + tag => $facts['region'], + } + + @@mysql_grant { "${mysql_user}@${facts['networking']['fqdn']}/${mysql_name}.*": + ensure => present, + table => "${mysql_name}.*", + user => "${mysql_user}@${facts['networking']['fqdn']}", + privileges => ['ALL'], + tag => $facts['region'], } $database_config = { type => 'mysql', - host => $mysql_host, + host => "${mysql_host}:${mysql_port}", name => $mysql_name, user => $mysql_user, password => $mysql_pass.unwrap, } - - $sensitive_database_config = Sensitive($database_config) } # build the grafana config hash @@ -44,7 +47,7 @@ class profiles::metrics::grafana ( server => { http_port => $http_port, }, - database => $sensitive_database_config, + database => $database_config, users => { allow_sign_up => $allow_sign_up, }, @@ -55,4 +58,10 @@ class profiles::metrics::grafana ( cfg => $cfg, } + # fix the package provided systemd service + systemd::unit_file { 'grafana-server.service': + content => template('profiles/metrics/grafana.service.erb'), + require => Package['grafana'], + before => Service['grafana'], + } } diff --git a/site/profiles/manifests/puppet/puppetca.pp b/site/profiles/manifests/puppet/puppetca.pp index 4e6233b..5b5124f 100644 --- a/site/profiles/manifests/puppet/puppetca.pp +++ b/site/profiles/manifests/puppet/puppetca.pp @@ -20,6 +20,7 @@ class profiles::puppet::puppetca ( # manage the crl file if $is_puppetca { + # export the puppet crl.pem @@file { '/etc/puppetlabs/puppet/ssl/crl.pem.latest': ensure => file, @@ -31,10 +32,12 @@ class profiles::puppet::puppetca ( unit => 'puppetserver.service', } }else{ + # import the puppet crl.pem File <<| tag == 'crl_pem_export' |>> { require => Service['puppetserver'], } + # copy latest to active location file { '/etc/puppetlabs/puppet/ssl/crl.pem': ensure => file, @@ -43,6 +46,7 @@ class profiles::puppet::puppetca ( source => '/etc/puppetlabs/puppet/ssl/crl.pem.latest', require => File['/etc/puppetlabs/puppet/ssl/crl.pem.latest'], } + # copy the latest crl when restarting systemd::manage_dropin { 'copy_crl.conf': ensure => present, diff --git a/site/profiles/manifests/sql/galera_member.pp b/site/profiles/manifests/sql/galera_member.pp index 24fab57..843e2a3 100644 --- a/site/profiles/manifests/sql/galera_member.pp +++ b/site/profiles/manifests/sql/galera_member.pp @@ -31,6 +31,7 @@ class profiles::sql::galera_member ( String $package_name = 'mariadb-server', Boolean $epel_needed = false, Boolean $manage_repo = true, + Hash $databases = lookup('mysql::db'), ) { # check that the master is named @@ -209,6 +210,20 @@ class profiles::sql::galera_member ( override_options => $merged_overrides, } + # import databases for this region + Mysql::Db <<| tag == $facts['region'] |>> + + # create databases from hiera + $databases.each |$name, $data| { + mysql::db {$name: + * => $data, + } + } + + # import users/grants for this region + Mysql_user <<| tag == $facts['region'] |>> + Mysql_grant <<| tag == $facts['region'] |>> + }else{ notice("${title} requires the servers_array to have 3 or more, currently it is ${length($servers_array)}.") } diff --git a/site/profiles/templates/metrics/grafana.service.erb b/site/profiles/templates/metrics/grafana.service.erb new file mode 100644 index 0000000..e67fd73 --- /dev/null +++ b/site/profiles/templates/metrics/grafana.service.erb @@ -0,0 +1,49 @@ +[Unit] +Description=Grafana instance +Documentation=http://docs.grafana.org +Wants=network-online.target +After=network-online.target +After=postgresql.service mariadb.service mysqld.service influxdb.service + +[Service] +EnvironmentFile=/etc/sysconfig/grafana-server +User=grafana +Group=grafana +Type=notify +Restart=on-failure +WorkingDirectory=/usr/share/grafana +RuntimeDirectory=grafana +RuntimeDirectoryMode=0750 +ExecStart=/usr/share/grafana/bin/grafana server \ + --config=${CONF_FILE} \ + --pidfile=${PID_FILE_DIR}/grafana-server.pid \ + --packaging=rpm \ + cfg:default.paths.logs=${LOG_DIR} \ + cfg:default.paths.data=${DATA_DIR} \ + cfg:default.paths.plugins=${PLUGINS_DIR} \ + cfg:default.paths.provisioning=${PROVISIONING_CFG_DIR} + +LimitNOFILE=10000 +TimeoutStopSec=20 +CapabilityBoundingSet= +DeviceAllow= +LockPersonality=true +MemoryDenyWriteExecute=false +NoNewPrivileges=true +PrivateDevices=true +PrivateTmp=true +ProtectControlGroups=true +ProtectHome=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectSystem=full +RemoveIPC=true +RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX +RestrictNamespaces=true +RestrictRealtime=true +RestrictSUIDSGID=true +SystemCallArchitectures=native +UMask=0027 + +[Install] +WantedBy=multi-user.target -- 2.47.3