Site icon akquinet AG – Blog

Provisioning Maven artifacts with Puppet

Our last blog post introduced how Puppet can be used to achieve Infrastructure-As-Code, and how to deploy Play applications following this practice. However, we didn’t address how the applications are actually copied to the host.

Apache Maven is a widely used build tool adopted by more and more companies to support their build process from compilation to deployment. Deploying, in the  Maven world,  means uploading the artifact to a Maven repository. Such Maven repositories are managed using Sonatype Nexus or JFrog Artifactory. However, this sort of deployment does not address the real provisioning of the application, i.e the deployment on the production servers.

This blog post presents a Puppet module to download Maven artifacts from a Nexus repository. This module closes the gap between the development team deploying their artifacts to a Maven repository, and the administration team responsible for installing and configuring the application.

Why use Puppet to download Maven artifacts ?

The first question you’re probably wondering is “why?”. At akquinet, Apache Maven and Nexus are cornerstones of our build processes. However, dealing with the live deployment still requires manual configuration, copies and so on. This process is error-prone and puts a lot of pressure on the development team. So, we started adopting Continuous Delivery and Infrastructure as Code to improve this last deployment step. But, all our applications and artifacts were stored in Nexus repositories, and the deployment to the production servers requires copying them onto a different type of server (generally via SSH/SCP) to be then deployed to the production servers. Even if these copies were automated using a continuous integration server (such as Jenkins), we’re duplicating the artifacts, making harder to trace the origin of each file. So, it makes a lot of sense to avoid this second server and to retrieve the artifacts directly from Nexus.

The puppet-nexus module is a Puppet extension downloading Maven artifacts from Nexus. Why Nexus? Because it relies on the REST API of Nexus. This Puppet extension supports authentication and repository selection. Actually, we have developed a Bash script to do the job. This script can be used outside of the Puppet module and is just wrapped inside Puppet. But we needed a solution integrated with Puppet and our deployment tool, and which simplified usage of the script.

The Puppet Nexus Module

The Puppet Nexus module defines two entities: The Nexus class and the artifact resource.

The Nexus class is configured with the base url of your Nexus installation and the credentials of the user:

class {'nexus':
    url      => "http://edge.spree.de/nexus",
    username => "nexus",
    password => "********"
}

Once done, you can declare nexus::artifacts as follows:

nexus::artifact {'commons-io':
   gav        => "commons-io:commons-io:2.1",
   repository => "public",
   output     => "/tmp/commons-io-2.1.jar"
}

The artifact is identified using the GAV coordinates (groupId:artifactId:version). The module supports SNAPSHOT versions (downloading the latest snapshot). The classifier and packaging attributes allow you to select the right file:

nexus::artifact {'chameleon web distribution':
   gav        => "org.ow2.chameleon:distribution-web:0.3.0-SNAPSHOT",
   classifier => 'distribution',
   packaging  => 'zip',
   repository => "public-snapshots",
   output     => "/tmp/distribution-web-0.3.0-SNAPSHOT.zip"

The repository attribute indicates the repository to use, generally a group (i.e. a group of proxies and hosted repositories) such as the public, public-snapshots, central. Check your nexus installation to know which repository you should use.

The output attribute indicates the location of the downloaded artifact. It must be an absolute path (following the Puppet convention).

The ensure parameter can be set to:

# Checks that the file is present, downloads it if needed
nexus::artifact {'ipojo-2':
    gav        => "org.apache.felix:org.apache.felix.ipojo:1.8.0",
    repository => "public",
    output     => "/tmp/ipojo-1.8.jar",
    ensure     => present
}
# Delete the file
nexus::artifact {'ipojo-1':
    gav        => "org.apache.felix:org.apache.felix.ipojo:1.8.0",
    repository => "public",
    output     => "/tmp/ipojo-1.8.jar",
    ensure     => absent
}
# Update the file
nexus::artifact {'ipojo-3':
    gav        => "org.apache.felix:org.apache.felix.ipojo:1.8.0",
    repository => "public",
    output     => "/tmp/ipojo-1.8.jar",
    ensure     => update
}

Getting and using the module

To use the presented module, clone the git repository. Once done, configure the modulepath of Puppet in the Puppet configuration file (/etc/puppet/puppet.conf). Once the module is installed correctly, you can download any Maven artifacts from the repositories hosted on your Nexus instance as presented above.

The common pattern is to download an archive containing your application (EAR, ZIP, WAR) and to unzip it (if needed) to the right location such as in the deploy folder of your application server.

Conclusion

This blog post has presented a Puppet Module closing the gap between Maven deployment and the production installation. The Nexus Puppet Module allows you to download Maven artifacts on your production servers. Artifacts are still organized and managed by Nexus. They are downloaded when the application is installed using Puppet.

Exit mobile version