This is the last part of my ongoing blog series on how to use Docker to create a local Puppet development stack. If you've followed all the previous steps you have hopefully learned a lot by now and are running a fully operational dockerized Puppet stack consisting of a Puppetmaster, The Foreman and PuppetDB.
In this blog post we will take a look at how to configure and use these components to provision a new docker container.
First we need to configure Foreman so that it may fulfill its role as ENC and management tool for Puppet.
1. Open your browser and go to: https://foreman.localdomain
2. You are greeted with a login screen after you've accepted the self-signed certificate. The default username is 'admin'. You have to generate a new password to be able to login. In my repository there is a script that resets the Foreman password. It runs the following command:
docker exec -t foreman foreman-rake permissions:reset. The generated password will be visible in your terminal. Copy it to the clipboard and use it to login to The Foreman.
3. If yo are logged in you need to configure the idle timeout first. This is a loose end that I need to fix but haven't been able to figure out yet. Foreman is unfortunately configured with an idle timeout of zero seconds by default. This means that you will be logged out on every page refresh. We have to increase the timeout to prevent this from happening (you will have to login three times before the setting is adjusted permanently, sorry!).
Go to the settings:
Click on the 'General' Tab and enter '60' at the idle_timeout:
Save your settings!
4. Now we have to configure a smart-proxy for The Foreman so that way can manage the Puppetmaster.
Go to Infrastructure - Smart Proxies:
Create a new smart-proxy and enter the following details:
Click submit to save the settings.
Before we can import Puppet classes and environments into Foreman we need to add some environment directories and modules. There is an environments directory in the repository that is used by the Puppetmaster to look for environments and modules. It installs a production environment by default.
1. Create common and development directories. Common will contain community modules that are used by all other environments. Development is for modules that are in development and not yet stable enough for production.
cd environments mkdir -p common/modules mkdir -p development/modules
2. Install some modules (I'm using Git but if you've installed Puppet you can use the
puppet module command which is more convenient)
cd environments/common/modules git clone --branch 4.4.0 https://github.com/puppetlabs/puppetlabs-stdlib.git stdlib git clone --branch 1.2.0 https://github.com/puppetlabs/puppetlabs-apache.git apache git clone --branch 3.0.0 https://github.com/puppetlabs/puppetlabs-mysql.git mysql git clone --branch 1.1.2 https://github.com/puppetlabs/puppetlabs-concat concat
3. Import the modules into The Foreman.
Go to Configure - Puppet - Environments:
Click 'Import from Puppetmaster'. This is your smart-proxy on the Puppetmaster.
The first time you might get an error:
ERF12-2749 [ProxyAPI::ProxyException]: Unable to get environments from Puppet ([RestClient::NotAcceptable]: 406 Not Acceptable) for proxy https://puppetmaster.localdomain:8443/puppet
Just reload the page and it will work. Hopefully someone can tell me why this is happening. After some time you can select which environments and classes to import:
Check all environments and click 'update'.
We are now at the stage where we can reap the benefits of all our hard work. Let's provision a new container with our imported Puppet classes.
1. Create and run a new container
docker run --dns 172.17.42.1 -h dummy.localdomain -it centos:centos6 bash
With this command we are now in a bash shell inside the container. The hostname will be 'dummy.localdomain' and we've set the DNS resolver to our Docker bridge on which Docker-spy is listening. I've used a clean CentOS 6 base image. If you start from a base image with Puppet pre-installed you can skip te next step.
2. Install Puppet and Connect to the Puppetmaster
rpm --import https://yum.puppetlabs.com/RPM-GPG-KEY-puppetlabs rpm --import http://download.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6 rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-6.noarch.rpm rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm yum -y install puppet-3.6.2-1.el6 puppet agent --test --server puppetmaster.localdomain
After running the Puppet command you should see the following lines:
Info: Creating a new SSL key for dummy.localdomain Info: Caching certificate for ca Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml Info: Creating a new SSL certificate request for dummy.localdomain Info: Certificate Request fingerprint (SHA256): 04:BA:A0:44:D3:B2:3D:7A:3C:DA:5C:2D:8C:90:16:7C:D1:C2:C9:51:4A:29:CE:DA:FE:7D:F4:F1:AC:4B:E6:78 Info: Caching certificate for ca Exiting; no certificate found and waitforcert is disabled
This means that the certificate needs to be signed on the Puppetmaster before the agent can connect. Let's do that in The Foreman:
3. Go to: infrastructure - Smart Proxies. Click on the certificates button.
You should see the dummy.localdomain certificate request that needs to be signed:
Click on the sign button to authorize the new node. If you want to make Puppetmaster sign requests automatically you can click on the Autosign Entries and add a wildcard for agents that may connect without manual approval.
4. In the dummy container rerun the Puppet agent command to register the node with The Foreman.
puppet agent --test --server puppetmaster.localdomain
You should see a lot of output and a message that the run was successful. This node is now registered in Foreman and can be configured with the Puppet classes. Let's install Apache, MySQL and our dummy module on this node.
5. Go to: Hosts - All Hosts
You should see our new dummy node listed:
Click on the edit button to configure our new node:
Select the development environment for this node and switch to the Puppet Class tab:
From the available classes select apache and mysql::server to be included on this node. Hit the submit button to save.
5. In the dummy container rerun the Puppet agent to provision the container.
puppet agent --test --server puppetmaster.localdomain
You should see a lot of output from the Puppet agent while it installs Apache and MySQL on the container. When the run ends you should be able to run the following commands:
curl localhost mysql
This should retrieve the default Apache page and connect to the MySQL server. You can now add more classes and docker containers to rapidly test and iterate with your Puppet infrastructure. Success!
It's been a long journey and we've touched upon a lot of cool new technologies. I hope you have enjoyed this blog series. Please leave a comment if you have any remarks or suggestions. Issues with the tools should be filed against their respective Github repositories.
Enjoy your new dockerized Puppet development stack!