Table of Contents
- Overview
- Module Description
- Upgrading
- Reporting
- Usage
- Reference
- Enforcement
- Limitations
- Development
- Packaging
This module adds a function compliance_map()
to the Puppet language. The
compliance_map()
function provides the ability for users to compare their
in-scope class parameters against a set of compliant parameters, either in
Hiera or at the global scope. Users may also provide custom inline policy
documentation and mapping documentation.
The goal of this module is to make it easier for users to both detect, and report on, deviations from a given policy inside their Puppet codebase.
This module provides the function compliance_map()
and a compliance_markup
class for including the functionality into your stack at the global level.
A utility for converting your old compliance_map()
Hiera data has also been
included in the utils
directory.
A utility script, compliance_map_migrate
has been included in the utils
directory of the module to upgrade your old compliance data to newer formats.
At minimum, you must pass to the script a compliance profile to migrate, the version of the API it was compatible with, and the version you wish to migrate it to. For instance, to upgrade a compliance map from API 0.0.1 to 1.0.0:
ruby compliance_map_migrate -i /etc/puppetlabs/code/environments/simp/hieradata/compliance_profiles/nist_800_53_rev4.yaml -s 0.0.1 -d 1.0.0
Please validate that the migrated YAML files work as expected prior to deploying them into production.
By default, the compliance_map()
function creates a set of reports, one per
node, on your Puppet Server at
/opt/puppetlabs/server/data/puppetserver/simp/compliance_reports/<fqdn>
.
You may optionally enable the creation of a File
resource on each of your
clients if you wish to have changes in this data automatically exported into
PuppetDB
.
The compliance_map()
function provides a mechanism for mapping compliance
data to settings in Puppet and should be globally activated by including
the
compliance_markup
class.
It is primarily designed for use in classes to validate that parameters are properly set but may also be used to perform a full compliance report against multiple profiles across your code base at compile time.
When the compliance_markup
class is included, the parameters in all in-scope
classes and defined types will be evaluated against top level parameters,
lookup()
values, or Hiera data, in that order.
The variable space against which the parameters will be evaluated must be structured as the following hash:
compliance_map :
<compliance_profile> :
<class_name>::<parameter> :
'identifiers' :
- 'ID String'
'value' : 'Compliant Value'
'notes' : 'Optional Notes'
For instance, if you were mapping to NIST 800-53
in the SSH
class, you
would use something like the following:
compliance_map :
nist_800_53 :
ssh::permit_root_login :
'identifiers' :
- 'CCE-1234'
'value' : false
Alternatively, you may use the compliance_map()
function to add compliance
data to your modules outside of a parameter mapping. This is useful if you have
more advanced logic that is required to meet a particular internal requirement.
NOTE: The parser does not know what line number and, possibly, what file the function is being called from based on the version of the Puppet parser being used.
The following parameters may be used to add your own compliance data:
:compliance_profile => 'A String, or Array, that denotes the compliance
profile(s) to which you are mapping.'
:identifiers => 'An array of identifiers for the policy to which you
are mapping.'
:notes => 'An *optional* String that allows for arbitrary notes to
include in the compliance report'
The compliance report is formatted as follows (YAML Representation):
---
# The API version of the report
version: "1.0.1"
fqdn: "my.system.fqdn"
hostname: "my"
ipaddress: "1.2.3.4"
puppetserver_info: "my.puppet.server"
compliance_profiles:
profile_name:
summary:
compliant: 80
non_compliant: 20
percent_compliant: 80
documented_missing_resources: 2
documented_missing_parameters: 1
compliant:
"Class[ClassName]":
parameters:
param1:
identifiers:
- ID 1
- ID 2
compliant_value: 'foo'
system_value: 'foo'
non_compliant:
"Class[BadClass]":
parameters:
bad_param:
identifiers:
- ID 3
- ID 4
compliant_value: 'bar'
system_value: 'baz'
documented_missing_resources:
- missing_class_one
- missing_class_two
documented_missing_parameters:
- "classname::param2"
custom_entries
"Class[CustomClass]":
location: "file.pp:123"
identifiers:
- My ID
site_data:
completely: random user input
The compliance_markup
class may take a number of options which must be passed
as a Hash
.
Default: [ 'non_compliant', 'unknown_parameters', 'custom_entries' ]
A String, or Array that denotes which types of reports should be generated.
Valid Types:
- full: The full report, with all other types included.
- non_compliant: Items that differ from the reference will be reported.
- compliant: Compliant items will be reported.
- unknown_resources: Reference resources without a system value will be reported.
- unknown_parameters: Reference parameters without a system value will be reported.
- custom_entries: Any one-off custom calls to compliance_map will be reported.
Default: None
A valid Hash that will be converted as passed and emitted into your node compliance report.
This can be used to add site-specific or other information to the report that may be useful for post-processing.
Default: false
A Boolean which, if set, will place a copy of the report on the client itself. This will ensure that PuppetDB will have a copy of the report for later processing.
Default: true
A Boolean which, if set, will store a copy of the report on the Server.
Default: Puppet[:vardir]/simp/compliance_reports
An Absolute Path that specifies the location on
Default: Puppet[:vardir]/simp/compliance_reports
An Absolute Path that specifies the location on the server where the reports should be stored.
A directory will be created for each FQDN that has a report.
Default: false
A Boolean which, if set, will dump a compatible compliance_map of all resources and defines that are in the current catalog.
This will be written to server_report_dir/<client_fqdn>
as catalog_compliance_map
.
Old versions will be overwritten.
NOTE: This is an experimental feature and subject to change without notice.
The full module reference can be found in the
module docs and in the
local docs/
directory.
Manifest
class foo (
$var_one => 'one',
$var_two => 'two'
) {
notify { 'Sample Class': }
}
$compliance_profile = 'my_policy'
include '::foo'
include '::compliance_markup'
Hiera.yaml
:backends:
- 'yaml'
:yaml:
:datadir: '/path/to/your/hieradata'
:hierarchy:
"global"
Hieradata
---
# In file /path/to/your/hieradata/global.yaml
compliance_map :
my_policy :
foo::var_one :
'identifiers' :
- 'POLICY_SECTION_ID'
'value' : 'one'
if $::circumstance {
compliance_map('my_policy','POLICY_SECTION_ID','Note about this section')
...code that applies POLICY_SECTION_ID...
}
This module also contains an experimental Hiera backend that can be used to enforce compliance profile settings on any module when it is included. It uses the compliance_markup::enforcement array to determine the profiles to use, and which profiles take priority.
Both a legacy v3 backend, and a modern Hiera v5 backend have been provided. It is highly recommended to use the Hiera v5 backend if the puppet agent on your puppetservers are 4.9 or higher.
---
version: 5
hierarchy:
- name: Compliance
lookup_key: compliance_markup::enforcement
- name: Common
path: default.yaml
defaults:
data_hash: yaml_data
datadir: "/etc/puppetlabs/code/environments/production/hieradata"
---
:backends:
- yaml
- simp_compliance_enforcement
:yaml:
:datadir: "/etc/puppetlabs/code/environments/%{environment}/hieradata"
:simp_compliance_enforcement:
:datadir: "/etc/puppetlabs/code/environments/%{environment}/hieradata"
:hierarchy:
- default
:logger: console
To enforce disa stig + nist, with disa stig compliance settings taking priority, add the following to your hiera data files. This will work like any hiera setting, so you can set enforcement based on any factor, including host, hostgroup, kernel or specfic os version.
---
compliance_markup::enforcement: [ 'disa_stig', 'nist_800_53_rev4' ]
Depending on the version of Puppet being used, the compliance_map()
function
may not be able to precisely determine where the function has been called and a
best guess may be provided.
Patches are welcome to the code on the SIMP Project Github account. If you provide code, you are guaranteeing that you own the rights for the code or you have been given rights to contribute the code.
To run the tests for this module perform the following actions after installing
bundler
:
bundle update
bundle exec rake spec
bundle exec rake beaker:suites
Running rake pkg:rpm[...]
will develop an RPM that is designed to be
integrated into a SIMP environment. This module is
not restricted to, or dependent on, the SIMP environment in any way.