DevOps for NodeRED on Bluemix
Hickmat 100000QA3T Visits (8625)
Following on from my last post, since coming back from my Christmas break I've had some spare processing cycles which I've been able to apply to creating a DevOps solution to allow me to promote Bluemix based NodeRED configuration to other Bluemix based NodeRED applications.
So what have I been doing and why....
Firstly lets look at the Why. Over last last year and a bit I've been playing with UrbanCode Deploy, NodeRED and Bluemix with a view to understanding who I could link a NodeRED component into a broader deployment story i.e. one which may encompass deployment to other middleware like IBM BMP as well as NodeRED. I had this covered with the local install version of NodeRED as that uses the file system to store its underlying JSON files (flow, credential and settings) but the Bluemix based version uses Cloudant to persist this information. So If I wanted to start developing a NodeRED solution in one Bluemix environment and application instance and then move that configuration to another application instance which may or may not be in another Bluemix environment then I needed to enhance / update my initial approach.
Now what have I done. So given I now needed to work with Cloudant my first task was to create a plugin to allow me to interact with Cloudant so I could access the NodeRED JSON data. This is the work I documented in my last blog entry. Next I needed to look at how I could work with the NodeRED environment hosted in Bluemix. I knew that I fundamentally had two key steps as follows:
Starting with step 1 I took a design decision that I would use Rational Asset Manager as the repository to store the JSON assets which make up my NodeRED application. Using my Cloudant plugin and the provided RAM plugin I created the following UrbanCode component process:
To ensure that I could easily manage difference in the various NodeRED instances i.e. Cloudant endpoints, userids, tokens etc I took the approach of pushing all this level of configuration into properties which are picked up from Environments defined in UrbanCode. So I could testing this out I set up 2 spaces under my Bluemix account (dev and test) and then created a new NodeRED app n the dev space (I already had an existing one configured with some suitably complex NodeRED flows) and an extra one in the test space. I then configured my UrbanCode environment as follows:
I created the above process under my "IoTFlow" application and once this was in place I was able to test it out. I had set up my source NodeRED environment as being represented in UrbanCode as the DEV environment so to test the process I simply executed the process at the component level and pointed it at the DEV environment. This worked a treat and asset (who's unique ID I configured under the basic settings of my "IoTFlow" component) was created in RAM and the NodeRED JSON configuration was successfully uploaded to it.
With the JSON now stored in RAM I set about creating an UrbanCode component process to manage the deployment of the JSON back into a NodeRED instance. At a high level this process needed to do the following:
In the case step 3, in order to update an existing document in Cloudant I first needed to read the document so I could get access to the _rev attribute as this needed to be passed along with the _id for the document in order to make sure a new version of the document wasn't created. In addition I found that of the 3 configuration JSON files in NodeRED only the "credential" JSON file isn't created by default. Based on this I had to define my process to take into account that in some cases I may need to "create" a new document rather than "update" an existing one. In the flow (shown below) you can see that I do this by taking a failure to read the credential document as a trigger to call the "create" step rather than "update".
The final step I took was to create an UrbanCode Process at the application level to execute the Deployment of my "IoTFlow" component. With this all in place I was then able to run the Deploy process for the TEST and PROD environments which resulted in the NodeRED configuration from my DEV environment being replicated into each of these environments.
So job done I still need to do some testing to ensure the flows are all working but the core approach looks to be proven. In addition just now I'm moving the JSON ASIS, I could see that there may be a need to tokenise some elements in the NodeRED JSON such that it can be adjusted as deployment moves from environment to environment. This would be relatively simple task of taking the imported JSON files from RAM, tokenising the appropriate areas and the updating the asset in RAM with the updated files. These tokens can then be easily replaced via the standard capabilities of UrbanCode as part of the above Deploy process.