CLM clustering on WebSphere with UrbanCode Deploy

A mild case of paranoia. Or too many episodes of Breaking Bad and Walter White Syndrome. Whatever it is, I feel like Darrell Schrag’s been peering over my shoulder (across all of 9000+ miles) as I’ve been working on this post, tut-tutting at some of the wrong turns I’ve taken.  Though Darrell had no idea I’ve been writing this post, “Getting the Most out of Your UrbanCode Deploy Implementation” might well have been directed at me: this post is a kind of a case in point, at least of his advice on using/creating plug-ins.

Where it started is in the 3 posts on UrbanCode Deploy and WebSphere:

I began to add steps to the first plug-in I wrote but needing a “guinea pig” to test them out on decided to tackle automating the deployment of CLM applications in a WebSphere cluster. As can be seen from the page at https://jazz.net/wiki/bin/view/Main/DeployingCLMClusterWithWASND, this is potentially fraught with peril because of the many steps involved. Admittedly the whole process is not something that needs to  be repeated on a very regular basis but is ideal for use as an example of how to implement some of Darrel’s advice. To limit the scope somewhat, I only implement the following sections from that Wiki page, ignoring both the WXS and RRDI parts:

Here are the plug-in steps I ended up with.

Command
Description
Create Application server
Creates a new application server in the configuration.
Create application server cluster from server
Creates a new server cluster with an existing server as the first cluster member.
Create proxy server
Creates a new proxy server in the configuration.
Create WAS Profile
Create a WebSphere profile
Federate WAS Profile
Federate a WebSphere profile
Install a WAS FixPack
Install a WebSphere FixPack
Install WAS from a response file
Install WebSphere using a response file
Install WAS from IM repository
Install WebSphere from an IM Repository
List installed package in directory
List package installed in a specified directory and populate productID value that can be used, for example, in imcl uninstall
List Packages in Repository
List packages in an IM Repository and set productID property that can be used imcl install
Run wsadmin script
Run a properly formatted Jython script provided in the Jython Script text area with wsadmin
Uninstall WAS
Uninstall WebSphere from given Directory

The names and descriptions should be fairly self-explanatory, but a few hidden details (and the devil is in them) are worth pointing out.

  • Following the approach used in the container topicApplication Deployment for WebSphere plug-in, most of the parameters (or arguments) to the command default to ${p:resource/<propertyname>}, which means that the values for these parameters need to be only set on the resource the process is being executed on. This is really useful as it means less fiddling with the process just because different resources the process is being run on have different characteristics. The path to the IBM Installation Manager command line tool (imcl) is one trivial example: setting the property value at the resource means it can be different on each resource and the process doesn’t need to be changed. If the expectation is that some properties will change more often, for example with each process invocation, then they can be defined and used from the process’ configuration. Note that UCD is flexible enough that a hybrid approach is possible: define the property with a default value on the resource, define the same property on the process setting the default value here to ${p:resource/<propertyname>}. Now with step value set to ${p:<propertyname>}, you get to choose at process invocation time whether to go with the default value set for the resource or change it for just this invocation.
  • Though the code-import plugin-test cycle is pretty short when writing UCD plug-ins, I take a more cautious approach particularly when testing steps that could either take a long time to run or steps that, if incorrectly executed, could do “bad things”. To aid with initial testing without fear of breaking things, all the steps have a “Preview Only” hidden property, that when enabled, will spit out the command to be executed  and not run it.
  • With some of the WebSphere commands implemented in my plug-in I didn’t want to prompt for every single argument possible but rather capture (IMHO) the most commonly used ones.  However to allow other arguments to be specified where necessary I always provide an “Additional Arguments” property.

So on to the process design itself, ignoring (for now) Darrell’s good advice on component templates. Since in a typical WAS ND clustered environment the Deployment Manager and its nodes may not be co-located on the same physical or virtual server, the “process” can actually be split into number of processes, each invoked at will from a “parent” process.

The parent process

parentprocess

