How to do Mule Deployment with Maven and Jenkins Pipeline


Mule Application Builds and Deployment can be fully managed using Maven. In the development phase, Anypoint Studio makes it easy to manage your application dependencies using Maven. For Deployment tasks, Mule provides a Maven plugin that can help to automate the application deployment to different target runtime environments such as Standalone, CloudHub, ARM, Cluster and more.

There are different ways to Install and Run Mule Runtime -

  1. Local Standalone Server: Mule Runtime installation on your local server and Mule runs as a single server instance.

  2. Local Cluster: Similar individual instance set up on local, except they are part of a cluster to interact with each other.

  3. CloudHub: Integration platform as a service (iPaas) provided by MuleSoft, where you Mule runs in the cloud.

  4. Pivotal Cloud Foundry: Mule Runtime deployed on Pivotal Cloud Foundry.

Deployments to all these environments can be managed through Manual Copy (For Local), Anypoint Runtime Manager, or Maven Deploy Plugin.

In this post, we will see how we can leverage Mule Maven plugin to perform deployments. We will do a deployment to Standalone Mule Instance as well as to CloudHub Instance. In the end, we will also automate our deployment using Jenkins Pipeline.

Version used:

  • Mule Runtime 3.9.0

  • Jenkins 2.11.0

  • Mule Maven Plugin 2.3.3

1. Mule Maven Plugin

1.1 Introduction

The mule-maven-plugin is a Maven Plugin provided as a part of Mule Framework. It allows us to run integration tests for Mule Application, and also to deploy the application to various environments.

1.2 Configuration

This plugin is available in the Mulesoft public repository, so you will need to add below repository to your settings.xml -

<pluginRepositories>
    <pluginRepository>
        <id>mule-public</id>
        <url>https://repository.mulesoft.org/nexus/content/repositories/releases</url>
    </pluginRepository>
</pluginRepositories>

Once you have added the repository, you can include the plugin in your pom.xml as -

<plugin>
  <groupId>org.mule.tools.maven</groupId>
  <artifactId>mule-maven-plugin</artifactId>
  <version>2.3.3</version>
</plugin>

At this point, you are ready to add configuration for your target server/environment.

1.3 Deployment Profiles

We may have different environments available for deploying our application. It is even possible that, you have a mix of Local Standalone Server and CloudHub approach.

So, Instead of configuring our pom.xml for a single environment, we will use a Maven parent POM approach. We will define a Maven Parent POM and add a Maven Profile for each of our target environments.

The full parent POM is available on the Github here. Configuration parameters are available as properties, and with default values where applicable.

Below profile will help us deploying to local mule server -

<profile>
	<id>standalone</id>
	<build>
		<plugins>
			<plugin>
				<groupId>org.mule.tools.maven</groupId>
				<artifactId>mule-maven-plugin</artifactId>
				<configuration>
                  <standaloneDeployment>
                    <muleVersion>${mule.version}</muleVersion> (1)
                    <muleHome>${mule.home}</muleHome> (2)
                    <applicationName>${artifactId}</applicationName> (3)
                  </standaloneDeployment>
				</configuration>
				<executions>
					<execution>
						<id>deploy</id>
						<phase>deploy</phase>
						<goals>
							<goal>deploy</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</profile>
1 Target Mule Version if Mule should be installed as a part of deployment.
2 This should be a path to our locally installed mule server, such as /opt/mule. Mule Version and Mule Home are exclusive to each other.
3 Application name to be used when deploying to Mule instance.
standaloneDeployment type allows to deploy Mule 3 applications to Enterprise as well as Community Edition.

Below profile will help for CloudHub Deployment -

<profile>
  <id>cloudhub</id>
  <build>
    <plugins>
      <plugin>
        <groupId>org.mule.tools.maven</groupId>
        <artifactId>mule-maven-plugin</artifactId>
        <configuration>
          <cloudHubDeployment>
            <muleVersion>${mule.version}</muleVersion> (1)
            <username>${anypoint.username}</username> (2)
            <password>${anypoint.password}</password> (3)
            <applicationName>${artifactId}-${maven.build.timestamp}</applicationName> (4)
            <environment>${cloundhub.env}</environment> (5)
            <businessGroup>${anypoint.businessGroup}</businessGroup>
            <region>${cloudhub.region}</region>
            <uri>${anypoint.uri}</uri> (6)
            <workerType>${cloudhub.workerType}</workerType> (7)
            <workers>${cloudhub.workers}</workers>
          </cloudHubDeployment>
        </configuration>
        <executions>
          <execution>
            <id>deploy</id>
            <phase>deploy</phase>
            <goals>
              <goal>deploy</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</profile>
