The amazing adventures of Doug Hughes

Introducing CFANT

Deploying apps can be a pain. Its not so much the copying of files from one place to another, but all the related tasks you have to remember to do!

As an example, we tend to have local development, staging, and production servers. Each of these servers tend have different configuration settings. On staging I might have a datasource called myAppDev. In staging it might be known as myAppStaging and in production it could be known as something completely different.

Then there are the issues of mappings, custom tag paths, event gateways, email servers, reloading applications, clearing template caches, etc, etc. Historically, Ive avoided using a number of advanced features of ColdFusion because of the configuration required on the server and the requirement that I remember tasks that need doing on each deployment.

Ill wager that the vast majority of websites and applications are quite simple and can easily be deployed via a copy and paste process or FTP. However, the larger and more complex an application and hosting environment become, the more arduous this process gets. At this point you begin to lust for automation but there are some things that are just hard to automate. In these cases you need to automate as much as you can and have a script for any other steps you need to take manually.

Well, at Alagad, weve been pretty stuck at the last mile. For some of our apps we have an ANT build script which essentially calls a remote cfm file that runs another ANT file. This remote ANT file would export the application out of Subversion and to the correct location depending on if were deploying to staging or production. Finally, it might make some configuration changes to the application such as setting Model-Glue and Reactor to production modes.

However, many of our applications run in production with the trusted cache enabled. Some of our applications require mappings or event gateways. Even if we manually set some of these up in the ColdFusion server, we still have to remember all this stuff when if we ever move to a new server or if we cluster our applications. Beyond that, there are still some things you have to do manually on each deploy such as clearing the template cache.

This problem started me thinking about the ColdFusion Admin API. As of version 7, ColdFusion shipped with a collection of CFCs which provided complete access to all the capabilities of the ColdFusion Administration interface. Why couldnt we create a set of reusable scripts which would use the Admin API to do things we would have to manually do while deploying an application? This weekend I decided to give it at shot and the result is a new Alagad offering known as CFANT.

CFANT provides a default mechanism for deploying applications remotely and also includes ANT tasks for everything you can do via the Admin API.

Deploying Applications Remotely

The CFANT project should be installed under your applications webroot in a directory named cfant. This directory should be web accessible. If youre squeamish about this cfant has some properties you can tweak to change the the directorys name and location and you can always make your build.xml file not web-accessible.

Under this folder there is a build.xml file. This file is heavily laden with comments to help you out, but the file itself is really just a starting point. If you look at the file youll see that the default comes with three targets: BuildLocal, BuildStaging and BuildProduction.

Lets start by looking at the BuildLocal target is what you would run locally to kick off the remote build processes. BuildLocal is also the default target. The BuildLocal target defines a few inputs. You can specify whatever inputs your script requires, but I recommend keeping the TARGET input at least as this specifies the name of the remote target youre executing. The rest of of the inputs would be inputs required for the remote target to run. Due to ColdFusions case insensitivity, I recommend you uppercase any values that will be passed to a remote script.

All of the inputs and any properties you may specify need to be passed to the remote build runner. The remote build runner is a simple CFM file in the /cfant/build directory that is executed via HTTP by the local build target. The remote build runner runs ANT on the remote system, specifies the same build.xml file that youve been editing, and runs the task specified. Any arguments that come in through the url as passed as arguments into ANT.

Two things are implicit in this process:

First, you must have ANT installed on your server and it must be accessible via the path. Or, in other words, you must be able to run ANT from the command line without specifying the full path to the ANT executable.

Secondly, you must have already manually pushed CFANT to your remote server. The remote build runner wont run if it and the build XML and various other files it depends on are not there.

At this point your remote build script runs and does whatever you told it too. For a typical Alagad build script, wed probably export code from Subversion, change some XML configuration, and reload the application via a URL.

But, I still need to use some of the features of the ColdFusion Admin API which is why I also included…

ColdFusion Administrator ANT Tasks