This is the parent process that orchestrates the whole process end-end. Each step in this process is simply an invocation of the “Run Generic Process” Utility plug-in step.

RunGenericProcess

This step invokes a specified Generic process, on a resource specified by the Resource Path property which defaults to the resource on which the parent process is invoked. In this example the Deployment Manager and the Proxy Server nodes are on the same host (resource) while the first Application Server node is located on a different host. Thus I have two properties defined for the process (resource.dmgr.path and resource.appsrv.path) which are used in the appropriate “Run Generic Process” steps each of which are described below.

00 Install WAS ND and Fix Pack

installwasprocess

The first step is the one from the very first version of my plugin and sets a productId property, which the second step uses to install WAS ND. The third step installs a WAS FixPack from an IM repository. Note that although the product being installed in this example is WAS ND 8.5.0 and FixPack 1, these three steps could be used to install just about any IBM IM based product, just by changing the string that the “List Packages in Repository” step searches for, “com.ibm.websphere.*” in this case.

01 Create WAS Deployment Manager profile and verify

createdmgr

This process uses the “Create WAS profile” step from my plug-in. This step runs the manageprofiles -create command with the values provided for arguments such as -profileName and -profilePath.

createwasprofile

The “Get server, node and cell names of dmgr” step runs a small Jython script that will fetch the server, node and cell names for the Deployment Manager profile created in the previous step and use the post-processing step to store them as properties. This is just a convenience which allows me to not have to know these values or set them up front. The “Run wsadmin script” plug-in step used here runs any properly formatted Jython script provided in the step configuration itself rather than in a script file as the topicExecute wsadmin Script does. These properties are used in the final Shell step in this process which runs the Installation Verification Tool for the profile just created which also has the nice side effect of starting the Deployment Manager.

02 Create proxy server profile, federate it and create proxy server

createproxy

The first step uses the same “Create WAS profile” step from my plug-in specifying “managed” for the profile template. The next step runs addNode to federate the new profile to the Deployment Manager using the “Federate WAS Profile” step from my plug-in. The final step runs AdminTask.createProxyServer with the appropriate arguments, allowing protocol selection for the Proxy Server and unique port generation. Again, rather than have to specify/know the node name of the new Proxy server ahead of time, I add a post-processing script to the “Federate WAS Profile” step that extracts and sets this as a property which the “Create <> server” step can use with ${p:Federate WAS Profile/nodename}.

03 Create app server profile, federate it and create app server

createappserver

The first 3 steps in this process are the same as those in the process to create a Proxy Server, except that “Create Application server” is a step from my plug-in that runs AdminTask.createApplicationServer.

The next three steps are interesting in that they show how easy it is to re-use existing deployment assets if you have them. A while ago Indradri and I wrote CLM deployment automation for WAS – departmental topology. The excellent scripts that Indradri produced read a config file and set various JVM and JVM custom properties required for CLM deployment on WAS.So “Read property file” uses a step from the UrbanCode FileUtils plug-in to read the same properties file that Indradri scripts read and then run a couple of scripts which are Jython snippets extracted from Indradri’s scripts.

The last step uses the “Install Application” step from the “Application Deployment for WebSphere” plug-in to install one of the CLM applications into the newly created  application server.

04 Create Cluster from app server

createcluster

Finally the process to create a cluster is a single step “Create application server cluster from server” from my plug-in. I created this step rather than use topicCreate Cluster to allow me to use the -convertServer argument in addition to setting weights and node-scoped routing.

createappserverstep

So there it is. Following some of Darrell’s good advice on using/creating plug-ins means this set of processes is mostly reusable for situations outside of just setting up CLM in a cluster. Other steps from the Application Deployment for WebSphere plug-in can be added to add cluster members, start/stop servers etc.

It should also be apparent that when migrating a bunch of existing deployment assets to take advantage of UCD’s features a gradual approach is usually best. For another example of this see the Jazz.net post on Using IBM UrbanCode Deploy for jazz.net deployments.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s