development (in)action

Zend Server Cluster Manager and Capistrano Deployments

One of the challenges of deploying applications in an elastic environment is the target servers are ever changing; from one moment to the next your environment may consist of four, twenty or more target hosts.  The process of determining these targets can be a tedious and time consuming task; requiring the examination of cluster member lists within the Zend Server Manager Gui or executing the ec2-describe-instances then parsing through the results for the correct group; either of these methods is time consuming and thwart with the possibility of mistyping a hostname, missing one or just breaking the process.

I approach deployments from an angle that no human interaction (beyond security dictated by my comfort level) should be required;  a programmatic method of gathering this dynamic list of target hosts is required. To gather this list I have created and employed a library for interacting with the API interface for Zend Server and Zend Server Cluster Manager, Jazsl (Just Another Zend Server Library.)  Jazsl provides methods for all current Zend Server API calls:

  • clusterAddServer
  • clusterRemoveServer
  • clusterDisableServer
  • clusterEnableServer
  • clusterGetServerStatus
  • getSystemInfo
  • restartPhp
  • configurationExport
  • configurationImport

More on these methods may be explored in the Zend Server documentation at Zend-Server-CM-Reference-Manual.  I will assume the target stage for this will be production, and the stage files is production.rb; construction of the dynamic servers list within the production.rb requires certain dependancies:

  • gem: capistrano
  • gem: capistrano-ext
  • gem: json
  • Zend Framework
  • Jazsl

These procedures will assume you have a working capistrano deployment configuration for your php project, the details of installing and configuring Jazsl are as follows. First install the pear packages for Jazsl and Zend Framework on the machine you intend to deploy from.

Now you must enable the zf configuration as well as enable each of the provider within the Jazsl project you intend to utilize; for the purpose of deployments we only require the JazslProvider JazslClusterProvider. To configuration of covered in the following gist:

Confirm your setup and configuration of Jazsl providers by executing zf ? , the out put of which should contain:

Before continuing we must configure an api key (read-only access is all we require.) To generate the api key we must log into the Zend Server Cluster Manager Gui, refer to the Zend Server documentation for details. The deployment hosts portion only requires a read-only api key. Once you have this key you can resume configuration of Jazsl tool as follows:

zf add-server-key jazsl zcsm key_full xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The parameters are described as follows:

zf add-server-key jazsl zendserver url keyname apikey
  • zendserver the identifying name for the key-set/host
  • url the full Uri for the Zend Server originating this api-key set
  • keyname the identifying name of the api-key given in the Zend Server Admin Gui Section
  • apikey the api-key hash provided

You may then validate its operation by executing:

zf cluster-status jazsl-server zcsm

where zcsm name of the key you just saved in the previous command; this command should return either an error message or a table of cluster members (provided you have cluster member)

Once this is confirmed you are now ready to use the jazsl-cluster tool to return the json string that will be used by Capistrano for the target lists as shown in the above gist. To utilize this json string we modify our production.rb file to execute the jazsl-cluster command and parse it as part of the roles determination as shown:

You will note for the :db roles section, I utilize a zf get-server jazsl-cluster command to return a single target host, I utilize this for database migrations which I only need to run on one instance in the cluster; while understanding that there are no static instances in an elastic environment. Finally deployment is executed as usual with capistrano: cap deploy production this will parse the servers list and execute all deployment commands on each server as usual.