Saturday, July 20, 2013

F5 LTM iRule Testing

I've been working with F5 LTMs for a few years now, and over time the configuration has accumulated some significant technical debt. Well, the time has come to clean it up, and unfortunately the configuration needs so much rework that it will be simpler just to rewrite all of the logic. That's where a testing tool comes in.
To rewrite all or a significant portion of the iRules, I needed a way to test the existing iRule logic and capture a snapshot of which logic works and which doesn't so that when the logic is revamped, it can be tested again to verify that the same functionality exists. After searching online for a while I came to the conclusion that the tool I needed didn't exist, so I decided to write one. It's called irule-tester, and it's written in Bash and leverages Curl to make the web requests.
I know some of you are going to cringe about it being written in Bash.  Hey, it works.  I was even able to put in a command-line argument that allows you to switch out the testing output format.  The results can be color-coded, plain text, or dumped in TAP (Test Anything Protocol) format so that the testing can be easily dropped into Jenkins for automated testing!
Write all iRule logic in a way that it can be tested.
When I started writing irule-tester, it quickly became obvious that some of my existing iRule logic would need to be changed to support reliable testing. This presented a chicken and egg scenario because some of the iRule logic needed to be rewritten to support the testing, but I needed the testing to validate that the changes were successful and didn't break anything. Because of this, I now believe that all iRule logic should be written in a way that allows external testing and validation of each iRule operation. To get through this, I created a function in irule-tester that just logs when a given piece of iRule logic can't currently be tested. This allows us to at least get the majority of the iRule logic tested and marks the part we can't as areas to improve in the future.
Environment agnostic LTM iRule methodology.
Another issue I've stumbled on over my time with the LTM is the complexity of performing periodic environment refreshes. From time to time, it becomes necessary for us to refresh our non-production environments from production, or to create a project environment based off of production and this is always painful. More specifically, it's difficult because each iRule contains environment-specific object names (classes, websites, pools, etc).
To solve this problem, I came up with a way to standardize the configuration across all of the environments in a way that allows true iRule code promotion across environments. The method involves creating an environment-specific 'variables' iRule which just sets variables for each object that is referenced in an iRule. This allows you to have a single iRule that sets variables that are different in each environment, and then have supporting iRules that carry out the traffic management logic and leverage those variables in place of the environment-specific objects.
You can see an example of what I'm talking about by looking at rule STD01 of my iRules standards on Github.