puppet-prod/site/profiles/manifests/pki/vault.pp
Ben Vincent 0782cd5679 feat: dynamically add subscribe to nginx resource
- add subscribe option to nginx resource dependent on nginx_listen_mode
- ensure nginx reloads when the ssl_cert or ssl_key changes, only if
  these values are not undef
- ensure the file resources are defined for certificates
2024-03-03 16:25:51 +11:00

127 lines
3.7 KiB
Puppet

# 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 { $base_path:
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}
# 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"),
}
# 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],
}
}
}
}