1 Target Mule Runtime Version where Application should be deployed.
2 Anypoint Platform Username with appropriate access to target environment.
3 Anypoint Platform User’s password.
4 Application Name for CloudHub. To generate unique name for demo application, timestamp is appended to the name.
5 Target Environment as configured on ARM.
6 If you are running ARM on private instance then specify url here. Eg. anypoint.example.com
7 Worker Type to be one of: Micro (0.1 vCores), Small (0.2 vCores), Medium (1 vCores), Large (2 vCores), xLarge (4 vCores).
Only platform users are allowed in this configuration. It’s not possible to user SSO/Federated as username.

List of available parameters varies based on the deploymentType. See here for a full list of parameters for each deployment type. You may have to modify your profile to add new parameters as needed.

1.4 Demo Application

The full demo application is available on the Github here.

Once we have our Parent POM ready, we use that in our Mule Application POM as -

<parent>
	<groupId>com.javastreets</groupId>
	<artifactId>mule-maven-parent-pom</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</parent>

1.2 Manual Deployment

At this point, we can deploy our application using Maven Deploy Plugin and running the maven commands in terminal.

Deploying to Local Standalone Mule -

mvn clean deploy -P standalone -Dmule.home=/opt/mule

Deploying to CloudHub -

mvn clean deploy -P cloudhub -Dmule.version=3.9.0 -Danypoint.username={your username} -Danypoint.password={your password}

You can pass-in additional parameter values as needed.

2. Jenkins Pipeline

2.1 Introduction

As per Jenkins website -

Jenkins Pipeline (or simply "Pipeline") is a suite of plugins which supports implementing and integrating continuous delivery pipelines into Jenkins.

In this post, I will not go into much detail about Pipeline and presume that you are aware of it. This Jenkins Document may give you a good overview of what Pipeline is.

2.2 Jenkins Setup

CloudHub and ARM deployment would need to access Anypoint Platform. Let’s add Anypoint Credentials in Jenkins Credential. We will use these credentials in our Pipeline to avoid hardcoding and password exposure. If you don’t know how to create Credentials, I suggest you follow this nice tutorial.

Configure Jenkins Credentials

If you do not specify anything in ID attribute, Jenkins will assign and auto generated ID. We will need this ID value for credential lookup in Pipeline.

2.3 Simple Pipeline

Now, we have all that we need for adding a Jenkins Pipeline to our Mule Application. For this, we will need to create a file named Jenkinsfile in the root of our application.

Here is the content of our Jenkinsfile -

pipeline {
  agent any
  stages {
    stage('Unit Test') { (1)
      steps {
        sh 'mvn clean test'
      }
    }
    stage('Deploy Standalone') { (2)
      steps {
        sh 'mvn deploy -P standalone'
      }
    }
    stage('Deploy ARM') { (3)
      environment {
        ANYPOINT_CREDENTIALS = credentials('anypoint.credentials') (4)
      }
      steps {
        sh 'mvn deploy -P arm -Darm.target.name=local-3.9.0-ee -Danypoint.username=${ANYPOINT_CREDENTIALS_USR}  -Danypoint.password=${ANYPOINT_CREDENTIALS_PSW}' (5)
      }
    }
    stage('Deploy CloudHub') { (6)
      environment {
        ANYPOINT_CREDENTIALS = credentials('anypoint.credentials')
      }
      steps {
        sh 'mvn deploy -P cloudhub -Dmule.version=3.9.0 -Danypoint.username=${ANYPOINT_CREDENTIALS_USR} -Danypoint.password=${ANYPOINT_CREDENTIALS_PSW}' (7)
      }
    }
  }
}
1 Stage to Run Unit tests on our Mule Application.
2 Deploy our Mule Application to Standalone server. As we are not passing in mule.home parameter value, this step will actually download the Mule server from Mule Maven Repository and install it in Jenkins workspace. If you want to deploy to already installed instance, then you may add a parameter -Dmule.home=/opt/mule in maven command.
3 Deploy to a Mule Server Managed via Anypoint Runtime Manager.
4 Credential Lookup: We need Anypoint Platforms credentials for this step. We will use jenkins credentials() function to lookup our credentials using ID value. This function then automatically sets two environment variables named {ourvariable}_USR and {ourvariable}_PSW.
5 Use Credential variables to set Anypoint Username and Password while calling our arm profile.
6 Deploy to CloudHub using cloudhub profile. Credentials setup is same as deploying to ARM.
7 For CloudHub deployments, mule.version must be same as it appears on CloudHub available Runtime version names.

