Using Geppetto in your infrastructure
Geppetto is an Eclipse-based IDE for developing Puppet modules. The editor provides features such as syntax highlighting, code completion, error highlighting, refactoring, and even integrates directly with the Puppet Forge.
Geppetto is incredibly powerful and feature packed, but like many powerful tools it can tend to be complex and favor software developers over those using Geppetto to maintain the Puppet modules used to manage their infrastructure. We'd like a workflow that lets you quickly and easily update, test, and then deploy modules directly from your workstation. We'd like to use the New Project wizard to create new modules with all the expected metadata files in place and we'd like to have the option of publishing them to the Forge.
This tutorial describes how you can configure Geppetto for this style of development and a useful workflow for maintaining and updating your in-house Puppet modules. Unfortunately, some of the steps are still manual, but we will configure shortcuts for as much as we can. For simplicity, we will assume that you have some form of git server running on your Puppet Master, allowing you to easily create new repositories as needed with the proper hooks in place to keep the code in your Puppet modulepath updated.
Configuring your Workspace
Your first step is to define a Workspace for your infrastructure. If this project is the only code that will be managed by Geppetto, go ahead and make it the default so you don't have to choose a workspace each time you start the environment.
Next, you'll want to configure an External Tool entry to run puppet apply for testing purposes. Click the downward facing arrow next to the Run button and choose "External Tools Configurations…"
In the configuration window, you'll want to add a new tool and configure it appropriately.
Configure the Location to match your system. For example, on a Windows workstation, you might set it to:
Now, when you select a module in the Project Explorer, you'll be able to enforce the
tests/init.pp smoke test locally for quick class validation. You'll still be able to run Puppet from the command line for more in-depth usage if needed. You may want to duplicate this tool configuration and add
--noop to the arguments list to also get a Puppet Noop Apply action.
Creating a module
Now it's time to build a module. Start the New Project wizard by clicking the New button or right clicking in the Project Explorer and choosing New ➥ Project. Select the Puppet Module Project, select Next, and then give it a name. Allow Geppetto to add it to the default location.
At this point, you'll have a local project containing a module that you can develop and test as you like. The Puppet code in
tests/init.pp will be enforced locally when you click the Run button. Add projects for each module you create.
Unless your modules are very simple, it's likely that you'll be using some upstream modules from the Puppet Forge. Let's add those to our workspace too. This will allow us to test enforce our code locally, and it will allow Geppetto to work its code completion and error highlighting magic. Click the File ➥ Import menu option, or right click inside the Project Explorer and choose Import. Select the Forge Repository option in the wizard and click Next.
In the keyword search box, type the name of the module you're looking for and hit the Select button.
This will bring up a dialog box with a list of modules that match the keyword(s) you entered. Choose the module you want and click OK a couple times to import a local copy of the module into your workspace.
Now you've got at least a couple modules to work with. You'll need to tell Geppetto about their dependencies, so it knows to index and build references between them all for code completion and error highlighting. Edit each of your modules'
metadata.json file and add the appropriate module dependencies.
This file is used by the Puppet Forge to set dependencies between modules so that module installation can also pull down any modules that are required for proper functionality. Geppetto also uses it internally to resolve references between modules, such as class names, or functions from other modules that you use in your own code.
Once the metadata is correct, Geppetto will be able to use the references from other modules, including defined types, classes, functions, and documentation for each. This will provide you with immediate feedback when you misspell a class name, for example, and it will give you tooltip information about how an external class is intended to be used.
Configuring your repositories
Now the question is how you get your code to your Puppet master. The usual workflow is to use a git server configured either with r10k or with post-receive hooks to update your
modulepath. You should allow r10k to manage Forge modules rather than adding them to local repositories. For the purpose of this tutorial, we'll assume that you've got it covered once the updates hit your git server.
In order to deploy configuration updates from Geppetto, you will need two things. You'll need a git repository for each of your own modules to push commits to and you'll need to initialize each of your module projects with a local git repository and configure a remote linked to your upstream repository.
On your git server, create a new repository for each of your own modules, but don't add any commits to it. You'll want to create this as a bare repository, which many frontends like GitLab will do automatically. Add any integrations needed to update your Puppet master modulepath.
Next, you'll want to tell Geppetto to create a single repository for the project by checking the Use or create repository in parent folder of project checkbox. Then select the project name and click the Create Repository button. Once complete, you can close the dialog box.
In order to deploy your code, you'll need to configure a remote pointing to the repository on your Puppet master. Switch to the Git Repositories view and find your project. Expand it, right click on Remotes and select Create Remote.
You will see another dialog with remote configuration. Click the Change button to change the remote URI and configure the resulting dialog with the appropriate information for the git repository for this module. Enter the hostname of the git server and the path to the repository. Choose the network protocol and enter your user credentials.
This example shows the git remote configuration for a module in the Puppetlabs Windows Essentials virtual training course.
Click the Save button when you are finished. Do not Save and Push yet, because we haven't committed any code to push.
Making your first commit
In the resulting dialog, you should enter a descriptive and meaningful commit message. This message should summarize briefly what you changed, but more importantly, it should explain why the changes were necessary. The commit message will serve as documentation for anyone later reading through history, or for collaborators in a code review environment.
Below the text input area, you should check the files you want to commit. You may commit the
.project file if you like. This file contains static project metadata that might make it easier for other Geppetto users to import the project. If you prefer not to commit it, you may create a
.gitignore file to instruct git to ignore the file.
Once you are satisfied, simply click the Commit and Push button. You may also choose to make several code commits before pushing them all at once.
The first time you push, Geppetto will require you to configure ref specifications. You should select the name of the local branch you are working on and the name of the remote branch to push it to. For the purposes of this tutorial, we will simply use the master branch, but in production you should be have feature or dev branches.
Select the branch name in the source and destination ref dropdowns and click the Add Spec button. Click the Finish button to perform the push action.
Repository management and etiquette is beyond the scope of this tutorial, but a good rule of thumb is that you should do your best to make the repository easy to navigate for other members of your team. They will thank you for it later, and if you ever have to crawl through history, future-you will thank current-you.
Once the push is complete, you will get a results window iterating each of the branches or tags you pushed and the response from the git server If your post-update hook has any output, it will be displayed in the lower pane of this window.
This example is displaying the output of the post-update hook from the Windows Essentials virtual training course.
At this point, assuming that your git server environment has been configured properly to update your Puppet master's modulepath with your code updates, deploying code to your infrastructure is a simple matter of writing and testing code on your Geppetto workstation and then pushing commits upstream. Test it now by classifying a client node and enforcing configuration by running puppet agent -t on it.
While on the topic of workflow, I will caution you that this is only the beginning. A robust infrastructure should have many more barriers between developer workstations and the live production environment. You should implement a code review process and an automated testing gatekeeper such as Jenkins or Travis CI.
Most importantly, on a live infrastructure, you should only merge signed-off commits to the production branch and only commit to feature or testing branches.