Skip to content

Instantly share code, notes, and snippets.

@nvalentine-puppetlabs
Created December 12, 2014 21:51
Show Gist options
  • Save nvalentine-puppetlabs/46b9a730566b3d36bc90 to your computer and use it in GitHub Desktop.
Save nvalentine-puppetlabs/46b9a730566b3d36bc90 to your computer and use it in GitHub Desktop.
vagrant-pinterest-puppet-devtest
--------------------------------
# Summary
This is a self-contained VM-based environment for developing Puppet code at Pinterest.
# Requirements
You'll need to have downloaded and installed the following:
* [VirtualBox](https://www.virtualbox.org/wiki/Downloads)
* [Vagrant](http://vagrantup.com/downloads.html)
VirtualBox gives you a way to easily spin virtual machines on your workstation
for testing of Puppet code. While it is possible the Pinterest devtest
environment could be extended to support VMWare or even Docker
virtualization/containerization, it currently supports VirtualBox only.
Vagrant is an additional layer of software which uses VirtualBox as a virtual
machine provider and enables management of virtual machines from a Ruby-based
DSL. In the Pinterest Puppet devtest environment this has been taken a step
further through utilization of Vagrant plugins developed by Puppet Labs such
that much of the virtual machine specification happens via YAML files. More on
that later.
## A special note for OSX users
We've noticed that Vagrant and OSX often have bit of a tussle after an initial
Vagrant install. This manifests itself as Vagrant command-line operations
hanging indefinetly. The "fix" for this problem is to install Vagrant twice
and without an uninstall between the two installs. Yes, really.
## Optional but Recommended Supporting Tooling
* [rbenv](https://github.com/sstephenson/rbenv) - installed in a user's
account which allows easy multiplexing of Ruby+gem environments. Very
useful for doing any sort of Ruby or Puppet development when you don't
want to rely on Ubuntu's version of Ruby and 'gem'. And you most likely
DON'T want to rely on Ubuntu's version. ;)
* [zsh](http://www.zsh.org) - and particularly with the [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh)
framework. OMZ enables a number of shell features which are super helpful when
interacting with git, Puppet, and the command-line in general.
* [puppet-module-skeleton](https://github.com/garethr/puppet-module-skeleton) -
extends the functionality of the 'puppet module generate' command to include
lots of useful addition scaffolding for new modules including code and utilities
for RSpec-based unit and acceptance testing.
# Usage
The Rake tasks documented below will allow you to setup and configure a Vagrant environment,
deploy the 'production' branch of the Puppet control repo to './puppet', and spin an
Ubuntu node to be used for local Puppet module development.
## Getting the devtest env
```console
$ cd ~/workspace
$ git clone git@github.pinadmin.com:OpsPuppet/vagrant-pinterest-puppet-devtest
$ cd vagrant-pinterest-puppet-devtest
$ ls
config Gemfile Rakefile README.md Vagrantfile
```
## Initial configuration of the env
Assuming you have rbenv installed (otherwise some of these commands will require a 'sudo'):
```console
$ gem install bundler
$ bundle install
```
To check whether or not your system has all of the dependencies necessary to run the Vagrant environments:
```console
$ rake deps
Checking environment dependencies...
...
Congratulations! Everything looks a-ok.
```
If the above step fails, unless the output tells you to do something differently, I recommend running:
```console
$ rake setup
$ rake deps
```
## Install the Pinterest Puppet codebase
The following command will pull down the Puppet code repo and checkout the 'master' branch
which represents code which deployed to production. You'll want to do your development on
a feature or topic branch.
```console
$ rake puppet
```
At this point you are ready to go into puppet/modules and start creating feature branches
for development of your Puppet modules.
## Starting your test VM
Vagrant will automagically create the VM, start the VM, and install the Puppet Enterprise
agent via the following command:
```console
$ vagrant up
```
** Note the failed Puppet run shown below. This is the EXPECTED behavior! More
on that later. **
```console
$ vagrant status
Current machine states:
ubuntu0 not created (virtualbox)
The environment has not yet been created. Run `vagrant up` to
create the environment. If a machine is not created, only the
default provider will be shown. So if a provider is not listed,
then the machine is not created for that environment.
$ vagrant up
Bringing machine 'ubuntu0' up with 'virtualbox' provider...
==> ubuntu0: Importing base box 'ubuntu/precise64'...
...
==> ubuntu0: Error: ::pinfo_team is not defined! at /tmp/vagrant-puppet-2/modules-0/pinterest/manifests/profile/base.pp:95 on node ubuntu0
==> ubuntu0: Error: ::pinfo_team is not defined! at /tmp/vagrant-puppet-2/modules-0/pinterest/manifests/profile/base.pp:95 on node ubuntu0
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.
```
Re-spining a VM is a rather time-consuming operation so frequent use of snapshots is highly recommended.
```console
$ vagrant snapshot take fresh
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
```
Restoring the VM is pretty straight-forward:
```console
$ vagrant snapshot go fresh
Powering off machine cfd93345-28a3-41dd-99d9-60a1f1cc0378
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Restoring snapshot d17ee975-0898-4d56-8783-836a43f9b0c6
Starting restored VM
==> ubuntu0: Resuming suspended VM...
==> ubuntu0: Booting VM...
==> ubuntu0: Waiting for machine to boot. This may take a few minutes...
ubuntu0: SSH address: 127.0.0.1:2222
ubuntu0: SSH username: vagrant
ubuntu0: SSH auth method: private key
ubuntu0: Warning: Connection refused. Retrying...
==> ubuntu0: Machine booted and ready!
```
## Hacking Pinterest Puppet code
### Setting the required pinfo_* facts and running Puppet via Vagrant
The master branch of the Pinterest Puppet code base including Hiera data lives
in the 'puppet' directory in the devtest environemnt. Before we start hacking,
let's fix our VM so we get a clean run against the master branch.
The error messages we saw in the initial Puppet run during our test of the
environment were a because the run is missing a set of required
Pinterest-specific core facts. This set of core facts will vary over time
but they are all prefixed with the 'pinfo_' string. In AWS/RightScale these
facts will be populated with values sourced from RightScale inputs as documented
in the [wiki](https://w.pinadmin.com/display/OPS/Masterless+Puppet) but in a
Vagrant environment we can mock them up by editing the file 'facter/facts.d/pinterest.yaml':
```yaml
---
pinfo_team: ops
pinfo_environment: dev
pinfo_cloud: vagrant
```
and then launch another Puppet run:
```console
$ vagrant provision --provision-with-puppet
==> ubuntu0: Running provisioner: puppet...
==> ubuntu0: Running Puppet with site.pp...
...
```
### Logging into our test VM to run Puppet
To login to the VM and run Puppet manually:
```console
$ vagrant ssh
Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.2.0-72-virtual x86_64)
* Documentation: https://help.ubuntu.com/
System information as of Fri Dec 12 19:39:19 UTC 2014
System load: 0.71 Processes: 78
Usage of /: 5.8% of 39.37GB Users logged in: 0
Memory usage: 21% IP address for eth0: 10.0.2.15
Swap usage: 0%
Graph this data and manage this system at:
https://landscape.canonical.com/
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
New release '14.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
vagrant@ubuntu0:~$ sudo su -
root@ubuntu0:~# puppet apply --modulepath /mnt/puppet/module --hiera_config /mnt/puppet/hiera.yaml /mnt/puppet/manifests/site.pp --debug
...
```
### Creating a topic/feature branch in the Puppet codebase
As an example, say we've been tasked with adding NTP configuration
to our Puppet codebase. We'll want to create a feature/topic branch
for our development and testing.
```console
$ cd puppet
$ git checkout master && git pull
Already on 'master'
Your branch is up-to-date with 'origin/master'.
Already up-to-date.
$ git checkout -b add_ntp
Switched to a new branch 'add_ntp'
```
Your VM has the puppet code directory mounted under /mnt/puppet so you can
now test your changes in the VM via either of the commands shown above
for launching Puppet runs.
The usual git branching, syncing, and merging tricks apply but are not
covered in this document.
### For local testing
* [rspec](http://rspec.info/)
* [beaker-rspec](https://github.com/puppetlabs/beaker-rspec)
### For centralized automated testing
* some form of [CI system]()
* [Jenkins](http://jenkinsci.org) is the most popular onsite solution.
* [TravisCI](http://travisci.org) is a good place to start for cloud-base CI through most find they outgrow it quickly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment