我想通过Puppet设置和configurationApache,并通过acme_tiny.py申请一个SSL证书。 我的Puppet类和资源用于Web服务器,并且在大多数情况下,除了第一次启动之外,还可以用于极其微小的工作。
不幸的是,acme_tiny需要一个正在运行的web服务器,这个服务器在acme_tiny资源成功完成之后才会启动。 我想这个stream程应该是这样的:
安装Apache – >启动Apache – >configurationHTTP虚拟主机 – >重新加载Apache – >运行acme_tiny – >configurationHTTPS虚拟主机 – >重新加载Apache
问题是资源“apache2 reload”只能在Puppet中存在一次,如果我在两者之间订购了acme_tiny资源,我会得到一个依赖周期。 此外,资源也由puppetlabs / apache模块pipe理,每次创build一个新的虚拟主机时,只有最后一个应用。 目前,stream程是这样的:
安装Apache – >启动Apache – >configurationHTTP虚拟主机 – >运行acme_tiny(失败) – >configurationHTTPS虚拟主机(跳过由于失败的依赖项) – >configuration其他所有 – >重新加载Apache(跳过由于失败的依赖项)
如果我在第一次运行后手动启动Apache2,则一切正常:检索证书,创buildHTTPS虚拟主机并重新加载Web服务器。 不幸的是,没有人工干预就无法工作。
我最小的资源看起来像这样:
exec { "${url}.crt": command => "acme_tiny.py --quiet --account-key ./${url}_account.key --csr ./${url}.csr --acme-dir /home/web/${url}/www > ${url}.crt", path => [ '/usr/bin', '/usr/local/bin' ], cwd => $profile::apache::params::ssl_dir, require => File['acme_tiny.py'], subscribe => File["${profile::apache::params::ssl_dir}/${url}.csr"], notify => Service['apache2'], }
有没有人有一个想法如何解决这个问题? 理想情况下,它应该全部在一个Puppet运行中完成,如果需要第二个Puppet运行而不需要手动干预,第二个最佳select是。 本质上,如果acme_tiny失败,只有HTTPS虚拟主机的configuration会失败,但不能重新加载Apache。
我设法做一点点肮脏的黑客,但至less它的作品。
我看到在Puppet安装了这个包之后,Apache已经在默认的Debian里面运行了,但是Puppet重新configuration了它(并且在最后发布了一个apache reload
)。 幸运的是,Web服务器已经通过提供静态文件来响应所有请求。
然后我将acme_tiny资源分为两部分:安装和更新:对于安装,Puppet首先创build文件夹/var/www/html/.well-known/acme-challenge
,然后执行下面的exec:
# Request a new certificate if the crt file does not yet exist exec { "${url}.crt initial": command => "acme_tiny.py --quiet --account-key ./${url}_account.key --csr ./${url}.csr --acme-dir /var/www/html/.well-known/acme-challenge > ${url}.crt", creates => "${profile::apache::params::ssl_dir}/${url}.crt", path => [ '/usr/bin', '/usr/local/bin' ], cwd => $profile::apache::params::ssl_dir, require => [ File['acme_tiny.py'], File['/var/www/html/.well-known/acme-challenge'] ], subscribe => File["${profile::apache::params::ssl_dir}/${url}.csr"], notify => Service['apache2'], }
如果证书已经存在,则不会执行此资源(因此将creates
参数)。
在随后的每一次运行中,续订执行都将被执行:
exec { "${url}.crt renewal": command => "acme_tiny.py --quiet --account-key ./${url}_account.key --csr ./${url}.csr --acme-dir /home/web/${url}/www > ${url}.crt", unless => ["openssl x509 -checkend 2592000 -noout -in ${url}.crt", "test ! -f ${url}.crt" ], path => [ '/usr/bin', '/usr/local/bin' ], cwd => $profile::apache::params::ssl_dir, require => File['acme_tiny.py'], subscribe => File["${profile::apache::params::ssl_dir}/${url}.csr"], notify => Service['apache2'], }
只有当现有证书有效期不超过一个月且证书已经存在时才执行该执行程序。
这应该使exec相互排斥,以便在一个Puppet运行中只执行一个exec。
还有一些设置要做(即使在初始设置之后也要创build一个默认的虚拟主机,例如,如果你想在已经运行的networking服务器上configuration第二个虚拟主机),但是我目前工作的很好。
这并没有回答Puppet的问题(因为它目前依赖于Apache的“function”),但实际上我非常怀疑它可能与Puppet:Puppet的核心function是非常资源只能应用一次。