Replacing an iFile on F5 BigIP using Ansible
Intro
F5 BigIP offers the option to upload small files as so called iFiles and allows you to use them in iRules. This enables you to distribute files without having to upload them to your servers. Since these files get occasionally changed, the idea of using Ansible to create a streamlined process, that backs up the current file and uploads the new one seemed like a good idea. The upload through the GUI is done by selecting the upload button on the iFiles site and then selecting overwrite in the new window. Should be an easy task to implement, but as it turns out it sadly is not.
Object locking in BigIP
In BigIP an object can only be deleted if it is not used in any other object.
This creates an issue for us, since the “overwrite” option of the file Module of the F5 collection does in fact not overwrite the iFile, but instead deletes and then replaces the iFile.
The iFile is the lowest part of a stack of objects with the following hierarchy:
Virtual Server -> iRule -> iFile List -> iFile
Objects using lower level objects do not have to be deleted, but all references to the lower object have to be removed.
Developing a solution
After identifying all involved objects, I started working on a solution for a simple virtual server without pools and only a single iRule
The idea was to destroy the stack from the top to the bottom, to upload the iFile and to rebuild the stack afterward. The only roadblock I ran into was the LTM iFile list which is currently not implemented in the BigIP API and thus not in the Ansible collection, the command module can be used to send the CLI commands for deleting and creating the iFile List.
The finished solution looks like this:
When executing the script, the file is unavailable for the duration of the playbook, which is why I ultimately decided not to use it in production.
Closing thoughts
While I came up with an idea to eliminate downtime a couple of days later, I decided to not implement it, since at this point I would have been adding way too much complexity in order to simplify an already simple task.
The optimized playbook would look like this:
Since my playbook has this huge downtime issue, I didn’t upload it this time, but if you are interested in it, just contact me and I will add a public repository for it.
Overall my opinion of the F5 Ansible collection is quite positive even though it, as this article shows, is still missing some functionality. An issue a lot of other big vendors face too.
Post Scriptum: A solution using the API
After looking at the API documentation and playing around with the file related endpoints, I came up with the following script:
filepath='/opt/test/myifile.txt'
filesize=$(du -b $filepath | awk '{print $1}')
curl -X POST https://10.0.0.1/mgmt/shared/file-transfer/uploads/testfile.txt -k -u user:pass -H 'content-type: application/octet-stream' -H "Content-Range: 1-$filesize/$filesize" -T $filepath
curl -X PUT https://10.0.0.1/mgmt/tm/sys/file/ifile/myifile.txt -k -u user:pass -d '{"system-path":"/var/config/rest/downloads/testfile.txt"}' -H 'content-type: application/json'
This has the desired functionality of replacing the file without having to edit any other objects. I am surprised this is not implemented in the Ansible module.