CFANT includes 320 ColdFusion administration ANT tasks. Each of these tasks map to a function on the ColdFusion Administration API. Each of these tasks are provided as a class under the bin/com/alagad/cfant folder and must be loaded using the <taskdef> ant tag.

To use any of these tasks youll first need to use the ANT task. (No, this is not the same things as the coldfusion tag. The name is confusing, I know. There may be others that are similarly confusing.) Heres some sample XML:

&lt;taskdef name=&quot;cflogin&quot; classname=&quot;com.alagad.cfant.cflogin&quot; classpath=&quot;${thisDir}/bin&quot; /&gt;
&lt;cflogin adminPassword=&quot;${CFADMINPASSWORD}&quot; /&gt;

Note that I use taskdef to load the cflogin task and then use the cflogin task. At this point I can use any of the other tasks.

Unfortunately, cfant doesnt come with any real documentation. Instead, youll want to use the documentation for the Admin API. And, also unfortunately, that documentation is next to non-existent.

To work around this, I recommend browsing directly to an Admin API CFC specified in the documentation. For example, go to http://yoursite.com/CFIDE/adminapi/administrator.cfc. ColdFusion will prompt you for your administrator password and show you automatically generated documentation.

Any public method on any of the Admin API CFCs has a corresponding tag. For example, the login method on the administrator.cfc has the cflogin task.

Each of the arguments on the Admin API method has a corresponding attribute on the task. For example, the login method accepts four arguments: adminPassword (required), adminUserId (optional), salt (dont use), rdsPasswordAllowed (optional). The task has corresponding attributes which you use in the exact same manner. Youll see in the example above that the cflogin task was provided the one required argument of adminPassword.

If an admin function returns a value you can use a property attribute to specify an ANT property to place the results into. Heres an example using the cfverifyDsn task:

&lt;taskdef name=&quot;cfverifyDsn&quot; classname=&quot;com.alagad.cfant.cfverifyDsn&quot; classpath=&quot;${thisDir}/bin&quot; /&gt;
&lt;cfverifyDsn dsn=&quot;VirtualPM&quot; property=&quot;dsn&quot; /&gt;
&lt;echo message=&quot;VirtualPM DSN is Valid: ${dsn}&quot; /&gt;

Again, the taskdef tag loads the cfverifyDsn task which maps to the verifyDsn function in the admin API. This method accepts an argument named dsn which is the name of the datasource were verifying. The method returns a boolean value and you can use the property attribute on the CFANT task to specify a property name. In the example above we then output the results of this using the ANT echo task.

Any function which returns a value (and the ColdFusion team has property indicated in their ColdFusion code returns a value) will have a property attribute. If the function returns a complex value this is dumped to text and the dump is returned.

How do the CFANT tasks work?

I’m glad you asked! Essentially, I wrote a generator.cfm which gets the metadata for each of the Admin API CFCs. Based on that, I generated a set of remote proxy CFCs that make the public methods on the Admin API remotely accessible. I then generated a simple Java class for each of the methods on the Admin API CFCs. This class ultimately extends the ANT task object and calls remote methods on the remote proxies. Returned values are parsed for errors.

Overall, because this is generated code and a new project, the vast majority of CFANT is completely untested. If you find a problem or have a suggestion please register with the projects Trac site and file a ticket. The Trac site is located here: http://trac.alagad.com/cfAnt.

You will be able to download CFANT from the Alagad.com products section as well as from Subversion at: http://svn.alagad.com/cfAnt/trunk/.

