puppet
This module handles the management of puppet agents as well as the puppetmaster. Puppetmaster invocations have the option of running the standard webrick (the default) or passenger. Multiple environ- ments are created to provide for a three-tiered development archit- ecture. These environments create 'production', 'development', and individual 'developer' areas. This module also provides for the management of additional environments for the purposes of providing puppet services to multiple sites (see CAVEAT below).
node myagent { class { 'puppet': mode => 'agent', } }
node myotheragent { class { 'puppet': } }
node smallagent { class { 'puppet': tidy_age => '4w', } }
node mymaster { class { 'puppet': mode => 'master', clients => [ 'host1', 'host2', etc ], modules => [ 'foolean-ssh' ], } }
node mylongtermmaster { class { 'puppet': mode => 'master', clients => [ 'host1', 'host2', etc ], tidy_age => '260w', modules => [ 'foolean-ssh' ], } }
node myothermaster { class { 'puppet': mode => 'passenger', workers => 5, clients => [ 'host1', 'host2', etc ], developers => [ 'user1', 'user2', etc ], modules => [ 'foolean-ssh' ], } }
node mysitemaster { class { 'puppet': mode => 'passenger', workers => 5, clients => [ 'host1', 'host2', etc ], developers => [ 'user1', 'user2', etc ], modules => [ 'foolean-ssh' ], sites => { 'site1' => { 'clients' => [ 'host1', 'host2', etc ], 'developers' => [ 'user1', 'user2', etc ], }, 'site2' => { 'clients' => [ 'host1', 'host2', etc ], 'developers' => [ 'user1', 'user2', etc ], }, }, } }
DO NOT USE MORE THAN ONE SITE PER PUPPETMASTER IF YOU NEED TO MAINTAIN PRIVACY BETWEEN SITES!
Puppet allows for the execution of arbitrary ruby code on the puppetmaster. This can be accomplished in manifest files by using the inline_template function or in template files themselves. The arbitrary code will execute in the context of the puppet daemon, typically uid:puppet, gid:puppet. While it limits the scope of readable and writable files over the entire file system it does also mean that any file puppet can read so can anyone with the rights to upload manifests and templates. Because of this "feature" there is no way to ensure privacy between sites.
Manifest Example:
# Grab the puppet.conf file (extra vars to ease 80-char wrapping)
$config_file = "${settings::confdir}/${settings::config_file_name}"
$foo = inline_template( "<%= %x{ cat ${config_file} } %>" )
notify { 'show-foo': message => $foo }
Template Example
<%=
%x{
hostname -f;
id ;
pwd;
echo "#"
echo "# uid=puppet and writable"
find / -type f -user puppet -perm -u=w -ls
echo "#"
echo "# gid=puppet and writable"
find / -type f -group puppet -perm -g=w -ls
echo "#"
echo "# world writable"
find / -type f -perm -o=w -ls
echo "#"
echo "# facter information"
facter
}
%>
Q. Shouldn't the Apache2 controls be in an Apache module instead of here?
This is an experiment to see if it is posisble to have this class be indepedent of any other classes. Ordinarily functionality such as the Apache2 controls would be handled by an Apache module so that enhancements will be carried through to all classes who utilize it. The a2ensite, a2dissite, and a2enmod defines are innocuous enough that their structure should not need to change. It is also the hopes of this module that it will not conflict with other Apache modules. In the future, a Foolean Apache module will be created. This module may depend on the Apache module only if conflicts can not be avoided. In the end, this is all an attempt to publish useful modules without having to foist additional modules upon the adopter.
This module requires puppet version 2.7 or greater.
For CentOS and RedHat this can be found on the RepoForge site as the EPEL site is still publishing v2.6.18
Note: Even as of SLES 11-SP3, Novell SUSE is still using v2.6.18.
Primary development is done on Debian and then validated against other operating systems. The current list of supported operating systems is:
+----------+-----------+--------+--------------+-----------+
| OS | Bootstrap | Puppet | Puppetmaster | Passenger |
+----------+-----------+--------+--------------+-----------+
| CentOS | yes | yes | yes | Yes |
| Debian | yes | yes | yes | Yes |
| Fedora | yes | yes | yes | Yes |
| OpenSUSE | yes | yes | yes | Yes |
| RedHat | yes | yes | yes | Yes |
| Ubuntu | yes | yes | yes | Yes |
+----------+-----------+--------+--------------+-----------+
Notes:
General: Puppet doesn't seem to be able to both stop puppetmaster and start Apache in the same run. Just manually start Apache after the first puppet run when switching to passenger. This should get fixed in a future release.
OpenSUSE: OpenSUSE requires that the modules be added to the APACHE_MODULES variable in /etc/sysconfig/apache2.
The following modules are required for Puppet's Passenger:
RedHat: There are a number of packages that are required to run passenger that are not in the EPEL or RepoForge repositories. They are however, in the RedHat subscription repository. If you are experimenting with the RedHat operating system and do not have a subscription, you can install the missing packages from a CentOS repository.
The missing packages are:
The passenger configuration created by this module does not function properly under SELinux at this time. This can be fixed by dropping back to permissive mode and running audit2allow after a client runs against the server. SELinux support will be addressed in a future release.
To facilitate host multiple sites, this module creates and relies on the following directory structure.
${settings::vardir}/sites
`-- default
|-- development
| |-- manifests
| | `-- site.pp
| |-- modules
| | |-- puppet
| | `-- [ other modules ]
| `-- private
| `-- [ fqdn ]
|-- developers
| `-- [ developer ]
| |-- manifests
| | `-- site.pp
| |-- modules
| | |-- puppet
| | `-- [ other modules ]
| `-- private
| `-- [ fqdn ]
`-- production
|-- manifests
| `-- site.pp
|-- modules
| |-- puppet
| `-- [ other modules ]
|-- private
`-- [ fqdn ]
Puppet, by default, will attempt to manage the permissions and ownership of the various files within the $vardir structure. In doing so a number of the objects will end up with world readable permissions and ownership other than the puppet user or group. In order to allow this module to manage the permissions and ownership the 'manage_internal_file_permissions' options is set to 'false' in the main configuration block of puppet.conf.
This module will then to remove all 'world' permissions and set ownership to the puppet user and puppet group as there is really no reason for any other users to access the puppet files. The premis is that only an administrator (e.g. someone with root) should be running puppet on a system. Likewise only an administrator or someone in the puppet group should be looking at any of the puppet files.
Even with all of this there are still a couple of areas where puppet itself still tries to enforce ownership.
This module uses a cron.d like format to handle prerun and postrun commands. Scripts should be placed in either $confdir/pre-run.d or $confdir/post-run.d. The 'rundir' script will execute any executable script found in the respective directory. This enables modules to add pre and post run processing much in the same manner that cron.d is handled. Script precedence can be achieved by adding numerical prefixes such as pre-run.d/00_etckeeper.
Example: prerun_command = /etc/puppet/rundir pre postrun_command = /etc/puppet/rundir post
NOTE: The 'rundir' script utilizes the PUPPET_NOOP variable, which is set by the facter script isnoop.rb to skip the running of the prerun and postrun scripts when running with --noop turned on.
CAUTION: This will run any executable script found in the pre and post run directories. It is for this reason that only root should be allowed to write into them. Allowing the puppet user to write into these directories will allow anyone with the ability to add recipees to the system to run arbitrary code on the agents. Like cron.d these will, more often than not, get run as root so care should be taken regarding the content that gets added.
Creating the package (tarball) that can be installed using puppet's module function is simple. Run the following command while in the top of the module directory (e.g. /usr/src/puppet-puppet).
puppet module build .
The resulting tarball will be named foolean-puppet-$VER.tar.gz and can be found in the "pkg" directory within the source tree.
Foolean Puppet is on PuppetLab's PuppetForge making installation as simple as:
puppet module install foolean/puppet
When we're installing from a tarball the installation and upgrade process is the same. You'll need to set --modulepath if f you're installing the module in a path other than the location defined in puppet.conf.
MODULEPATH=/var/lib/puppet/modules
puppet module install \
--force \
--ignore-dependencies \
--module-path $MODULEPATH \
$PATHTO/foolean-puppet-$VER.tar.gz
When going for complete deterministic installations we will quickly find ourselves in chicken/egg territory. We use puppet to ensure determinism in our systems but how do we get puppet onto a new puppetmaster when an existing puppetmaster doesn't exist? That is the purpose of the "bootstrap.pp" file. The first time the operating system comes up after install the following steps can be run to bootstrap the puppetmaster.
# install puppet
apt-get install puppet
# retrieve the bootstrap.pp file
wget https://raw.github.com/foolean/puppet-puppet/master/manifests/master/bootstrap.pp
# run the bootstrap process (add --noop if you want to review first)
puppet apply --detailed-exitcodes --verbose ./bootstrap.pp
# run puppet again to configure the system as a puppetmaster
puppet agent --test
Copyright (c) 2013 Foolean.org
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
bennett@foolean.org