Puppet, Manifests, and Direct Application
In my last post, I went over all the different errors I encountered getting Puppet apply working on a system with modules. I will go over this configuration, a manifest to setup Two Factor Authentication on SSH, and applying Puppet manifests directly on a system.
Configuration for Puppet Magic
I have go these items working on a system:
- puppet 5
- vagrant 1.9.3
- Ubuntu 14.04 Trusty Tahr
All of the above are the latest and/or currently supported versions as of this writing.
This is the Vagrantfile, default.pp file, associated modules folder:
Vagrantfile contents
Vagrant.configure("2") do |config|
config.vm.box = 'ubuntu/trusty64'
# resolves error: ==> default: Warning: Could not retrieve fact fqdn
config.vm.hostname = "vagrant.example.com"
# http://www.terrarum.net/blog/masterless-puppet-with-vagrant.html
config.vm.provision 'shell', :inline => <<-SHELL
apt-get purge -y puppet # remove puppet3
wget https://apt.puppetlabs.com/puppet5-release-trusty.deb
dpkg -i ./puppet5-release-trusty.deb
apt-get update
apt-get install -y puppet-agent # install puppet5
SHELL
# https://github.com/mitchellh/vagrant/issues/3740#issuecomment-92106636
config.vm.provision 'puppet' do |puppet|
puppet.environment_path = 'environments'
puppet.environment = 'production'
puppet.module_path = 'modules'
end
end
Just to going over things quickly:
- the shell provisioner removes puppet3 and installs puppet5
- this configures puppet provisioner to:
- use the modules folder
- set the environments variable to
production
- set the environments path to
environments/
- load any manifests from vagrant’s shared directory
Manifest File contents
Location: environments/production/manifests/default.pp:
class { 'apt': }
apt::ppa{ 'ppa:ubuntu-elisp': }
package { 'emacs-snapshot':
ensure => 'latest',
require => Apt::Ppa['ppa:ubuntu-elisp']
}
Note: The Vagrant configuration will provision any manifests file in the “environments/production/manifests/” folder. There’s no need to name the file default.pp. It’s done here as a default.
Configure Modules
I am bootstrapping all the modules for the manifests files into the vagrant/modules directory.
The big problem: puppet modules require a working version of puppet to download puppet modules. This is a problem if the host system does not have a working version of puppet.
One way I worked around this: use another system’s puppet to download modules and copy the modules directory to the shared vagrant directory.
To bootstrap modules from the guest/vagrant system:
$ puppet module install puppetlabs-apt
$ cp -r ~/.puppet/modules /vagrant/ # puppet 3
$ cp -r /opt/puppetlabs/puppet/modules /vagrant # puppet 5
Time to Provision
Now that the Vagrantfile, manifests, and modules are setup, let’s provision! Provisioning this system will produce these types messages at the end:
$ vagrant up
...
==> default: Notice: /Stage[main]/Apt/Apt::Setting[conf-update-stamp]/File[/etc/apt/apt.conf.d/15update-stamp]/content: content changed '{md5}b9de0ac9e2c9854b1bb213e362dc4e41' to '{md5}0962d70c4ec78bbfa6f3544ae0c41974'
==> default: Notice: /Stage[main]/Main/Apt::Ppa[ppa:ubuntu-elisp]/Exec[add-apt-repository-ppa:ubuntu-elisp]/returns: executed successfully
==> default: Notice: /Stage[main]/Apt::Update/Exec[apt_update]: Triggered 'refresh' from 1 event
==> default: Notice: /Stage[main]/Main/Apt::Ppa[ppa:ubuntu-elisp]/File[/etc/apt/sources.list.d/ppa:ubuntu-elisp.list]/ensure: created
==> default: Notice: /Stage[main]/Main/Package[emacs-snapshot]/ensure: created
==> default: Notice: Applied catalog in 54.07 seconds
If there any other messages that say Error
, check my
last article for
possible solutions. Otherwise, contact me
and let’s work through it together.
Manifest: Two Factor Authentication
Now that puppet is provisioning the system, this is another manifest to install two factor authentication on SSH login.
One thing a puppet manifests allows is easy setup of cloud instances with security. I like having two factor authentication on SSH setup, there are three steps and any misstep can lock you out of your own system.
Having a puppet manifest manage this configuration and setup is better than doing it manually.
File: vagrant_home/environments/production/manifests/two_factor_authentication.pp
# uses puppet modules:
# - ghoneycutt-ssh; https://forge.puppet.com/ghoneycutt/ssh
# - stdlib (included with the above module)
class { 'stdlib': }
# get google authenticator
package { 'libpam-google-authenticator':
ensure => 'installed'
}
# add google_authenticator config pamd
file_line { 'pamd config':
path => '/etc/pam.d/sshd',
line => 'auth required pam_google_authenticator.so'
}
# config ssh & restart after pamd changes
class { 'ssh':
sshd_config_challenge_resp_auth => 'yes',
subscribe => File_line['pamd config']
}
Bootstrap all the modules needed for puppet:
modules directory:
$ puppet module install ghoneycutt-ssh
$ cp -r .puppet/modules /vagrant/ # puppet 3
$ cp -r /opt/puppetlabs/puppet/modules /vagrant # puppet 5
Run vagrant up
:
bash-3.2$ vagrant up
...
Notice: /Stage[main]/Ssh/File[sshd_config]/mode: mode changed '0644' to '0600'
Notice: /Stage[main]/Ssh/Service[sshd_service]: Triggered 'refresh' from 3 events
Notice: /Stage[main]/Ssh/File[ssh_known_hosts]/ensure: created
Notice: Applied catalog in 1.53 seconds
Voila! The system is now configured for two factor authentication. To get two factor authentication on login:
bash-3.2$ vagrant ssh
Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 3.13.0-128-generic x86_64)
...
Last login: Wed Aug 30 11:36:56 2017 from 10.0.2.2
vagrant@vagrant:~$ google-authenticator
Do you want authentication tokens to be time-based (y/n) y
...
Do you want to enable rate-limiting (y/n) y
vagrant@vagrant:~$
But, one does not need to have two factor authentication on a virtual machine, a puppet manifest like this would be a lot more useful to apply the manifest directly on a cloud instance, say AWS EC2 or Digital Ocean droplet…
Applying Puppet Directly
Puppet manifests can be directly applied to a cloud instance by executing puppet directly. Configure the system in a similar way as the virtual machine:
- setup puppet 5
- install modules (as root/super user)
- run
puppet apply
(as root/super user)
Setting up Puppet5
This will be exactly the same as in the Vagrantfile shell provisioner. Main
difference: prefix each command with sudo
as the shell provisioner is
executing commands as root/super user.
From the cloud instance command line, run these commands setup puppet 5:
$ sudo apt-get purge -y puppet # remove puppet3
$ wget https://apt.puppetlabs.com/puppet5-release-trusty.deb
$ sudo dpkg -i ./puppet5-release-trusty.deb
$ sudo apt-get update
$ sudo apt-get install -y puppet-agent # install puppet-agent
Install Modules
Install any modules used in the manifests. On the cloud instance, any changes at the system level usually requires root/super user privileges, puppet needs to execute with the same privileges, modules need to be accessible to puppet as well.
Puppet 3 will install modules in the users’ home directory.
Puppet 5 will install modules in system directory:
/etc/puppetlabs/code/environments/production/modules
Install associated modules for recipe (as root!):
$ sudo /opt/puppetlabs/puppet/bin/puppet module install ghoneycutt-ssh
Notice: Preparing to install into /etc/puppetlabs/code/environments/production/modules ...
Notice: Downloading from https://forgeapi.puppet.com ...
Notice: Installing -- do not interrupt ...
/etc/puppetlabs/code/environments/production/modules
└─┬ ghoneycutt-ssh (v3.54.0)
├── ghoneycutt-common (v1.7.0)
├── puppetlabs-firewall (v1.9.0)
└── puppetlabs-stdlib (v4.19.0)
Puppet Apply
Run puppet apply as root:
$ sudo /opt/puppetlabs/puppet/bin/puppet apply /full/path/to/file.pp
...
Notice: /Stage[main]/Ssh/File[ssh_config]/content: content changed '{md5}7c3fc0754c5a373bac7b09d9d4f6e403' to '{md5}08cc71e013e8ba01c7d1f03d212f1ee5'
Notice: /Stage[main]/Ssh/File[sshd_config]/content: content changed '{md5}dd54c90b78bdff564b4dd0d20648f0a7' to '{md5}1a79014d4d4a409e854eb18b798e660b'
Notice: /Stage[main]/Ssh/File[sshd_config]/mode: mode changed '0644' to '0600'
Notice: /Stage[main]/Ssh/Service[sshd_service]: Triggered 'refresh' from 3 events
Notice: /Stage[main]/Ssh/File[ssh_known_hosts]/ensure: created
Notice: Applied catalog in 1.53 seconds
To test two factor authentication, see if the google-authenticator
has been
installed:
$ which google-authenticator
/usr/bin/google-authenticator
Conclusion
Puppet is a magical system. I have presented on how to configure a vagrant system configured with the latest puppet (version 5) and bootstrapping modules so clean manifests can used.
I also have shown how a manifest for a system level configuration, like two factor authentication over SSH.
Finally, I explained how to run puppet manifests on system directly so manifests are useful on cloud instances such as AWS EC2 or Digital Ocean Droplet.