Comments on: "Introducing CFANT" (16)

  1. Eric Pfleckl said:

    Pure genius! We use pre- and post-commit hooks and SVNANT to automagically build our staging site, but we’re still pushing production updates manually. I’ll be sure to check this out for our production deployments. With 4 load-balanced CF servers, shared and local file systems, and template caching; production deployments can be less than trivial. I was already playing with the CF admin API to reset the cache, but wrapping all the features together with CFANT sounds perfect for our needs. Thanks Doug! Ill send feedback once I have something…
    -e

    Like

  2. Damon Gentry said:

    Wow! What timing! I was just getting ready to write a Deployment Manager application for our environment. I was debating between using rsync as the transport mechanism or SVN and updating the target environments. I’ll be evaluating this heavily over the next few weeks!

    Like

  3. FYI, a year ago someone blogged about an undocumented tag cfant, so you may want to watch out for naming collisions…

    http://coolskool.blog-city.com/cfant__undocumented_coldfusion_tag.htm

    Like

  4. Doug Hughes said:

    I am officially not worrying about undocumented features. I’ll rename this in the future if I need to.

    Like

  5. Boyan Kostadinov said:

    While this is neat, I feel it’s somewhat reinventing the wheel. Here are some things to consider:

    1. CF does come with the “undocumented” cfant tag that you can use to run ant build scripts. You can see an example of it’s usage on my blog: http://blog.tech-cats.com/2007/10/unzip-with-utf-support-in-coldfusion.html

    2. For deployment, you can use something like CruiseControl to automate your build and demployment since you need to install CFANT on the server anyway. CruiseControl works by checking the SVN repo for changes and then invoking local build tasks.

    3. You can build your scripts with ANT or NAnt and in a very similar fashion execute them through the web on the test/prod machine.

    The big advantage I see in CFAnt is the built-in tasks that come with it. Is there a list of those somewhere? Do they depend on pre-built Ant tasks?

    Like

  6. Doug Hughes said:

    Boyan – Thanks for your feedback. I agree that there are multiple ways to deploy a project and that the “neat” part about running an ant script remotely could be done in about a hundred different ways. However, I really like to just right click on a build.xml file in Eclipse to deploy. This allows me to easily do this.

    And, like you said, the real nice part about the framework is the integration with the the Admin API. To find a list of the task you can do two things. Either look through the Admin API’s functions or look at this directory in SVN: http://svn.alagad.com/cfAnt/trunk/src/com/alagad/cfant/ . Each file is an ANT task.

    Like

  7. Doug Hughes said:

    A couple of notes about CFANT:

    1) The example that comes with CFANT pretty much assumes that you use the same server for production and staging. You’d need to change how the script works if you had different servers you were deploying to.

    2) The SVN site is not currently configured for public reading. We’ll get this fixed tomorrow.

    Like

  8. Jim Priest said:

    I need to download this and try it but in a nutshell – I usually develop locally and use Ant to push my files from SVN up to the server.

    This sounds like it installs on the server and you are then pulling the files from SVN directly to the server – making changes to them, or to the server if needed using the CFAdmin info??

    I doubt I could ever get the server overlords here to install this on our production server 🙂

    Like

  9. Doug Hughes said:

    Jim – If nothing else, you’d need to put the remote admin proxies on the server to use the CF admin ant tasks.

    What I find interesting is that they’d rather have something like an FTP port open on the server instead of a build script that could accept passwords via input.

    Anyhow, I think the most useful part are the ant tasks.

    Like

  10. Shannon Holck said:

    I’m confused by Boyan’s comment.

    and CFAnt seem to be two different things.

    allows you to execute the ant executable from a coldfusion page

    CFAnt is a set of libraries that define tasks for using within your ANT buildscript. I see that to avoid confusion, it appears the new generation of this project has been renamed to Ant4CF

    See also ant4cf.riaforge.org

    Thanks, Doug! Ant4CF looks awesome! 🙂

    Like

  11. @Shannon – Thanks for the comment. FYI, cfant is now ant4cf. Ant4CF could be considered the version 2.0 of cfant. I changed to name to reduce this confusion and to illustrate that there were some significant changes under the hood.

    Like

  12. I am to submit a report on this niche your post has been very very helpfull

    Like

  13. where do i get more information on this

    Like

  14. CFANT is not working for CF 10 . Does CFANT support CF 10 ?

    Like

Comments are closed.

Tag Cloud

%d bloggers like this: