From 116342bdaa47c59ef1d375105e1c61630c6de462 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 26 Aug 2023 16:11:53 +1000 Subject: [PATCH 01/18] Added class to manage a default set of scripts - included scripts into profiles::base - updated hiera with list of scripts to create and their template name - created template for a puppet wrapper --- hieradata/common.yaml | 3 +++ site/profiles/manifests/base.pp | 4 +++ site/profiles/manifests/base/scripts.pp | 26 +++++++++++++++++++ .../base/scripts/puppetwrapper.py.erb | 22 ++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 site/profiles/manifests/base/scripts.pp create mode 100644 site/profiles/templates/base/scripts/puppetwrapper.py.erb diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 5c004ed..569a796 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -21,6 +21,9 @@ profiles::base::packages::common: - wget - zsh +profiles::base::scripts::scripts: + puppet: puppetwrapper.py + profiles::puppet::autosign::subnet_ranges: - '198.18.17.0/24' diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index 5a5493c..079b8d3 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -17,8 +17,12 @@ class profiles::base ( } } + # install common required applications class { 'profiles::base::packages': packages => hiera('profiles::base::packages::common'), ensure => 'installed', } + + # include admin scripts + include profiles::base::scripts } diff --git a/site/profiles/manifests/base/scripts.pp b/site/profiles/manifests/base/scripts.pp new file mode 100644 index 0000000..fc0b3e8 --- /dev/null +++ b/site/profiles/manifests/base/scripts.pp @@ -0,0 +1,26 @@ +# This class can be included directly in node definitions or other classes. +# The preferred method for declaring the scripts is via Hiera. +# +# Here's an example Hiera configuration: +# +# profiles::base::scripts::scripts: +# script1: script1 +# script2: script2 +# +# This would deploy 'script1' and 'script2' to /usr/local/bin using their +# respective ERB templates in the profiles/base/scripts directory. +# +class profiles::base::scripts ( + Hash $scripts = {}, +) { + $scripts.each |$script_name, $template_name| { + file { "/usr/local/bin/${script_name}": + ensure => file, + owner => 'root', + group => 'root', + mode => '0755', + content => template("profiles/base/scripts/${template_name}.erb"), + } + } +} + diff --git a/site/profiles/templates/base/scripts/puppetwrapper.py.erb b/site/profiles/templates/base/scripts/puppetwrapper.py.erb new file mode 100644 index 0000000..57ca8b1 --- /dev/null +++ b/site/profiles/templates/base/scripts/puppetwrapper.py.erb @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +import sys +import subprocess + +def main(): + # If "-E" is in the arguments, modify the following argument + args = sys.argv[1:] + if "-E" in args: + index = args.index("-E") + 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("/","_") + args[index + 1] = modified_environment_value + + # Construct the full puppet command with the modified args + command = ["/opt/puppetlabs/bin/puppet"] + args + subprocess.run(command) + +if __name__ == "__main__": + main() From 81784f819fddf05247c42a9ffb7e65bb6b9701f3 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Tue, 29 Aug 2023 21:46:39 +1000 Subject: [PATCH 02/18] Show commit version when applying puppet - set the config_version in the environment.conf file --- environment.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/environment.conf b/environment.conf index 4569646..19e7e87 100644 --- a/environment.conf +++ b/environment.conf @@ -1,2 +1,3 @@ manifest = manifests/site.pp modulepath = external_modules:site +config_version = '/usr/bin/grep signature /etc/puppetlabs/code/environments/$environment/.g10k-deploy.json | /usr/bin/cut -d \" -f 4' From 2b11a9417c33f4ba3884921832ef076d386cfd54 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Tue, 29 Aug 2023 23:10:40 +1000 Subject: [PATCH 03/18] Account/Sudo management - imported account and sudo puppet modules - created account management wrapper - defined sysadmin account, set to be created on all nodes - removed sudo from base packages as its managed by sudo module now --- Puppetfile | 2 + hieradata/common.yaml | 4 +- site/profiles/manifests/accounts/sysadmin.pp | 15 +++++++ site/profiles/manifests/base.pp | 7 +++ site/profiles/manifests/base/account.pp | 45 ++++++++++++++++++++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 site/profiles/manifests/accounts/sysadmin.pp create mode 100644 site/profiles/manifests/base/account.pp diff --git a/Puppetfile b/Puppetfile index 5995d48..e24a9bc 100644 --- a/Puppetfile +++ b/Puppetfile @@ -15,3 +15,5 @@ mod 'puppetlabs-vcsrepo', '6.1.0' mod 'puppetlabs-yumrepo_core', '2.0.0' mod 'puppet-yum', '7.0.0' mod 'puppetlabs-apt', '9.1.0' +mod 'saz-sudo', '8.0.0' +mod 'puppetlabs-accounts', '8.1.0' diff --git a/hieradata/common.yaml b/hieradata/common.yaml index cd02e13..8708200 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -14,7 +14,6 @@ profiles::base::packages::common: - python3 - screen - strace - - sudo - tmux - vim - vnstat @@ -36,3 +35,6 @@ 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::accounts::sysadmin::sshkeys: + - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZ8SRLlPiDylBpdWR9LpvPg4fDVD+DZst4yRPFwMMhta4mnB1H9XuvZkptDhXywWQ7QIcqa2WbhCen0OQJCtwn3s7EYtacmF5MxmwBYocPoK2AArGuh6NA9rwTdLrPdzhZ+gwe88PAzRLNzjm0ZBR+mA9saMbPJdqpKp0AWeAM8QofRQAWuCzQg9i0Pn1KDMvVDRHCZof4pVlHSTyHNektq4ifovn0zhKC8jD/cYu95mc5ftBbORexpGiQWwQ3HZw1IBe0ZETB1qPIPwsoJpt3suvMrL6T2//fcIIUE3TcyJKb/yhztja4TZs5jT8370G/vhlT70He0YPxqHub8ZfBv0khlkY93VBWYpNGJwM1fVqlw7XbfBNdOuJivJac8eW317ZdiDnKkBTxapThpPG3et9ib1HoPGKRsd/fICzNz16h2R3tddSdihTFL+bmTCa6Lo+5t5uRuFjQvhSLSgO2/gRAprc3scYOB4pY/lxOFfq3pU2VvSJtRgLNEYMUYKk= ben@unkin.net diff --git a/site/profiles/manifests/accounts/sysadmin.pp b/site/profiles/manifests/accounts/sysadmin.pp new file mode 100644 index 0000000..81bde92 --- /dev/null +++ b/site/profiles/manifests/accounts/sysadmin.pp @@ -0,0 +1,15 @@ +# create the sysadmin user +class profiles::accounts::sysadmin( + 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, + } +} diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index 5a5493c..7383b59 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -21,4 +21,11 @@ class profiles::base ( packages => hiera('profiles::base::packages::common'), ensure => 'installed', } + + # all hosts will have sudo applied + include sudo + + # default users + include profiles::accounts::sysadmin + } diff --git a/site/profiles/manifests/base/account.pp b/site/profiles/manifests/base/account.pp new file mode 100644 index 0000000..92011b4 --- /dev/null +++ b/site/profiles/manifests/base/account.pp @@ -0,0 +1,45 @@ +# a wrapper for puppetlabs-account and saz-sudo +define profiles::base::account ( + String $username, + Integer $uid, + Integer $gid = undef, + Boolean $manage_home = true, + Boolean $create_group = true, + Boolean $purge_sshkeys = true, + Boolean $system = false, + Boolean $locked = false, + String $password = '!!', + Boolean $ignore_pass = false, + Array[String] $groups = [], + Array[String] $sshkeys = [], + Array[String] $sudo_rules = [], + String $shell = '/usr/bin/bash', +) { + + # Set gid to uid if gid is undef + $final_gid = $gid ? { + undef => $uid, + default => $gid, + } + + # Manage user + accounts::user { $username: + uid => $uid, + gid => $final_gid, + shell => $shell, + groups => $groups, + sshkeys => $sshkeys, + system => $system, + locked => $locked, + password => $password, + create_group => $create_group, + managehome => $manage_home, + purge_sshkeys => $purge_sshkeys, + ignore_password_if_empty => $ignore_pass, + } + + # Manage sudo rules + sudo::conf { "${username}_sudo": + content => $sudo_rules, + } +} From 080cdd8884eac10e09e1d4d2640f96a54ae5498c Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 26 Aug 2023 23:50:22 +1000 Subject: [PATCH 04/18] Setup PuppetDB/Puppetboard - install modules required - puppetdb - postgresql - puppetboard - python - create new profiles to manage each item (puppetdb/puppetboard) - added puppetdb role - include the puppetdb::master::config in puppetmaster role - re-organised the puppetfile - moved python to be managed by the python module - added postgresql to list of managed repos --- Puppetfile | 23 ++++++---- hieradata/common.yaml | 4 +- hieradata/os/AlmaLinux/AlmaLinux8.yaml | 1 + hieradata/os/AlmaLinux/AlmaLinux9.yaml | 1 + site/profiles/manifests/base.pp | 9 ++++ site/profiles/manifests/puppet/puppetboard.pp | 43 +++++++++++++++++++ site/profiles/manifests/puppet/puppetdb.pp | 38 ++++++++++++++++ .../profiles/manifests/puppet/puppetmaster.pp | 1 + site/roles/manifests/puppet/puppetdb.pp | 7 +++ 9 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 site/profiles/manifests/puppet/puppetboard.pp create mode 100644 site/profiles/manifests/puppet/puppetdb.pp create mode 100644 site/roles/manifests/puppet/puppetdb.pp diff --git a/Puppetfile b/Puppetfile index 5995d48..2ac7bc2 100644 --- a/Puppetfile +++ b/Puppetfile @@ -1,17 +1,24 @@ forge 'forge.puppetlabs.com' moduledir 'external_modules' -# Forge Modules +# puppetlabs mod 'puppetlabs-stdlib', '9.1.0' mod 'puppetlabs-inifile', '6.0.0' mod 'puppetlabs-concat', '9.0.0' -#mod 'eyp-eyplib', '0.1.24' -#mod 'eyp-systemd', '3.1.0' -mod 'puppet-systemd', '5.1.0' -mod 'ghoneycutt-puppet', '3.3.0' -mod 'puppet-archive', '7.0.0' -mod 'puppet-chrony', '2.6.0' mod 'puppetlabs-vcsrepo', '6.1.0' mod 'puppetlabs-yumrepo_core', '2.0.0' -mod 'puppet-yum', '7.0.0' mod 'puppetlabs-apt', '9.1.0' +mod 'puppetlabs-puppetdb', '7.13.0' +mod 'puppetlabs-postgresql', '9.1.0' +mod 'puppetlabs-firewall', '6.0.0' + +# puppet +mod 'puppet-python', '7.0.0' +mod 'puppet-systemd', '5.1.0' +mod 'puppet-yum', '7.0.0' +mod 'puppet-archive', '7.0.0' +mod 'puppet-chrony', '2.6.0' +mod 'puppet-puppetboard', '9.0.0' + +# other +mod 'ghoneycutt-puppet', '3.3.0' diff --git a/hieradata/common.yaml b/hieradata/common.yaml index cd02e13..83adf2c 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -11,7 +11,6 @@ profiles::base::packages::common: - mtr - ncdu - neovim - - python3 - screen - strace - sudo @@ -36,3 +35,6 @@ 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::puppetdb::puppetdb_host: prodinf01n04.main.unkin.net +puppetdb::master::config::create_puppet_service_resource: false +puppetdb::master::config::puppetdb_host: "%{lookup('profiles::puppet::puppetdb::puppetdb_host')}" diff --git a/hieradata/os/AlmaLinux/AlmaLinux8.yaml b/hieradata/os/AlmaLinux/AlmaLinux8.yaml index b932b45..3447bca 100644 --- a/hieradata/os/AlmaLinux/AlmaLinux8.yaml +++ b/hieradata/os/AlmaLinux/AlmaLinux8.yaml @@ -6,3 +6,4 @@ profiles::yum::managed_repos: - 'appstream' - 'epel' - 'puppet7' + - 'yum.postgresql.org' diff --git a/hieradata/os/AlmaLinux/AlmaLinux9.yaml b/hieradata/os/AlmaLinux/AlmaLinux9.yaml index 2c7f1c2..2613c77 100644 --- a/hieradata/os/AlmaLinux/AlmaLinux9.yaml +++ b/hieradata/os/AlmaLinux/AlmaLinux9.yaml @@ -6,3 +6,4 @@ profiles::yum::managed_repos: - 'appstream' - 'epel' - 'puppet7' + - 'yum.postgresql.org' diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index 5a5493c..ca34981 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -17,8 +17,17 @@ class profiles::base ( } } + # include the base packages profile class { 'profiles::base::packages': packages => hiera('profiles::base::packages::common'), ensure => 'installed', } + + # include the python class + class { 'python': + manage_python_package => true, + manage_venv_package => true, + manage_pip_package => true, + use_epel => false, + } } diff --git a/site/profiles/manifests/puppet/puppetboard.pp b/site/profiles/manifests/puppet/puppetboard.pp new file mode 100644 index 0000000..85d2d4e --- /dev/null +++ b/site/profiles/manifests/puppet/puppetboard.pp @@ -0,0 +1,43 @@ +# Class: profiles::puppet::puppetboard +# +# This class manages the configuration of Puppetboard, a web frontend for PuppetDB. +# +# Parameters: +# - `python_version`: Specifies the Python version used for the virtualenv where Puppetboard runs. +# - `manage_virtualenv`: Determines if this class should handle the creation of the virtual environment for Puppetboard. +# - `reports_count`: Defines the number of reports to show per node in Puppetboard. +# - `offline_mode`: Determines if Puppetboard should work in offline mode or not. +# - `default_environment`: Sets the default Puppet environment to filter results in Puppetboard. +# +# Usage: +# This class can be called directly in your manifests or through Hiera. +# +# Example: +# To use the default parameters (as shown below), you can declare the class: +# +# include profiles::puppet::puppetboard +# +# Alternatively, you can customize the parameters: +# +# class { 'profiles::puppet::puppetboard': +# python_version => '3.8', +# reports_count => 50, +# offline_mode => false, +# } +# +class profiles::puppet::puppetboard ( + String $python_version = '3.6', + Boolean $manage_virtualenv = false, + Integer $reports_count = 40, + Boolean $offline_mode = true, + String $default_environment = '*', +) { + + class { 'puppetboard': + python_version => $python_version, + manage_virtualenv => $manage_virtualenv, + reports_count => $reports_count, + offline_mode => $offline_mode, + default_environment => $default_environment, + } +} diff --git a/site/profiles/manifests/puppet/puppetdb.pp b/site/profiles/manifests/puppet/puppetdb.pp new file mode 100644 index 0000000..eaf2f44 --- /dev/null +++ b/site/profiles/manifests/puppet/puppetdb.pp @@ -0,0 +1,38 @@ +# profiles::puppet::puppetdb +# +# This class manages the installation and configuration of PuppetDB +# and its underlying PostgreSQL database on a single node. +# +# It makes use of the puppetlabs-puppetdb module to manage both the +# PuppetDB service and its PostgreSQL backend. +# +class profiles::puppet::puppetdb( + String $puppetdb_host, + String $listen_address = $facts['networking']['ip'], +) { + + # disable the postgresql dnf module for el8+ + if $facts['os']['family'] == 'RedHat' and $facts['os']['release']['major'] >= '8' { + # based on https://github.com/puppetlabs/puppetlabs-postgresql/blob/main/manifests/dnfmodule.pp + package { 'postgresql dnf module': + ensure => 'disabled', + name => 'postgresql', + provider => 'dnfmodule', + before => Class['puppetdb::database::postgresql'], + } + } + + # Install and configure PostgreSQL for PuppetDB + class { 'puppetdb::database::postgresql': + listen_addresses => $listen_address, + postgresql_ssl_on => false, + postgres_version => '15', + puppetdb_server => $puppetdb_host, + before => Class['puppetdb::server'], + } + + class { 'puppetdb::server': + database_host => $listen_address, + postgresql_ssl_on => false, + } +} diff --git a/site/profiles/manifests/puppet/puppetmaster.pp b/site/profiles/manifests/puppet/puppetmaster.pp index a835cc0..366317c 100644 --- a/site/profiles/manifests/puppet/puppetmaster.pp +++ b/site/profiles/manifests/puppet/puppetmaster.pp @@ -27,6 +27,7 @@ class profiles::puppet::puppetmaster { include profiles::puppet::g10k include profiles::puppet::enc include profiles::puppet::autosign + include puppetdb::master::config class { 'profiles::puppet::server': vardir => '/opt/puppetlabs/server/data/puppetserver', diff --git a/site/roles/manifests/puppet/puppetdb.pp b/site/roles/manifests/puppet/puppetdb.pp new file mode 100644 index 0000000..29ece76 --- /dev/null +++ b/site/roles/manifests/puppet/puppetdb.pp @@ -0,0 +1,7 @@ +# a role to deploy the puppetdb +# work in progress +class roles::puppet::puppetdb { + include profiles::defaults + include profiles::base + include profiles::puppet::puppetdb + } From 86a6c1bd96b9c38a0e8d4dcc7f65e0ddb9052ec8 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 21 Oct 2023 23:52:48 +1100 Subject: [PATCH 05/18] feat: add sudo secure_path - update the sudo class from an include to a definition - set the secure_path variable to include /usr/local/{bin,sbin} --- site/profiles/manifests/base.pp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index 23c0746..0f40f27 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -32,7 +32,9 @@ class profiles::base ( } # all hosts will have sudo applied - include sudo + class { 'sudo': + secure_path => '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/opt/puppetlabs/bin' + } # default users include profiles::accounts::sysadmin From 95434214a9559b9e09c8cb99fc50cc15fc2688be Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 22 Oct 2023 00:32:10 +1100 Subject: [PATCH 06/18] feat: add management of /etc/hosts - add class to manage the /etc/hosts file - add static hosts to /etc/hosts file via hiera array/hash --- hieradata/common.yaml | 15 +++++++++++++ site/profiles/manifests/base.pp | 3 +++ site/profiles/manifests/base/hosts.pp | 30 ++++++++++++++++++++++++++ site/profiles/templates/base/hosts.erb | 15 +++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 site/profiles/manifests/base/hosts.pp create mode 100644 site/profiles/templates/base/hosts.erb diff --git a/hieradata/common.yaml b/hieradata/common.yaml index d07c72a..1520bd2 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -43,3 +43,18 @@ puppetdb::master::config::puppetdb_host: "%{lookup('profiles::puppet::puppetdb:: profiles::accounts::sysadmin::sshkeys: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZ8SRLlPiDylBpdWR9LpvPg4fDVD+DZst4yRPFwMMhta4mnB1H9XuvZkptDhXywWQ7QIcqa2WbhCen0OQJCtwn3s7EYtacmF5MxmwBYocPoK2AArGuh6NA9rwTdLrPdzhZ+gwe88PAzRLNzjm0ZBR+mA9saMbPJdqpKp0AWeAM8QofRQAWuCzQg9i0Pn1KDMvVDRHCZof4pVlHSTyHNektq4ifovn0zhKC8jD/cYu95mc5ftBbORexpGiQWwQ3HZw1IBe0ZETB1qPIPwsoJpt3suvMrL6T2//fcIIUE3TcyJKb/yhztja4TZs5jT8370G/vhlT70He0YPxqHub8ZfBv0khlkY93VBWYpNGJwM1fVqlw7XbfBNdOuJivJac8eW317ZdiDnKkBTxapThpPG3et9ib1HoPGKRsd/fICzNz16h2R3tddSdihTFL+bmTCa6Lo+5t5uRuFjQvhSLSgO2/gRAprc3scYOB4pY/lxOFfq3pU2VvSJtRgLNEYMUYKk= ben@unkin.net + + +profiles::base::hosts::additional_hosts: + - ip: 198.18.17.3 + hostname: prodinf01n01.main.unkin.net + aliases: + - prodinf01n01 + - puppet + - puppetmaster + - puppetca + - ip: 198.18.17.4 + hostname: prodinf01n04.main.unkin.net + aliases: + - prodinf01n04 + - puppetdb diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index 8e56160..e5831df 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -26,6 +26,9 @@ class profiles::base ( # include admin scripts include profiles::base::scripts + # include admin scripts + include profiles::base::hosts + # include the python class class { 'python': manage_python_package => true, diff --git a/site/profiles/manifests/base/hosts.pp b/site/profiles/manifests/base/hosts.pp new file mode 100644 index 0000000..922b244 --- /dev/null +++ b/site/profiles/manifests/base/hosts.pp @@ -0,0 +1,30 @@ +# basic class to manage the /etc/hosts file from a template +# +# @param additional_hosts: +# An array of hashes with ip/hostname/aliases +# Aliases is an array in case there is a need for multiple aliases +# +# class { 'profiles::base::hosts': +# additional_hosts => [ +# { 'ip' => '192.168.0.10', 'hostname' => 'server1.example.com', 'aliases' => ['server1'] }, +# { 'ip' => '192.168.0.11', 'hostname' => 'server2.example.com' }, +# # ... and so on +# ], +# } +# +class profiles::base::hosts ( + Array[Hash] $additional_hosts = [] +) { + + $fqdn = $facts['networking']['fqdn'] + $hostname = $facts['networking']['hostname'] + + # Ensure the file exists and manage its content + file { '/etc/hosts': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + content => template('profiles/base/hosts.erb'), + } +} diff --git a/site/profiles/templates/base/hosts.erb b/site/profiles/templates/base/hosts.erb new file mode 100644 index 0000000..45bf0d2 --- /dev/null +++ b/site/profiles/templates/base/hosts.erb @@ -0,0 +1,15 @@ +# /etc/hosts file managed by Puppet + +# The following lines are desirable for IPv4 capable hosts +127.0.0.1 <%= @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 -%> From c6c36e835189100db47242f94e03850131de774f Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 22 Oct 2023 00:14:00 +1100 Subject: [PATCH 07/18] fix: set the puppetdb_host correctly - change the puppetdb::master::config from include to class statement - set the puppetdb_host value to match what is stored in hiera - disable firewall management on the puppetdb host --- site/profiles/manifests/puppet/puppetdb.pp | 1 + site/profiles/manifests/puppet/puppetmaster.pp | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/site/profiles/manifests/puppet/puppetdb.pp b/site/profiles/manifests/puppet/puppetdb.pp index eaf2f44..9ca7a57 100644 --- a/site/profiles/manifests/puppet/puppetdb.pp +++ b/site/profiles/manifests/puppet/puppetdb.pp @@ -34,5 +34,6 @@ class profiles::puppet::puppetdb( class { 'puppetdb::server': database_host => $listen_address, postgresql_ssl_on => false, + manage_firewall => false, } } diff --git a/site/profiles/manifests/puppet/puppetmaster.pp b/site/profiles/manifests/puppet/puppetmaster.pp index 366317c..76a80b6 100644 --- a/site/profiles/manifests/puppet/puppetmaster.pp +++ b/site/profiles/manifests/puppet/puppetmaster.pp @@ -22,12 +22,17 @@ # # Limitations: # This is designed to work on Unix-like systems. -class profiles::puppet::puppetmaster { +class profiles::puppet::puppetmaster ( + String $puppetdb_host = lookup('profiles::puppet::puppetdb::puppetdb_host'), +) { include profiles::puppet::r10k include profiles::puppet::g10k include profiles::puppet::enc include profiles::puppet::autosign - include puppetdb::master::config + + class { 'puppetdb::master::config': + puppetdb_server => $puppetdb_host, + } class { 'profiles::puppet::server': vardir => '/opt/puppetlabs/server/data/puppetserver', From f77221563047a73311ceb5f5d947ffe6d66d14f4 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 22 Oct 2023 01:30:57 +1100 Subject: [PATCH 08/18] fix: found typo in r10k script --- site/profiles/manifests/puppet/r10k.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/profiles/manifests/puppet/r10k.pp b/site/profiles/manifests/puppet/r10k.pp index c404be7..29d302f 100644 --- a/site/profiles/manifests/puppet/r10k.pp +++ b/site/profiles/manifests/puppet/r10k.pp @@ -52,7 +52,7 @@ class profiles::puppet::r10k ( group => 'root', mode => '0755', content => "#!/bin/bash\n( - cd /etc/puppetlabls/r10k + cd /etc/puppetlabs/r10k git reset --hard master git clean -fd git pull\n)", From 6bb52f2a1577ced8e17d9131338e62702cfe532b Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 22 Oct 2023 19:54:10 +1100 Subject: [PATCH 09/18] feat: add firewalld management profile - basic profile to enable/disable, and install/remove - defaulting to enabled and installed, but set to disabled and removed in hiera --- hieradata/os/AlmaLinux/all_releases.yaml | 3 ++ site/profiles/manifests/base.pp | 1 + site/profiles/manifests/firewall/firewalld.pp | 32 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 site/profiles/manifests/firewall/firewalld.pp diff --git a/hieradata/os/AlmaLinux/all_releases.yaml b/hieradata/os/AlmaLinux/all_releases.yaml index beee352..230dbd0 100644 --- a/hieradata/os/AlmaLinux/all_releases.yaml +++ b/hieradata/os/AlmaLinux/all_releases.yaml @@ -2,3 +2,6 @@ --- profiles::yum::base::baseurl: http://almalinux.mirror.digitalpacific.com.au profiles::yum::epel::baseurl: http://epel.mirror.digitalpacific.com.au +profiles::firewall::firewalld::ensure_package: 'absent' +profiles::firewall::firewalld::ensure_service: 'stopped' +profiles::firewall::firewalld::enable_service: false diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index e5831df..056d3e1 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -8,6 +8,7 @@ class profiles::base ( case $facts['os']['family'] { 'RedHat': { include profiles::yum::global + include profiles::firewall::firewalld } 'Debian': { include profiles::apt::global diff --git a/site/profiles/manifests/firewall/firewalld.pp b/site/profiles/manifests/firewall/firewalld.pp new file mode 100644 index 0000000..eaafda7 --- /dev/null +++ b/site/profiles/manifests/firewall/firewalld.pp @@ -0,0 +1,32 @@ +# Manages the firewalld package and service on RedHat-like distributions. +# +# @param ensure_package Determines the state of the firewalld package. +# Can be set to 'absent' to remove the package or 'installed' to ensure it's present. +# +# @param ensure_service Determines the state of the firewalld service. +# Can be set to 'stopped' to stop the service or 'running' to ensure it's active. +# +# @param enable_service A boolean that specifies whether to enable or disable the firewalld service on boot. +# +class profiles::firewall::firewalld ( + Enum['absent', 'installed'] $ensure_package = 'installed', + Enum['stopped', 'running'] $ensure_service = 'running', + Boolean $enable_service = true, +) { + # Ensure it only runs on RedHat like distributions + if $facts['os']['family'] == 'RedHat' { + + # Manage the firewalld package + package { 'firewalld': + ensure => $ensure_package, + } + + # Manage the firewalld service + service { 'firewalld': + ensure => $ensure_service, + enable => $enable_service, + hasrestart => true, + require => Package['firewalld'], + } + } +} From e682462917518767a91df8f980cb52cb4d2ef9a9 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 22 Oct 2023 19:46:10 +1100 Subject: [PATCH 10/18] feat: split puppetdb role into api and sql - add puppetdb_api and puppetdb_sql role - add puppetdb_api and puppetdb_sql profile - add prodinf01n05 to /etc/hosts file - set listen_address for all services to be hosts ip - set storeconfigs and storeconfigs_backend to be managed by puppetmaster profile --- hieradata/common.yaml | 7 +++- site/profiles/manifests/puppet/puppetdb.pp | 39 ------------------- .../profiles/manifests/puppet/puppetdb_api.pp | 16 ++++++++ .../profiles/manifests/puppet/puppetdb_sql.pp | 27 +++++++++++++ .../profiles/manifests/puppet/puppetmaster.pp | 29 +++++++------- site/profiles/manifests/puppet/server.pp | 28 +++++++------ .../templates/puppet/server/puppet.conf.epp | 2 + site/roles/manifests/puppet/puppetdb_api.pp | 6 +++ site/roles/manifests/puppet/puppetdb_sql.pp | 6 +++ 9 files changed, 95 insertions(+), 65 deletions(-) delete mode 100644 site/profiles/manifests/puppet/puppetdb.pp create mode 100644 site/profiles/manifests/puppet/puppetdb_api.pp create mode 100644 site/profiles/manifests/puppet/puppetdb_sql.pp create mode 100644 site/roles/manifests/puppet/puppetdb_api.pp create mode 100644 site/roles/manifests/puppet/puppetdb_sql.pp diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 1520bd2..eea398c 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -38,8 +38,9 @@ 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::puppetdb::puppetdb_host: prodinf01n04.main.unkin.net +profiles::puppet::puppetdb::postgres_host: prodinf01n05.main.unkin.net puppetdb::master::config::create_puppet_service_resource: false -puppetdb::master::config::puppetdb_host: "%{lookup('profiles::puppet::puppetdb::puppetdb_host')}" +#puppetdb::master::config::puppetdb_host: "%{lookup('profiles::puppet::puppetdb::puppetdb_host')}" profiles::accounts::sysadmin::sshkeys: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZ8SRLlPiDylBpdWR9LpvPg4fDVD+DZst4yRPFwMMhta4mnB1H9XuvZkptDhXywWQ7QIcqa2WbhCen0OQJCtwn3s7EYtacmF5MxmwBYocPoK2AArGuh6NA9rwTdLrPdzhZ+gwe88PAzRLNzjm0ZBR+mA9saMbPJdqpKp0AWeAM8QofRQAWuCzQg9i0Pn1KDMvVDRHCZof4pVlHSTyHNektq4ifovn0zhKC8jD/cYu95mc5ftBbORexpGiQWwQ3HZw1IBe0ZETB1qPIPwsoJpt3suvMrL6T2//fcIIUE3TcyJKb/yhztja4TZs5jT8370G/vhlT70He0YPxqHub8ZfBv0khlkY93VBWYpNGJwM1fVqlw7XbfBNdOuJivJac8eW317ZdiDnKkBTxapThpPG3et9ib1HoPGKRsd/fICzNz16h2R3tddSdihTFL+bmTCa6Lo+5t5uRuFjQvhSLSgO2/gRAprc3scYOB4pY/lxOFfq3pU2VvSJtRgLNEYMUYKk= ben@unkin.net @@ -58,3 +59,7 @@ profiles::base::hosts::additional_hosts: aliases: - prodinf01n04 - puppetdb + - ip: 198.18.17.5 + hostname: prodinf01n05.main.unkin.net + aliases: + - prodinf01n05 diff --git a/site/profiles/manifests/puppet/puppetdb.pp b/site/profiles/manifests/puppet/puppetdb.pp deleted file mode 100644 index 9ca7a57..0000000 --- a/site/profiles/manifests/puppet/puppetdb.pp +++ /dev/null @@ -1,39 +0,0 @@ -# profiles::puppet::puppetdb -# -# This class manages the installation and configuration of PuppetDB -# and its underlying PostgreSQL database on a single node. -# -# It makes use of the puppetlabs-puppetdb module to manage both the -# PuppetDB service and its PostgreSQL backend. -# -class profiles::puppet::puppetdb( - String $puppetdb_host, - String $listen_address = $facts['networking']['ip'], -) { - - # disable the postgresql dnf module for el8+ - if $facts['os']['family'] == 'RedHat' and $facts['os']['release']['major'] >= '8' { - # based on https://github.com/puppetlabs/puppetlabs-postgresql/blob/main/manifests/dnfmodule.pp - package { 'postgresql dnf module': - ensure => 'disabled', - name => 'postgresql', - provider => 'dnfmodule', - before => Class['puppetdb::database::postgresql'], - } - } - - # Install and configure PostgreSQL for PuppetDB - class { 'puppetdb::database::postgresql': - listen_addresses => $listen_address, - postgresql_ssl_on => false, - postgres_version => '15', - puppetdb_server => $puppetdb_host, - before => Class['puppetdb::server'], - } - - class { 'puppetdb::server': - database_host => $listen_address, - postgresql_ssl_on => false, - manage_firewall => false, - } -} diff --git a/site/profiles/manifests/puppet/puppetdb_api.pp b/site/profiles/manifests/puppet/puppetdb_api.pp new file mode 100644 index 0000000..fb1be2e --- /dev/null +++ b/site/profiles/manifests/puppet/puppetdb_api.pp @@ -0,0 +1,16 @@ +# configure the puppetdb api service +class profiles::puppet::puppetdb_api ( + String $postgres_host = lookup('profiles::puppet::puppetdb::postgres_host'), + String $listen_address = $facts['networking']['ip'], +) { + + class { 'puppetdb::server': + database_host => $postgres_host, + manage_firewall => false, + ssl_listen_address => $listen_address, + listen_address => $listen_address, + } + + contain ::puppetdb::server + +} diff --git a/site/profiles/manifests/puppet/puppetdb_sql.pp b/site/profiles/manifests/puppet/puppetdb_sql.pp new file mode 100644 index 0000000..2d80d30 --- /dev/null +++ b/site/profiles/manifests/puppet/puppetdb_sql.pp @@ -0,0 +1,27 @@ +# configure the puppetdb sql service +class profiles::puppet::puppetdb_sql ( + String $puppetdb_host = lookup('profiles::puppet::puppetdb::puppetdb_host'), + String $listen_address = $facts['networking']['ip'], +) { + + # disable the postgresql dnf module for el8+ + if $facts['os']['family'] == 'RedHat' and $facts['os']['release']['major'] >= '8' { + # based on https://github.com/puppetlabs/puppetlabs-postgresql/blob/main/manifests/dnfmodule.pp + package { 'postgresql dnf module': + ensure => 'disabled', + name => 'postgresql', + provider => 'dnfmodule', + before => Class['puppetdb::database::postgresql'], + } + } + + # Install and configure PostgreSQL for PuppetDB + class { 'puppetdb::database::postgresql': + listen_addresses => $listen_address, + postgres_version => '15', + puppetdb_server => $puppetdb_host, + } + + contain ::puppetdb::database::postgresql + +} diff --git a/site/profiles/manifests/puppet/puppetmaster.pp b/site/profiles/manifests/puppet/puppetmaster.pp index 76a80b6..f2a559a 100644 --- a/site/profiles/manifests/puppet/puppetmaster.pp +++ b/site/profiles/manifests/puppet/puppetmaster.pp @@ -31,16 +31,17 @@ class profiles::puppet::puppetmaster ( include profiles::puppet::autosign class { 'puppetdb::master::config': - puppetdb_server => $puppetdb_host, + puppetdb_server => $puppetdb_host, + manage_storeconfigs => false, } 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 => [ + 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', @@ -49,11 +50,13 @@ class profiles::puppet::puppetmaster ( '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', + 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', } } diff --git a/site/profiles/manifests/puppet/server.pp b/site/profiles/manifests/puppet/server.pp index ca68998..bfec7d1 100644 --- a/site/profiles/manifests/puppet/server.pp +++ b/site/profiles/manifests/puppet/server.pp @@ -27,6 +27,8 @@ class profiles::puppet::server ( String $autosign, String $default_manifest, String $default_environment, + Boolean $storeconfigs, + String $storeconfigs_backend, ) { file { '/etc/puppetlabs/puppet/puppet.conf': @@ -35,18 +37,20 @@ class profiles::puppet::server ( group => 'root', mode => '0644', content => epp('profiles/puppet/server/puppet.conf.epp', { - 'vardir' => $vardir, - 'logdir' => $logdir, - 'rundir' => $rundir, - 'pidfile' => $pidfile, - 'codedir' => $codedir, - 'dns_alt_names' => join($dns_alt_names, ','), - 'server' => $server, - 'node_terminus' => $node_terminus, - 'external_nodes' => $external_nodes, - 'autosign' => $autosign, - 'default_manifest' => $default_manifest, - 'default_environment' => $default_environment, + 'vardir' => $vardir, + 'logdir' => $logdir, + 'rundir' => $rundir, + 'pidfile' => $pidfile, + 'codedir' => $codedir, + 'dns_alt_names' => join($dns_alt_names, ','), + 'server' => $server, + 'node_terminus' => $node_terminus, + 'external_nodes' => $external_nodes, + 'autosign' => $autosign, + 'default_manifest' => $default_manifest, + 'default_environment' => $default_environment, + 'storeconfigs' => $storeconfigs, + 'storeconfigs_backend' => $storeconfigs_backend, }), notify => Service['puppetserver'], } diff --git a/site/profiles/templates/puppet/server/puppet.conf.epp b/site/profiles/templates/puppet/server/puppet.conf.epp index a22777b..c241a70 100644 --- a/site/profiles/templates/puppet/server/puppet.conf.epp +++ b/site/profiles/templates/puppet/server/puppet.conf.epp @@ -17,3 +17,5 @@ external_nodes = <%= $external_nodes %> autosign = <%= $autosign %> default_manifest = <%= $default_manifest %> default_environment = <%= $default_environment %> +storeconfigs = <%= $storeconfigs %> +storeconfigs_backend = <%= $storeconfigs_backend %> diff --git a/site/roles/manifests/puppet/puppetdb_api.pp b/site/roles/manifests/puppet/puppetdb_api.pp new file mode 100644 index 0000000..991102d --- /dev/null +++ b/site/roles/manifests/puppet/puppetdb_api.pp @@ -0,0 +1,6 @@ +# a role to deploy the puppetdb api service +class roles::puppet::puppetdb_api { + include profiles::defaults + include profiles::base + include profiles::puppet::puppetdb_api + } diff --git a/site/roles/manifests/puppet/puppetdb_sql.pp b/site/roles/manifests/puppet/puppetdb_sql.pp new file mode 100644 index 0000000..db640a3 --- /dev/null +++ b/site/roles/manifests/puppet/puppetdb_sql.pp @@ -0,0 +1,6 @@ +# a role to deploy the puppetdb postgresql service +class roles::puppet::puppetdb_sql { + include profiles::defaults + include profiles::base + include profiles::puppet::puppetdb_sql + } From 0171a82d58e79eda2877f5e8a2424cdd78c0ab84 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Mon, 23 Oct 2023 22:34:53 +1100 Subject: [PATCH 11/18] feat: add features to puppet.conf - reports, for sending reports to puppetdb - usecacheonfailure, to show faulures in puppetboard (when set to false) --- site/profiles/manifests/puppet/puppetmaster.pp | 2 ++ site/profiles/manifests/puppet/server.pp | 4 ++++ site/profiles/templates/puppet/server/puppet.conf.epp | 2 ++ 3 files changed, 8 insertions(+) diff --git a/site/profiles/manifests/puppet/puppetmaster.pp b/site/profiles/manifests/puppet/puppetmaster.pp index f2a559a..9819d5e 100644 --- a/site/profiles/manifests/puppet/puppetmaster.pp +++ b/site/profiles/manifests/puppet/puppetmaster.pp @@ -58,5 +58,7 @@ class profiles::puppet::puppetmaster ( default_environment => 'develop', storeconfigs => true, storeconfigs_backend => 'puppetdb', + reports => 'puppetdb', + usecacheonfailure => false, } } diff --git a/site/profiles/manifests/puppet/server.pp b/site/profiles/manifests/puppet/server.pp index bfec7d1..7f0aec5 100644 --- a/site/profiles/manifests/puppet/server.pp +++ b/site/profiles/manifests/puppet/server.pp @@ -29,6 +29,8 @@ class profiles::puppet::server ( String $default_environment, Boolean $storeconfigs, String $storeconfigs_backend, + String $reports, + Boolean $usecacheonfailure, ) { file { '/etc/puppetlabs/puppet/puppet.conf': @@ -51,6 +53,8 @@ class profiles::puppet::server ( 'default_environment' => $default_environment, 'storeconfigs' => $storeconfigs, 'storeconfigs_backend' => $storeconfigs_backend, + 'reports' => $reports, + 'usecacheonfailure' => $usecacheonfailure, }), notify => Service['puppetserver'], } diff --git a/site/profiles/templates/puppet/server/puppet.conf.epp b/site/profiles/templates/puppet/server/puppet.conf.epp index c241a70..226346d 100644 --- a/site/profiles/templates/puppet/server/puppet.conf.epp +++ b/site/profiles/templates/puppet/server/puppet.conf.epp @@ -19,3 +19,5 @@ default_manifest = <%= $default_manifest %> default_environment = <%= $default_environment %> storeconfigs = <%= $storeconfigs %> storeconfigs_backend = <%= $storeconfigs_backend %> +reports = <%= $reports %> +usecacheonfailure = <%= $usecacheonfailure %> From 46c3eb9597a0c7c183f0151103b8def5d650cd00 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Mon, 23 Oct 2023 22:30:15 +1100 Subject: [PATCH 12/18] feat: add puppetboard role - add nginx module to manage reverse proxy on host level - add puppetboard venv - add gunicorn instance - add script to start the gunicorn instance - add nginx vhost --- Puppetfile | 1 + hieradata/common.yaml | 4 + site/profiles/manifests/puppet/puppetboard.pp | 138 ++++++++++++++---- .../puppetboard/puppetboard.service.erb | 12 ++ .../puppet/puppetboard/start_puppetboard.erb | 7 + site/roles/manifests/puppet/puppetboard.pp | 6 + 6 files changed, 139 insertions(+), 29 deletions(-) create mode 100644 site/profiles/templates/puppet/puppetboard/puppetboard.service.erb create mode 100644 site/profiles/templates/puppet/puppetboard/start_puppetboard.erb create mode 100644 site/roles/manifests/puppet/puppetboard.pp diff --git a/Puppetfile b/Puppetfile index 5ad891a..e4f3c7d 100644 --- a/Puppetfile +++ b/Puppetfile @@ -20,6 +20,7 @@ mod 'puppet-yum', '7.0.0' mod 'puppet-archive', '7.0.0' mod 'puppet-chrony', '2.6.0' mod 'puppet-puppetboard', '9.0.0' +mod 'puppet-nginx', '5.0.0' # other mod 'ghoneycutt-puppet', '3.3.0' diff --git a/hieradata/common.yaml b/hieradata/common.yaml index eea398c..0a0ce3e 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -63,3 +63,7 @@ profiles::base::hosts::additional_hosts: hostname: prodinf01n05.main.unkin.net aliases: - prodinf01n05 + - ip: 198.18.17.6 + hostname: prodinf01n06.main.unkin.net + aliases: + - prodinf01n06 diff --git a/site/profiles/manifests/puppet/puppetboard.pp b/site/profiles/manifests/puppet/puppetboard.pp index 85d2d4e..0085eb5 100644 --- a/site/profiles/manifests/puppet/puppetboard.pp +++ b/site/profiles/manifests/puppet/puppetboard.pp @@ -1,43 +1,123 @@ # Class: profiles::puppet::puppetboard # -# This class manages the configuration of Puppetboard, a web frontend for PuppetDB. -# -# Parameters: -# - `python_version`: Specifies the Python version used for the virtualenv where Puppetboard runs. -# - `manage_virtualenv`: Determines if this class should handle the creation of the virtual environment for Puppetboard. -# - `reports_count`: Defines the number of reports to show per node in Puppetboard. -# - `offline_mode`: Determines if Puppetboard should work in offline mode or not. -# - `default_environment`: Sets the default Puppet environment to filter results in Puppetboard. -# -# Usage: -# This class can be called directly in your manifests or through Hiera. -# -# Example: -# To use the default parameters (as shown below), you can declare the class: -# -# include profiles::puppet::puppetboard -# -# Alternatively, you can customize the parameters: -# -# class { 'profiles::puppet::puppetboard': -# python_version => '3.8', -# reports_count => 50, -# offline_mode => false, -# } +# This class manages the Puppetboard, a web interface to PuppetDB. # class profiles::puppet::puppetboard ( - String $python_version = '3.6', - Boolean $manage_virtualenv = false, - Integer $reports_count = 40, - Boolean $offline_mode = true, - String $default_environment = '*', + String $python_version = '3.6', + Boolean $manage_virtualenv = false, + Integer $reports_count = 40, + Boolean $offline_mode = true, + String $default_environment = '*', + String $puppetdb_host = lookup('profiles::puppet::puppetdb::puppetdb_host'), + Stdlib::AbsolutePath $basedir = '/opt/puppetboard', + Stdlib::Absolutepath $virtualenv_dir = "${basedir}/venv", + Stdlib::Absolutepath $settings_file = "${basedir}/settings.py", + String $user = 'puppetboard', + String $group = 'puppetboard', + String $gunicorn_bind = '127.0.0.1:8080', + String $gunicorn_bind_prefix = 'http://', + Integer $gunicorn_workers = 1, + Integer $gunicorn_threads = 4, + String $nginx_vhost = 'puppetboard.main.unkin.net', + Integer $nginx_port = 80, + #String[1] $secret_key = "${fqdn_rand_string(32)}", ) { + # store puppet-agents ssl settings/certname + $ssl_dir = $::settings::ssldir + $puppetboard_certname = $trusted['certname'] + + # setup the puppetboard venv class { 'puppetboard': python_version => $python_version, manage_virtualenv => $manage_virtualenv, reports_count => $reports_count, offline_mode => $offline_mode, + basedir => $basedir, + virtualenv_dir => $virtualenv_dir, + settings_file => $settings_file, + #secret_key => $secret_key, default_environment => $default_environment, + puppetdb_host => $puppetdb_host, + puppetdb_port => 8081, + puppetdb_key => "${basedir}/ssl/${puppetboard_certname}.pem", + puppetdb_ssl_verify => "${ssl_dir}/certs/ca.pem", + puppetdb_cert => "${ssl_dir}/certs/${puppetboard_certname}.pem", + user => $user, + group => $group, + notify => Service['puppetboard.service'], + } + + # install gunicorn + python::pip { 'puppetboard_gunicorn': + ensure => 'latest', + pkgname => 'gunicorn', + virtualenv => $virtualenv_dir, + require => Class['puppetboard'], + } + + # create ssl dir for puppetboard + file { "${basedir}/ssl": + ensure => directory, + owner => $user, + group => $group, + mode => '0750', + require => Class['puppetboard'], + } + + # copy the ssl certs for puppetboard + file { "${basedir}/ssl/${puppetboard_certname}.pem": + ensure => present, + owner => $user, + group => $group, + mode => '0750', + source => "${ssl_dir}/private_keys/${puppetboard_certname}.pem", + require => File["${basedir}/ssl"], + notify => Service['puppetboard.service'], + } + + # create script to start service + file { "${virtualenv_dir}/bin/start_puppetboard": + ensure => file, + owner => $user, + group => $group, + mode => '0755', + content => template('profiles/puppet/puppetboard/start_puppetboard.erb'), + require => Class['puppetboard'], + notify => Service['puppetboard.service'], + } + + # create systemd service unit + systemd::unit_file { 'puppetboard.service': + content => template('profiles/puppet/puppetboard/puppetboard.service.erb'), + active => true, + enable => true, + require => File["${virtualenv_dir}/bin/start_puppetboard"], + } + + # ensure the nginx service is managed + class { 'nginx': } + + # create the nginx vhost + nginx::resource::server { $nginx_vhost: + listen_port => $nginx_port, + server_name => [$nginx_vhost], + proxy => "${gunicorn_bind_prefix}${gunicorn_bind}", + proxy_set_header => [ + 'Host $http_host', + 'X-Real-IP $remote_addr', + 'X-Scheme $scheme', + ], + proxy_pass_header => ['Server'], + proxy_redirect => 'off', + proxy_connect_timeout => '10s', + proxy_read_timeout => '10s', + } + + # service static files from nginx for performance + nginx::resource::location { "${nginx_vhost}_static": + location => '/static', + server => $nginx_vhost, + location_alias => "${virtualenv_dir}/lib/python${python_version}/site-packages/puppetboard/static", } } diff --git a/site/profiles/templates/puppet/puppetboard/puppetboard.service.erb b/site/profiles/templates/puppet/puppetboard/puppetboard.service.erb new file mode 100644 index 0000000..08fec4d --- /dev/null +++ b/site/profiles/templates/puppet/puppetboard/puppetboard.service.erb @@ -0,0 +1,12 @@ +[Unit] +Description=puppetboard daemon +After=network.target +[Service] +Type=simple +User=<%= @user %> +Group=<%= @group %> +Environment="PUPPETBOARD_SETTINGS=<%= @settings_file %>" +ExecStart=<%= @virtualenv_dir %>/bin/start_puppetboard +PrivateTmp=true +[Install] +WantedBy=multi-user.target diff --git a/site/profiles/templates/puppet/puppetboard/start_puppetboard.erb b/site/profiles/templates/puppet/puppetboard/start_puppetboard.erb new file mode 100644 index 0000000..46e6da3 --- /dev/null +++ b/site/profiles/templates/puppet/puppetboard/start_puppetboard.erb @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +<%= @virtualenv_dir %>/bin/gunicorn \ + --workers <%= @gunicorn_workers %> \ + --threads <%= @gunicorn_threads %> \ + --config <%= @settings_file %> \ + --bind <%= @gunicorn_bind %> \ + puppetboard.app:app diff --git a/site/roles/manifests/puppet/puppetboard.pp b/site/roles/manifests/puppet/puppetboard.pp new file mode 100644 index 0000000..34862c3 --- /dev/null +++ b/site/roles/manifests/puppet/puppetboard.pp @@ -0,0 +1,6 @@ +# a role to deploy the puppetboard +class roles::puppet::puppetboard { + include profiles::defaults + include profiles::base + include profiles::puppet::puppetboard + } From 130669a1301d630a395786b974d6eaed984e3d91 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 29 Oct 2023 20:17:07 +1100 Subject: [PATCH 13/18] feat: manage puppet clients - manage the service - manage the package, version lock it - deploy the /etc/puppetlabs/puppet/puppet.conf from template for puppet clients only --- hieradata/common.yaml | 10 ++++ site/profiles/manifests/base.pp | 6 +++ site/profiles/manifests/puppet/client.pp | 50 +++++++++++++++++++ .../templates/puppet/client/puppet.conf.erb | 13 +++++ 4 files changed, 79 insertions(+) create mode 100644 site/profiles/manifests/puppet/client.pp create mode 100644 site/profiles/templates/puppet/client/puppet.conf.erb diff --git a/hieradata/common.yaml b/hieradata/common.yaml index eea398c..0f3ff84 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -3,6 +3,9 @@ profiles::base::ntp_servers: - 0.au.pool.ntp.org - 1.au.pool.ntp.org +profiles::base::puppet_servers: + - 'prodinf01n01.main.unkin.net' + profiles::base::packages::common: - ccze - curl @@ -31,6 +34,13 @@ profiles::puppet::autosign::domains: # profiles::puppet::autosign::nodes: # - 'somenode.main.unkin.net' +profiles::puppet::client::puppet_version: '7.26.0' +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::enc::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::g10k::bin_path: '/opt/puppetlabs/bin/g10k' diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index 056d3e1..35874eb 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -1,6 +1,7 @@ # this is the base class, which will be used by all servers class profiles::base ( Array $ntp_servers, + Array $puppet_servers, ) { class { 'chrony': servers => $ntp_servers, @@ -24,6 +25,11 @@ class profiles::base ( ensure => 'installed', } + # manage puppet clients + if ! member($puppet_servers, $trusted['certname']) { + include profiles::puppet::client + } + # include admin scripts include profiles::base::scripts diff --git a/site/profiles/manifests/puppet/client.pp b/site/profiles/manifests/puppet/client.pp new file mode 100644 index 0000000..360e296 --- /dev/null +++ b/site/profiles/manifests/puppet/client.pp @@ -0,0 +1,50 @@ +# Class: profiles::puppet::client +# +# This class manages Puppet client 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. +# +# site/profile/manifests/puppet/client.pp +class profiles::puppet::client ( + String $dns_alt_names = $trusted['certname'], + String $server = 'puppetmaster', + String $ca_server = 'puppetca', + String $environment = 'develop', + Integer $runinterval = 1800, + Integer $runtimeout = 3600, + Boolean $show_diff = true, + Boolean $usecacheonfailure = false, + String $puppet_version = 'latest', +) { + + # Ensure the puppet-agent package is installed and locked to a specific version + package { 'puppet-agent': + ensure => $puppet_version, + } + + # Ensure the puppet service is running + service { 'puppet': + ensure => 'running', + enable => true, + hasrestart => true, + require => Package['puppet-agent'], + } + + # 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/templates/puppet/client/puppet.conf.erb b/site/profiles/templates/puppet/client/puppet.conf.erb new file mode 100644 index 0000000..e7a86c6 --- /dev/null +++ b/site/profiles/templates/puppet/client/puppet.conf.erb @@ -0,0 +1,13 @@ +[main] +dns_alt_names = <%= @dns_alt_names %> + +[agent] +server = <%= @server %> +ca_server = <%= @ca_server %> +environment = <%= @environment %> +report = true +report_server = <%= @server %> +runinterval = <%= @runinterval %> +runtimeout = <%= @runtimeout %> +show_diff = <%= @show_diff %> +usecacheonfailure = <%= @usecacheonfailure %> From 5076d7383a8594a7d564ac22d02ab8a69b7e2ba0 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Thu, 2 Nov 2023 20:12:47 +1100 Subject: [PATCH 14/18] feat: add ceph osd/mds/mon roles - basic roles currently - will allow build of ceph to begin --- site/roles/manifests/ceph/mds.pp | 6 ++++++ site/roles/manifests/ceph/mon.pp | 6 ++++++ site/roles/manifests/ceph/osd.pp | 6 ++++++ 3 files changed, 18 insertions(+) create mode 100644 site/roles/manifests/ceph/mds.pp create mode 100644 site/roles/manifests/ceph/mon.pp create mode 100644 site/roles/manifests/ceph/osd.pp diff --git a/site/roles/manifests/ceph/mds.pp b/site/roles/manifests/ceph/mds.pp new file mode 100644 index 0000000..a7a6a2e --- /dev/null +++ b/site/roles/manifests/ceph/mds.pp @@ -0,0 +1,6 @@ +# a role to deploy the ceph mds +# work in progress +class roles::ceph::mds { + include profiles::defaults + include profiles::base +} diff --git a/site/roles/manifests/ceph/mon.pp b/site/roles/manifests/ceph/mon.pp new file mode 100644 index 0000000..b1fe65a --- /dev/null +++ b/site/roles/manifests/ceph/mon.pp @@ -0,0 +1,6 @@ +# a role to deploy the ceph mon +# work in progress +class roles::ceph::mon { + include profiles::defaults + include profiles::base +} diff --git a/site/roles/manifests/ceph/osd.pp b/site/roles/manifests/ceph/osd.pp new file mode 100644 index 0000000..047718a --- /dev/null +++ b/site/roles/manifests/ceph/osd.pp @@ -0,0 +1,6 @@ +# a role to deploy the ceph osd +# work in progress +class roles::ceph::osd { + include profiles::defaults + include profiles::base +} From 75a66a3339fb41f5958a8f9e820b45280d6b364f Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Thu, 2 Nov 2023 22:08:00 +1100 Subject: [PATCH 15/18] fix: digitalpacific epel repodata broken - change epel to read from aarnet --- hieradata/os/AlmaLinux/all_releases.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hieradata/os/AlmaLinux/all_releases.yaml b/hieradata/os/AlmaLinux/all_releases.yaml index 230dbd0..e749c94 100644 --- a/hieradata/os/AlmaLinux/all_releases.yaml +++ b/hieradata/os/AlmaLinux/all_releases.yaml @@ -1,7 +1,7 @@ # hieradata/os/almalinux/all_releases.yaml --- profiles::yum::base::baseurl: http://almalinux.mirror.digitalpacific.com.au -profiles::yum::epel::baseurl: http://epel.mirror.digitalpacific.com.au +profiles::yum::epel::baseurl: http://mirror.aarnet.edu.au/pub/epel profiles::firewall::firewalld::ensure_package: 'absent' profiles::firewall::firewalld::ensure_service: 'stopped' profiles::firewall::firewalld::enable_service: false From a89a68bc61a9838c83eaa37633e9efbd467f1205 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Thu, 2 Nov 2023 22:14:38 +1100 Subject: [PATCH 16/18] fix: debian puppet_version different to EL - change puppet_version to be set per-os in hieradata --- hieradata/common.yaml | 1 - hieradata/os/AlmaLinux/all_releases.yaml | 2 ++ hieradata/os/Debian/Debian11.yaml | 2 ++ hieradata/os/Debian/Debian12.yaml | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 4ab4245..3a828ea 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -34,7 +34,6 @@ profiles::puppet::autosign::domains: # profiles::puppet::autosign::nodes: # - 'somenode.main.unkin.net' -profiles::puppet::client::puppet_version: '7.26.0' profiles::puppet::client::environment: 'develop' profiles::puppet::client::runinterval: 1800 profiles::puppet::client::runtimeout: 3600 diff --git a/hieradata/os/AlmaLinux/all_releases.yaml b/hieradata/os/AlmaLinux/all_releases.yaml index e749c94..bdb6ccb 100644 --- a/hieradata/os/AlmaLinux/all_releases.yaml +++ b/hieradata/os/AlmaLinux/all_releases.yaml @@ -5,3 +5,5 @@ profiles::yum::epel::baseurl: http://mirror.aarnet.edu.au/pub/epel profiles::firewall::firewalld::ensure_package: 'absent' profiles::firewall::firewalld::ensure_service: 'stopped' profiles::firewall::firewalld::enable_service: false + +profiles::puppet::client::puppet_version: '7.26.0' diff --git a/hieradata/os/Debian/Debian11.yaml b/hieradata/os/Debian/Debian11.yaml index 8ed26ec..41e6201 100644 --- a/hieradata/os/Debian/Debian11.yaml +++ b/hieradata/os/Debian/Debian11.yaml @@ -10,3 +10,5 @@ profiles::apt::components: - contrib - main - non-free + +profiles::puppet::client::puppet_version: '7.25.0-1bullseye' diff --git a/hieradata/os/Debian/Debian12.yaml b/hieradata/os/Debian/Debian12.yaml index 7063126..fab31d1 100644 --- a/hieradata/os/Debian/Debian12.yaml +++ b/hieradata/os/Debian/Debian12.yaml @@ -11,3 +11,5 @@ profiles::apt::components: - main - non-free - non-free-firmware + +profiles::puppet::client::puppet_version: 'latest' From 0cc0bacad33b26b8c79caa41ca674ef603a02d65 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 4 Nov 2023 18:12:35 +1100 Subject: [PATCH 17/18] feat: add motd and facts - use parameters created by the enc to create external facts - use external facts to generate the motd - use features from https://git.unkin.net/unkinben/puppet-enc/pulls/22 --- site/profiles/manifests/base.pp | 4 +++ site/profiles/manifests/base/facts.pp | 29 +++++++++++++++++++ site/profiles/manifests/base/motd.pp | 20 +++++++++++++ .../profiles/templates/base/facts/enc_env.erb | 1 + .../templates/base/facts/enc_role.erb | 1 + site/profiles/templates/base/motd/motd.erb | 13 +++++++++ 6 files changed, 68 insertions(+) create mode 100644 site/profiles/manifests/base/facts.pp create mode 100644 site/profiles/manifests/base/motd.pp create mode 100644 site/profiles/templates/base/facts/enc_env.erb create mode 100644 site/profiles/templates/base/facts/enc_role.erb create mode 100644 site/profiles/templates/base/motd/motd.erb diff --git a/site/profiles/manifests/base.pp b/site/profiles/manifests/base.pp index 35874eb..e1a98c0 100644 --- a/site/profiles/manifests/base.pp +++ b/site/profiles/manifests/base.pp @@ -52,4 +52,8 @@ class profiles::base ( # default users include profiles::accounts::sysadmin + # add a motd + include profiles::base::facts + include profiles::base::motd + } diff --git a/site/profiles/manifests/base/facts.pp b/site/profiles/manifests/base/facts.pp new file mode 100644 index 0000000..e234625 --- /dev/null +++ b/site/profiles/manifests/base/facts.pp @@ -0,0 +1,29 @@ +# a class to define some global facts +class profiles::base::facts { + + # The path where external facts are stored + $facts_d_path = '/opt/puppetlabs/facter/facts.d' + + # Ensure the directory exists + file { $facts_d_path: + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + # facts to create + $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], + } + } +} diff --git a/site/profiles/manifests/base/motd.pp b/site/profiles/manifests/base/motd.pp new file mode 100644 index 0000000..e1dd5ca --- /dev/null +++ b/site/profiles/manifests/base/motd.pp @@ -0,0 +1,20 @@ +# set the motd +class profiles::base::motd ( + String $enc_role = pick($facts['enc_role'], 'undefined'), + String $enc_env = pick($facts['enc_env'], 'undefined'), + String $fqdn = $facts['networking']['fqdn'], + String $addr = $facts['networking']['ip'], + String $nic = $facts['networking']['primary'], + String $os_name = $facts['os']['name'], + String $os_release = $facts['os']['release']['full'], +) { + + # Use the regsubst function to remove the 'roles::' prefix from the role name + $clean_role = regsubst($enc_role, '^roles::', '') + + # Manage the content of the /etc/motd file + file { '/etc/motd': + ensure => file, + content => template('profiles/base/motd/motd.erb'), + } +} diff --git a/site/profiles/templates/base/facts/enc_env.erb b/site/profiles/templates/base/facts/enc_env.erb new file mode 100644 index 0000000..7695e4d --- /dev/null +++ b/site/profiles/templates/base/facts/enc_env.erb @@ -0,0 +1 @@ +enc_env=<%= @enc_env %> diff --git a/site/profiles/templates/base/facts/enc_role.erb b/site/profiles/templates/base/facts/enc_role.erb new file mode 100644 index 0000000..d59acdf --- /dev/null +++ b/site/profiles/templates/base/facts/enc_role.erb @@ -0,0 +1 @@ +enc_role=<%= @enc_role[0] %> diff --git a/site/profiles/templates/base/motd/motd.erb b/site/profiles/templates/base/motd/motd.erb new file mode 100644 index 0000000..7ca06df --- /dev/null +++ b/site/profiles/templates/base/motd/motd.erb @@ -0,0 +1,13 @@ +<% +# calculate padding for the longest word +max_length = ['fqdn:', 'os:', 'role:', 'branch:', 'addr:', 'nic:'].max_by(&:length).length +# helper lambda to right-align text +align = ->(word) { word.ljust(max_length) } +%> +<%= align.call('fqdn:') %> <%= @fqdn %> +<%= align.call('os:') %> <%= @os_name %> <%= @os_release %> +<%= align.call('role:') %> <%= @clean_role %> +<%= align.call('branch:') %> <%= @enc_env %> +<%= align.call('addr:') %> <%= @addr %> +<%= align.call('nic:') %> <%= @nic %> + From 56518f1fcb94d265f4add099351e844194555fb4 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 4 Nov 2023 20:25:35 +1100 Subject: [PATCH 18/18] feat: change enc repo to be tagged - enc repository will download a specific tag - defaults to master - hiera set to release tag '0.1' --- hieradata/common.yaml | 4 +++- site/profiles/manifests/puppet/enc.pp | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 3a828ea..b8267f4 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -40,7 +40,9 @@ profiles::puppet::client::runtimeout: 3600 profiles::puppet::client::show_diff: true profiles::puppet::client::usecacheonfailure: false -profiles::puppet::enc::enc_repo: https://git.unkin.net/unkinben/puppet-enc.git +profiles::puppet::enc::repo: https://git.unkin.net/unkinben/puppet-enc.git +profiles::puppet::enc::release: '0.1' +profiles::puppet::enc::force: true profiles::puppet::r10k::r10k_repo: https://git.unkin.net/unkinben/puppet-r10k.git profiles::puppet::g10k::bin_path: '/opt/puppetlabs/bin/g10k' profiles::puppet::g10k::cfg_path: '/etc/puppetlabs/r10k/r10k.yaml' diff --git a/site/profiles/manifests/puppet/enc.pp b/site/profiles/manifests/puppet/enc.pp index 6745587..4e84227 100644 --- a/site/profiles/manifests/puppet/enc.pp +++ b/site/profiles/manifests/puppet/enc.pp @@ -34,7 +34,9 @@ # This is designed to work on Unix-like systems only. # class profiles::puppet::enc ( - String $enc_repo, + String $repo, + String $release = 'master', + Boolean $force = false, ) { include profiles::git::git @@ -42,7 +44,9 @@ class profiles::puppet::enc ( vcsrepo { '/opt/puppetlabs/enc': ensure => latest, provider => git, - source => $enc_repo, + source => $repo, + revision => $release, + force => $force, require => Package['git'], }