diff --git a/REFERENCE.md b/REFERENCE.md
index 3936bc75..6cdaba49 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -9,6 +9,7 @@
#### Public Classes
* [`letsencrypt`](#letsencrypt): Install and configure Certbot, the LetsEncrypt client
+* [`letsencrypt::plugin::apache`](#letsencrypt--plugin--apache): install and configure the Let's Encrypt apache plugin
* [`letsencrypt::plugin::dns_cloudflare`](#letsencrypt--plugin--dns_cloudflare): Installs and configures the dns-cloudflare plugin
* [`letsencrypt::plugin::dns_rfc2136`](#letsencrypt--plugin--dns_rfc2136): Installs and configures the dns-rfc2136 plugin
* [`letsencrypt::plugin::dns_route53`](#letsencrypt--plugin--dns_route53): Installs and configures the dns-route53 plugin
@@ -338,6 +339,33 @@ certificate. Two environmental variables are supplied by certbot:
Default value: `[]`
+### `letsencrypt::plugin::apache`
+
+install and configure the Let's Encrypt apache plugin
+
+#### Parameters
+
+The following parameters are available in the `letsencrypt::plugin::apache` class:
+
+* [`manage_package`](#-letsencrypt--plugin--apache--manage_package)
+* [`package_name`](#-letsencrypt--plugin--apache--package_name)
+
+##### `manage_package`
+
+Data type: `Boolean`
+
+Manage the plugin package.
+
+Default value: `true`
+
+##### `package_name`
+
+Data type: `String[1]`
+
+The name of the package to install when $manage_package is true.
+
+Default value: `'python3-certbot-apache'`
+
### `letsencrypt::plugin::dns_cloudflare`
This class installs and configures the Let's Encrypt dns-cloudflare plugin.
diff --git a/data/os/CentOS/7.yaml b/data/os/CentOS/7.yaml
index 3920067f..65f6516b 100644
--- a/data/os/CentOS/7.yaml
+++ b/data/os/CentOS/7.yaml
@@ -3,3 +3,4 @@ letsencrypt::plugin::dns_rfc2136::package_name: 'python2-certbot-dns-rfc2136'
letsencrypt::plugin::dns_route53::package_name: 'python2-certbot-dns-route53'
letsencrypt::plugin::dns_cloudflare::package_name: 'python2-certbot-dns-cloudflare'
letsencrypt::plugin::nginx::package_name: 'python2-certbot-nginx'
+letsencrypt::plugin::apache::package_name: 'python2-certbot-apache'
diff --git a/data/os/RedHat/7.yaml b/data/os/RedHat/7.yaml
index 3920067f..65f6516b 100644
--- a/data/os/RedHat/7.yaml
+++ b/data/os/RedHat/7.yaml
@@ -3,3 +3,4 @@ letsencrypt::plugin::dns_rfc2136::package_name: 'python2-certbot-dns-rfc2136'
letsencrypt::plugin::dns_route53::package_name: 'python2-certbot-dns-route53'
letsencrypt::plugin::dns_cloudflare::package_name: 'python2-certbot-dns-cloudflare'
letsencrypt::plugin::nginx::package_name: 'python2-certbot-nginx'
+letsencrypt::plugin::apache::package_name: 'python2-certbot-apache'
diff --git a/manifests/certonly.pp b/manifests/certonly.pp
index b04f94b5..f8148ad2 100644
--- a/manifests/certonly.pp
+++ b/manifests/certonly.pp
@@ -216,6 +216,17 @@
}
}
+ 'apache': {
+ require letsencrypt::plugin::apache
+
+ if $ensure == 'present' {
+ $_domains = join($domains, '\' -d \'')
+ $plugin_args = "--cert-name '${cert_name}' -d '${_domains}'"
+ } else {
+ $plugin_args = "--cert-name '${cert_name}'"
+ }
+ }
+
default: {
if $ensure == 'present' {
$_domains = join($domains, '\' -d \'')
diff --git a/manifests/plugin/apache.pp b/manifests/plugin/apache.pp
new file mode 100644
index 00000000..500dbc9d
--- /dev/null
+++ b/manifests/plugin/apache.pp
@@ -0,0 +1,16 @@
+# @summary install and configure the Let's Encrypt apache plugin
+#
+# @param manage_package Manage the plugin package.
+# @param package_name The name of the package to install when $manage_package is true.
+class letsencrypt::plugin::apache (
+ Boolean $manage_package = true,
+ String[1] $package_name = 'python3-certbot-apache',
+) {
+ include letsencrypt
+
+ if $manage_package {
+ package { $package_name:
+ ensure => $letsencrypt::package_ensure,
+ }
+ }
+}
diff --git a/spec/acceptance/letsencrypt_plugin_apache_spec.rb b/spec/acceptance/letsencrypt_plugin_apache_spec.rb
new file mode 100644
index 00000000..f3e6732e
--- /dev/null
+++ b/spec/acceptance/letsencrypt_plugin_apache_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper_acceptance'
+
+describe 'letsencrypt::plugin::apache' do
+ it_behaves_like 'an idempotent resource' do
+ let(:manifest) do
+ <<-PUPPET
+ include letsencrypt
+ include letsencrypt::plugin::apache
+ PUPPET
+ end
+ end
+end
diff --git a/spec/classes/plugin/apache_spec.rb b/spec/classes/plugin/apache_spec.rb
new file mode 100644
index 00000000..a9b739e0
--- /dev/null
+++ b/spec/classes/plugin/apache_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'letsencrypt::plugin::apache' do
+ on_supported_os.each do |os, os_facts|
+ context "on #{os}" do
+ let(:facts) { os_facts }
+ let(:params) { {} }
+ let(:pre_condition) do
+ <<-PUPPET
+ class { 'letsencrypt':
+ email => 'foo@example.com',
+ }
+ PUPPET
+ end
+ let(:package_name) do
+ if facts[:os]['family'] == 'RedHat' && facts[:os]['release']['major'] == '7'
+ 'python2-certbot-apache'
+ else
+ 'python3-certbot-apache'
+ end
+ end
+
+ context 'with default parameters' do
+ it { is_expected.to compile.with_all_deps }
+
+ it 'installs the certbot apache plugin' do
+ is_expected.to contain_class('letsencrypt::plugin::apache')
+ is_expected.to contain_package(package_name).with_ensure('installed')
+ end
+
+ describe 'with manage_package => false' do
+ let(:params) { super().merge(manage_package: false, package_name: 'apache-package') }
+
+ it { is_expected.not_to contain_package('apache-package') }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/defines/letsencrypt_certonly_spec.rb b/spec/defines/letsencrypt_certonly_spec.rb
index 26c5ee77..761a5833 100644
--- a/spec/defines/letsencrypt_certonly_spec.rb
+++ b/spec/defines/letsencrypt_certonly_spec.rb
@@ -185,6 +185,26 @@ class { 'letsencrypt::plugin::nginx':
it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a nginx --cert-name 'foo.example.com' -d 'foo.example.com'" }
end
+ context 'with apache plugin' do
+ let(:title) { 'foo.example.com' }
+ let(:params) { { plugin: 'apache', letsencrypt_command: 'letsencrypt' } }
+ let(:pre_condition) do
+ <<-PUPPET
+ class { 'letsencrypt':
+ email => 'foo@example.com',
+ config_dir => '/etc/letsencrypt',
+ }
+ class { 'letsencrypt::plugin::apache':
+ package_name => 'irrelevant',
+ }
+ PUPPET
+ end
+
+ it { is_expected.to compile.with_all_deps }
+ it { is_expected.to contain_class('letsencrypt::plugin::apache') }
+ it { is_expected.to contain_exec('letsencrypt certonly foo.example.com').with_command "letsencrypt --text --agree-tos --non-interactive certonly --rsa-key-size 4096 -a apache --cert-name 'foo.example.com' -d 'foo.example.com'" }
+ end
+
context 'with dns-cloudflare plugin' do
let(:title) { 'foo.example.com' }
let(:params) { { plugin: 'dns-cloudflare', letsencrypt_command: 'letsencrypt' } }