diff --git a/README.md b/README.md
index 426e8f8914291ea0dfe5dc9bb5de275aef7e2cf1..d4e99e3bca309e6fe73540de63c96f6788487861 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,7 @@
* [`freeradius::sql`](#freeradiussql)
* [`freeradius::statusclient`](#freeradiusstatusclient)
* [`freeradius::template`](#freeradiustemplate)
+ * [`freeradius::virtual_module`](#freeradiusvirtual_module)
4. [Limitations - OS compatibility, etc.](#limitations)
5. [Development - Guide for contributing to the module](#development)
6. [Release Notes](#release-notes)
@@ -758,6 +759,29 @@ Provide source to a file with the template item. Specify only one of `source` or
Provide content of template item. Specify only one of `source` or `content`.
+#### `freeradius::virtual_module`
+
+Define a virtual module which consists of one or more other modules, for failover or
+load-balancing purposes.
+
+##### `name`
+##### `submodules`
+##### `type`
+
+```puppet
+freeradius::virtual_module { 'myldap':
+ submodules => ['ldap1', 'ldap2'],
+ type => 'redundant-load-balance',
+}
+```
+yields
+```
+redundant-load-balance myldap {
+ ldap1
+ ldap2
+}
+```
+
## Limitations
This module is targeted at FreeRADIUS 3.x running on CentOS 7. It will not work on
diff --git a/manifests/virtual_module.pp b/manifests/virtual_module.pp
new file mode 100644
index 0000000000000000000000000000000000000000..1006f436f5f03df96eb0c66642600ff233f13c0a
--- /dev/null
+++ b/manifests/virtual_module.pp
@@ -0,0 +1,38 @@
+# Define a virtual module, made up of others
+define freeradius::virtual_module (
+ $submodules,
+ $ensure = present,
+ $type = 'redundant-load-balance',
+) {
+ $fr_package = $::freeradius::params::fr_package
+ $fr_service = $::freeradius::params::fr_service
+ $fr_basepath = $::freeradius::params::fr_basepath
+ $fr_group = $::freeradius::params::fr_group
+
+ # Valid types of virtual module from
+ # http://wiki.freeradius.org/config/load-balancing
+ # http://wiki.freeradius.org/config/Fail-over#virtual-modules
+ validate_re($type, [
+ '^redundant$',
+ '^load-balance$',
+ '^redundant-load-balance$',
+ '^group$',
+ ])
+
+ # Make sure $submodules is a non-zero array
+ $submodules = any2array($submodules)
+ validate_array($submodules)
+ if count($submodules) < 1 {
+ fail('Must specify at least one $submodule')
+ }
+
+ file { "${fr_basepath}/instantiate/${name}":
+ ensure => $ensure,
+ mode => '0640',
+ owner => 'root',
+ group => $fr_group,
+ content => template('freeradius/virtual_module.erb'),
+ require => [Package[$fr_package], Group[$fr_group]],
+ notify => Service[$fr_service],
+ }
+}
diff --git a/templates/virtual_module.erb b/templates/virtual_module.erb
new file mode 100644
index 0000000000000000000000000000000000000000..1b212278aa37f60f847c93df9ec7e46da7f818fd
--- /dev/null
+++ b/templates/virtual_module.erb
@@ -0,0 +1,5 @@
+<%= @type %> <%= @name %> {
+<% @submodules.each do |submod| -%>
+ <%= submod %>
+<% end -%>
+}