To understand the syntax of Jenkinsfile, you may refer this Jenkins Syntax Reference document.

2.4 Jenkins Pipeline Job

Now, we can create a Jenkins Pipeline Job for our demo and configure it to use Jenkinsfile from SCM.

Jenkins Pipeline Job

2.4.1 Job Execution

When this job runs, your pipeline should run and perform all deployments -

Mule Maven Pipeline Job Execution

2.5 Deployment Result

2.5.1 Standalone Deployment

[INFO] --- mule-maven-plugin:2.2.1:deploy (deploy) @ mule-maven-deployment-demo ---
[INFO] No application configured. Using project artifact: /Users/manik/.jenkins/workspace/mule-maven-deployment-demo-simple-pipeline/target/mule-maven-deployment-demo-1.0.0-SNAPSHOT-b0.zip
[INFO] Resolving org.mule.distributions:mule-standalone:tar.gz:3.9.0
[INFO] Copying /Users/manik/.m2/repository/org/mule/distributions/mule-standalone/3.9.0/mule-standalone-3.9.0.tar.gz to /Users/manik/.jenkins/workspace/mule-maven-deployment-demo-simple-pipeline/target (1)
[INFO] Expanding: /Users/manik/.m2/repository/org/mule/distributions/mule-standalone/3.9.0/mule-standalone-3.9.0.tar.gz into /Users/manik/.jenkins/workspace/mule-maven-deployment-demo-simple-pipeline/target
[INFO] Using MULE_HOME: /Users/manik/.jenkins/workspace/mule-maven-deployment-demo-simple-pipeline/target/mule-standalone-3.9.0
MULE_HOME is set to /Users/manik/.jenkins/workspace/mule-maven-deployment-demo-simple-pipeline/target/mule-standalone-3.9.0
Mule is not running.
[INFO] Starting Mule Runtime
MULE_HOME is set to /Users/manik/.jenkins/workspace/mule-maven-deployment-demo-simple-pipeline/target/mule-standalone-3.9.0
Starting Mule...
[INFO] Deploying application [/Users/manik/.jenkins/workspace/mule-maven-deployment-demo-simple-pipeline/target/mule-maven-deployment-demo.zip] (2)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
1 We did not specify mule.home parameter, so this step actually downloaded Mule Runtime and installed it.
2 Then it deployed the generated application zip.

2.5.2 ARM Deployment

[INFO] --- mule-maven-plugin:2.2.1:deploy (deploy) @ mule-maven-deployment-demo ---
[INFO] No application configured. Using project artifact: /Users/manik/.jenkins/workspace/mule-maven-deployment-demo-simple-pipeline/target/mule-maven-deployment-demo-1.0.0-SNAPSHOT-b0.zip
[INFO] Found application mule-maven-deployment-demo on server local-3.9.0-ee. Redeploying application... (1)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
1 As the application was already deployed to ARM, it just redeployed our application.
ARM deployed application

2.5.3 CloudHub Deployment

[INFO] --- mule-maven-plugin:2.2.1:deploy (deploy) @ mule-maven-deployment-demo ---
[INFO] No application configured. Using project artifact: /Users/manik/.jenkins/workspace/mule-maven-deployment-demo-simple-pipeline/target/mule-maven-deployment-demo-1.0.0-SNAPSHOT-b0.zip
[INFO] Deploying application mule-maven-deployment-demo to Cloudhub
[INFO] Application mule-maven-deployment-demo already exists, redeploying (1)
[INFO] Uploading application contents mule-maven-deployment-demo
[INFO] Starting application mule-maven-deployment-demo
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
1 Redeploying our application to CloudHub.
CloudHub deployed application

3. Conclusion

Mule Runtime can be installed on many platforms and Mule Maven plugin does simplify the deployment process. We can also do integration tests using this plugin. We used Mule Maven plugin and Jenkins Pipeline to automate our mule deployment to Anypoint Runtime Manager as well as CloudHub environment.

Refer to Source code on Github for full source code - mule-maven-deployment-demo and mule-maven-parent-pom

on twitter to get updates on new posts.

Stay updated!

On this blog, I post articles about different technologies like Java, MuleSoft, and much more.

You can get updates for new Posts in your email by subscribing to JavaStreets feed here -


Lives on Java Planet, Walks on Java Streets, Read/Writes in Java, JCP member, Jakarta EE enthusiast, MuleSoft Integration Architect, MuleSoft Community Ambassador, Open Source Contributor and Supporter, also writes at Unit Testers, A Family man!