Building and Testing 
Puppet with Docker 
Carla Souza
Carla Souza 
Software engineer for Reliant 
Puppet user since 2010 
Container virtualization user since 2008
Our environment 
~15k nodes 
Redboxes 
Amazon EC2 Instances 
Virtual machines 
OpenVZ containers 
KVM
Code your infrastructure
Code QA
Check your syntax 
puppet parse validate 
puppet-lint 
yaml syntax checker 
erb syntax checker
Variable data type validation 
validate_absolute_path 
validate_array 
validate_augeas 
validate_bool 
validate_cmd 
validate_hash 
validate_ipv4_address 
validate_ipv6_address 
validate_re 
validate_slength 
validate_string
Smoke testing 
#tests/test.pp 
class { 'apt': } 
puppet apply --noop --modulepath=".." tests/test.pp
rspec-puppet 
https://github.com/puppetlabs/puppetlabs-apt/blob/master/spec/unit/puppet/type/apt_key_spec.rb#L75
beaker
beaker 
https://github.com/puppetlabs/puppetlabs-apt/blob/master/spec/acceptance/nodesets/default.yml
Code Review
No errors on the puppet run 
!= 
Correctly configured
Mimic the production 
environment
Image from http://wegeekgirls.files.wordpress.com/2014/04/mystique_x-men_days-of-future-past.png
1. Target node's hostname 
2. Use custom facts* 
3. Specify OS 
4. Thats all 
* not required
Step 2: Facts 
Write your own custom facts 
# myserver-facts.txt 
domain=reliantsecurity.com 
ipaddress=172.17.42.1 
ipaddress_docker0=172.17.42.1 
ipaddress_lo=127.0.0.1 
ipaddress_wlan0=172.16.3.218 
is_virtual=false
Step 2: Facts 
Steal facts from an existing node
Step 2: Facts 
$ mystique fetch-facts myserver 
$ mystique fetch-facts --hostname myserver --user carla myserver.company 
# myserver-facts.txt 
domain=reliantsecurity.com 
ipaddress=172.17.42.1 
ipaddress_docker0=172.17.42.1 
ipaddress_lo=127.0.0.1 
ipaddress_wlan0=172.16.3.218 
is_virtual=false 
(...)
Step 3: Specify OS 
--os ubuntu14.04 
--os debian-wheezy
# mystique run --os ubuntu14.04 --hostname myserver
# mystique run --facts /path/to/facts.txt --hostname myserver
Image from http://wegeekgirls.files.wordpress.com/2014/04/mystique_x-men_days-of-future-past.png
FROM tianon/debian:wheezy 
RUN apt-get -qq -y install puppet puppetmaster 
ONBUILD ADD puppet.tar.gz /etc/puppet/
$ ls . 
./ 
../ 
.git/ 
.gitignore 
files/ 
templates/ 
manifests/ 
modules/ 
auth.conf 
autosign.conf 
fileserver.conf 
namespaceauth.conf
FROM mystique/debian:latest 
ADD myserver-facts.txt /etc/facter/facts.d/ 
RUN puppet apply --modulepath=/etc/puppet/modules master.pp 
CMD puppet agent --no-daemonize
# mystique run --facts /path/to/facts.txt --hostname myserver 
Report for myserver 
12 resources created 
2 warnings 
0 errors
# mystique run --facts /path/to/facts.txt  
--hostname myserver  
--verbose
Why using the existing 
tools?
What can I do with all 
this?
Future steps 
● Mimic existing resources from nodes 
● Extend supported OS 
● Specify puppet version 
● Multiple node testing 
○ Linking containers 
● User an existing Puppet Master
Thank you! 
carlasouza@reliantsecurity.com 
https://github.com/carlasouza/mystique* 
Twitter: @carlaas 
* not yet available

Building and Testing from Scratch a Puppet Environment with Docker - PuppetConf 2014