Thursday, October 17, 2013

Automating a JBoss Deployment with ANT

http://www.brainhemorage.com/?p=149

One area where virtually all organizations seem to differ is in change management–and specifically in the deployment strategy.  Recently, a client requested I put together deployment instructions, specifying a preference that I include a deployment script that could remotely deploy the application.  To meet this requirement, I decided to incorporate this new functionality into my existing ANT build script.
In my case, the application is a JBoss Web Service deployment.  The following steps are necessary to deploy the application:
  1. Stop the JBoss Server.
  2. Removed the previous EAR deployment.
  3. Copy the new EAR file up to the server.
  4. Restart the JBoss Server.
Note that restarting the JBoss server is not entirely necessary for many applications.  The JBoss hot deploy feature will gladly pick up the changes. However, we’ve had a few issues with hot deployments in other applications and over time have found it best to restart the application server for each deployment. Your mileage may vary.
Also, because we will eventually deploy to multiple environments, I want to be able to store configuration parameters for each target environment in its own .properties file.
The expected command line to run this deployment will be:
ant -Denv=targetEnvironment jboss-deploy
Where targetEnvironment specifies the target deployment environment.
To get started, I added an ANT target to verify two things:
  • That an environment has been specified
  • The corresponding env.properties file exists.
If these conditions are met, it reads in the target environment’s configution properties.  Here is the code:
<target name="-jboss-deploy-prep">
  <fail
     message="Target environment must be specified in ant command line as -Denv=target"
     unless="env" />

  <fail message="conf/${env}.properties file does not exist">
    <condition>
      <not>
        <available file="conf/${env}.properties" />
      </not>
    </condition>
  </fail>

  <!-- Get properties for target environment -->
  <property file="conf/${env}.properties" />
</target>
The contents of the properties file goes something like this:
jboss.remote.instance.home=/home/jboss/jboss-5.1.0.GA/server/testapp
jboss.remote.host=myhostname
jboss.remote.username=jboss
#jboss.remote.password=secret
jboss.remote.stop=/home/jboss/jboss-5.1.0.GA/server/testapp/bin/testapp stop
jboss.remote.start=/home/jboss/jboss-5.1.0.GA/server/testapp/bin/testapp start
Note that the password is commented out. For security reasons, we may not want to keep the password in the properties file. If the password is not specified, we want to prompt for it. So I added this target:
<!-- get password if not specified -->
<target name="-jboss-prompt-password" unless="jboss.remote.password">
  <input message="Jboss Remote Password:" addproperty="jboss.remote.password">
    <handler classname="org.apache.tools.ant.input.SecureInputHandler" />
  </input>
</target>
Now that I have all the right pieces in place, time to add the jboss-deploy target:
<target
   name="jboss-deploy"
   depends="clean, dist-app, -jboss-deploy-prep, -jboss-prompt-password" >

  <echo message="JBoss Deployment" />
  <echo message="--------------------------------------------------------" />

  <echo message="Stopping the JBoss server running in ${env}" />
  <sshexec
     trust="true"
     host="${jboss.remote.host}"
     username="${jboss.remote.username}" password="${jboss.remote.password}"
     command="${jboss.remote.stop}" />

  <echo message="Removing existing deployment ..." />
  <sshexec
     trust="true"
     host="${jboss.remote.host}"
     username="${jboss.remote.username}" password="${jboss.remote.password}"
     command="rm -f ${jboss.remote.instance.home}/deploy/rce-j2ee-*.ear" />

  <echo message="Transferring new deployment ..." />
  <scp
    sftp="true" trust="true"
    file="${file.appdist}"
    todir="${jboss.remote.username}@${jboss.remote.host}:${jboss.remote.instance.home}/deploy"
    password="${jboss.remote.password}" />

  <echo message="Starting JBoss server running in ${env}" />
  <sshexec
    trust="true"
    host="${jboss.remote.host}"
    username="${jboss.remote.username}" password="${jboss.remote.password}"
    command="${jboss.remote.start}" />

</target>
That’s it. Now executing the jboss-deploy target does the following:
  • Compiles my application
  • Creates a versioned EAR file
  • Stops the JBoss Server
  • Removes the previous deployment
  • Securely copies the new EAR to the server
  • Starts the JBoss server
One other note: if your start/stop scripts make use of the sudo command (as mine does), you may need to modify your sudoers configuration to skipping checking for TTY. The sshexec task does not allocate a TTY terminal, so many Linux distros will not allow the sudo.

No comments:

Post a Comment