This is a guest post I wrote in the Puppetlabs blog for their Module of the Week program about the MaestroDev/maven module we created.
Module of the Week: maestrodev/maven – Maven repository artifact downloads
Purpose | Manage Apache Maven installation and download artifacts from Maven repositories |
Module | maestrodev/maven |
Puppet Version | 2.7+ |
Platforms | RHEL5, RHEL6 |
The maven module allows Puppet users to install and configure Apache Maven, the build and project management tool, as well as easily use dependencies from Maven repositories.
If you use Maven repositories to store the artifacts resulting from your development process, whether you use Maven, Ivy, Gradle or any other tool capable of pushing builds to Maven repositories, this module defines a new maven type that will let you deploy those artifacts into any Puppet managed server. For instance, you can deploy WAR files directly from your Maven repository by just using their groupId, artifactId and version, bridging development and provisioning without any extra steps or packaging like RPMs or debs.
The maven type allows you to easily provision servers during development by using SNAPSHOT versions—using the latest build for provisioning. Together with a CI tool, this enables you to always keep your development servers up to date.
In this first version, this module supports
- Installing Apache Maven
- Configuring Maven settings.xml for repository configuration
- Configuring Maven environment variables
- Downloading artifacts from Maven repositories
Installing the module
Complexity | Easy |
Installation Time | 2 minutes |
Installing the Maven module is as simple as using the Puppet module tool, available in Puppet 2.7.14+ and Puppet Enterprise 2.5+, and also available as a RubyGem:
$ puppet module install maestrodev-maven Preparing to install into /etc/puppet/modules ... Downloading from http://forge.puppetlabs.com ... Installing -- do not interrupt ... /etc/puppet/modules └─┬ maestrodev-maven (v0.0.1) └── maestrodev-wget (v0.0.1)
Alternatively, you can install the Maven module manually:
$ cd /etc/puppet/modules/ $ wget http://forge.puppetlabs.com/system/releases/m/maestrodev/maestrodev-maven-0.0.1.tar.gz $ tar zxvf maestrodev-maven-0.0.1.tar.gz && rm maestrodev-maven-0.0.1.tar.gz $ mv maestrodev-maven-0.0.1 maven $ wget http://forge.puppetlabs.com/system/releases/m/maestrodev/maestrodev-wget-0.0.1.tar.gz $ tar zxvf maestrodev-wget-0.0.1.tar.gz && rm maestrodev-wget-0.0.1.tar.gz $ mv maestrodev-wget-0.0.1 wget
Resource Overview
CLASSES
maven class
This class installs Apache Maven with a default version of 2.2.1
maven::maven class
Installs Apache Maven, allowing you to specify the version of Maven you wish to install
DEFINITIONS
maven::environment
The definition allows us to configure Apache Maven environment variables on a per-user basis.
maven::settings
Configures $HOME/.m2/settings.xml per user with repositories, mirrors, credentials and properties.
TYPES
maven
This new type lets us download files from remote Maven repositories. Maven must be previously installed.
Testing the module
The module includes some Puppet rspec tests that use the puppetlabs_spec_helper, so it’s simple to implement, and all the fixtures will be automatically downloaded and tests run.
There is a Gemfile included to install all the dependent gems, so after running
$ bundle install
The tests can be executed with
$ bundle exec rake spec
Configuring the module
Complexity | Easy |
Installation Time | 5 minutes |
To install Maven there are two options, a simple one to install the default version (2.2.1):
include maven
or a slightly more complex option that customizes the version:
class { "maven::maven": version => "3.0.4" }
Maven will be downloaded by default from the main Apache archive location. It can be configured to be downloaded from a different repository, like one in the local network, by using this repository syntax used throughout the module.
$repo = { id => "myrepo", username => "myuser", password => "mypassword", url => "http://repo.acme.com", mirrorof => "external:*" # if you want to use the repo as a mirror, see maven::settings below } class { "maven::maven": version => "3.0.4", repo => $repo }
Once you have Maven installed you can configure the Maven settings.xml for different users, override the mirrors, servers, localRepository, active properties and default repository. It is particularly useful to force Maven to use a repository in the internal network for faster downloads. These settings are used by both command line Maven and the maven puppet type.
We are using hashes to be able to reuse repository definitions, without copy and paste, like the $repo definition above.
# Create a settings.xml with the repo credentials maven::settings { 'maven' : mirrors => [$central], # mirrors entry in settings.xml, uses id, url, mirrorof from the hash passed servers => [$central], # servers entry in settings.xml, uses id, username, password from the hash passed user => 'maven', default_repo_config => { url => $repo['url], snapshots => { enabled => 'true', updatePolicy => 'always' }, releases => { enabled => 'true', updatePolicy => 'always' } } properties => { myproperty => 'myvalue' }, local_repo => '/home/maven/.m2/repository' }
We can override the central repository with mirrors, whichb add repositories to the mirrors settings. The servers parameter configures each settings.xml server entry for user and password credentials.
With default_repo_config, we can add a repository that will be enabled for all Maven executions, including the aven puppet type. That would be necessary in order to check a remote repository for snapshots, as there is no snapshot repository defined by default in Maven.
The properties parameter is a hash with keys and values for the properties section of the settings, while local_repo overrides Maven default local repository location.
Another Maven file that can be configured to alter the Maven environment variables is $HOME/.mavenrc with the maven::environment class. The .mavenrc is sourced by the Apache Maven script for each run.
maven::environment { 'env-maven-user' : user => 'maven', maven_opts => '-XX:MaxPermSize=256m', maven_path_additions => '/usr/local/bin' }
Probably the module’s most useful functionality is the ability to download artifacts from Maven repositories. This requires having Maven correctly installed and configured, which can be done with the previous classes and definitions, and uses the Maven dependency:get plugin behind the scenes. The title of the maven resource is used as the file destination, and the user to run maven as can be set with the user parameter.
maven { "/tmp/maven-core-2.2.1.jar": id => "org.apache.maven:maven-core:2.2.1:jar", repos => ["central::default::http://repo.maven.apache.org/maven2","http://mirrors.ibiblio.org/pub/mirrors/maven2"], user => "maven", }
With the optional parameter repos, we can define what repositories to download the dependencies from if not using the default Maven central. The parameter is in the form expected by the Maven dependency plugin, that is id::[layout]::url or just url, separated by a comma.
Or, a little more verbose:
maven { "/tmp/maven-core-2.2.1-sources.jar": groupid => "org.apache.maven", artifactid => "maven-core", version => "2.2.1", classifier => "sources", packaging => "jar", user => "maven", }
Example usage
With some simple declarations we can install Maven in a node, downloading the Apache Maven binaries from apache.org and uncompressing them under /usr/local, and then download any file from the central Maven repo. An example is maven-core-2.2.1.jar, which is located in the repository under org.apache.maven groupId and maven-core artifactId.
# Install Maven class { "maven::maven": } -> maven { "/tmp/maven-core-2.2.1.jar": id => "org.apache.maven:maven-core:2.2.1:jar", }
The usage of the shorter form groupId:artifactId:version:packaging allows us to be more concise, but we could do the same using the groupid, artifactid, version, packaging parameters of the maven type. Note that we are using the chain arrow (->) to explicitly install Maven before using it to download the jar file.
You should have a /tmp/maven-core-2.2.1.jar file with contents matching those of http://repo.maven.apache.org/maven2/org/apache/maven/maven-core/2.2.1/maven-core-2.2.1.jar.
Conclusion
If you use Apache Maven this module comes in handy for installing and configuring it on any machine in a consistent and repeatable way. This module also consumes the output artifacts from the development process in later stages of product delivery without extra steps or re-packaging.
Please let us know if you have any issues with the module. We are looking for new ways to improve the module, such as removing the need for wget to be installed. We look forward to your feedback!
Learn More: