Applying DevOps principles to projects based on customized Commercial Off The Shelf (COTS) products can feel really hard sometimes. Honestly, the same can be said for a lot of Open Source projects as well. It’s not that the software is bad — in fact, part of what makes these tools great might also make it hard to automate deployments. Software like Atlassian Confluence or Drupal work hard to make sure that you can do a lot from a web control panel. A less mature environment might just have a labyrinth of config files to navigate.
The problem on the DevOps side, is that config files are really easy to change via simple scripts. Web based control panels — not so much. You may find that folks on your team are resistant to the idea that it is even possible to automate configuration or deployments for this kind of click-and-type configuration But it does work just fine if you embrace tools like Selenium as part of your deployment pipeline.
Here is my sample project that builds a Java application to change a configuration setting in Confluence. Specifically, this will disable threaded comments — but you can make any configuration or content change with the same technique.
If you do go down this road, there are a few things I would suggest doing.
#1 Use environment variables or a config file for all your site settings
Don’t commit to code things that are properties of your environment. The obvious things are passwords, but if you have multiple environments then the site URL, usernames, and other configuration might be different for each env. Here’s the Java I’m using for filling in the username and password:
driver.findElement(By.id(“os_username”)).sendKeys(System.getenv(“CONF_USER”));
driver.findElement(By.id(“os_password”)).sendKeys(System.getenv(“CONF_PASS”));
#2 All configuration changes should be idempotent
In DevOps land, an operation or function is idempotent if it leaves the system in the same state no matter how many times you run it. For web based configuration, something like updating a text field is easy to keep idempotent. No matter how many times you write the same thing into that input box, it is the same. But checkboxes will toggle values every time you click them. For those cases, make sure your code doesn’t just click the box but instead ensures that the box is set to the expected state:
public static void setCheckedState(String elementID, boolean desiredState) {
WebElement el = driver.findElement(By.id(elementID));
if (el.isSelected() != desiredState) {
driver.findElement(By.xpath(“//label[@for=’ ” + elementID + “’]”)).click();
}
}
#3 Be smart about element selection
Best case, you can select elements to be clicked or change using the element ID. If that’s not possible, I highly recommend using XPath. CSS can get really messy and doesn’t easily allow you to select elements by their content. Here’s an example of selecting the button based on the “Save” text inside the element, which is unique on the page being manipulated:
driver.findElement(By.xpath(“//input[@value=‘Save’]”)).click();
#4 Build for headless, allow graphics
Selenium and other RPA tools allow you to run your scripts in a “headless” mode. That’s great for running on a CI/CD pipeline without a GUI desktop installed — but it makes development very hard and debugging even harder. When you first write our new configuration steps in code, being able to see the browser run is the key to making this all work. It’s even more critical when trying to debug what might be going wrong should you need to do so.
#5 Things I have usefully automated
My example code is pretty trivial, but it is just an example. There are better things to automate that give a much better return on investment.:
- Templates and Macros — Confluence allows you to create templates and user macros in the web configuration screens. Configuring these in your DevOps pipeline lets you keep the contents in source control.
- Page Content — If you have specific content pages, such as help text or a user manual, you can automate deployment of that content so it arrives exactly at the same time the site functionality changes
- Plugin and License Updates — If you have a large number of environments with multiple plugins, being able to coordinate updates across them will save a lot of time. Extra useful if you have individual development environments. Being able to sync up every dev system is invaluable.
The real benefit though is just being able to automate a full start to finish deployment. Accurate deployments in your CI/CD pipeline is foundational for good DevOps practices. There is so much you can’t do if a deployment isn’t fully automated.