It's been a while since my last blog post. (Even longer, since I wrote this blog post months ago!) Real life got in the way, and I have been 100% focused outside of my personal channels. So, for the past month, everything Basement Programmer-related was put on hold. At the moment, there appears that there may be some light at the end of the tunnel, and so I have an opportunity to sit on my deck, with a coffee in hand on a hot summer day, and start writing a new technical blog post.
Avoiding Vendor Lock-In
As a Solutions Architect working for AWS, I often encountered customers who were worried about vendor lock-in when selecting services. Having been in the IT industry since the early 90's I understand the concern. There are vendors out there whose business model is built around the idea that instead of trying to give customers what they need or finding a price point that is acceptable to the customer, they will instead focus on making the cost of transitioning away from their product (either in the form of money or difficulty) greater than the perceived value of that transition. If it's going to cost you $200,000 in consulting services to move away from my software, and the result is that you might save $20,000, you are likely to keep using my product, albeit begrudgingly.
This idea of keeping customers hostage has resulted in many customers being wary about trusting things perceived as unique offerings. For example, I have encountered some customers in the past who have been wary about using AWS Lambda because Lambda is proprietary to Amazon Web Services. They view "Lambda" as locking, which could prevent them from moving away from AWS and either going to Azure, Google, or another cloud provider.
Cloud is a utility offering
Back in 2014, the idea of AWS Lambda was earth-shattering. The idea that you could write some code, throw it into a managed service, and then something would magically make the code run on infrastructure that you didn't have to provision, maintain, or even know anything about was unique. In 2014, you would be right to be concerned about the idea of vendor lock-in because the entire idea of the service was crazy. Fast forward to 2023, every cloud vendor has the idea of Function As A Service.
Now, each "Function As A Service" offering has its own nuances and specifics of integration with the service. However, at the core, they are just execution environments. In this way, you should look at AWS Lambda, Azure Functions, and Google Cloud Functions in the same light as Virtual Machines. No one would suggest you shouldn't use Amazon EC2 because Azure and Google don't have EC2. If you are concerned with vendor lock-in you would just use the EC2 instance in a way that either avoids or abstracts, functionality that is unique to EC2, such as the instance metadata service.
You can never truly avoid vendor lock-in
In reality, the only way to completely avoid vendor lock-in is never to do anything. If I write my code in Python, because I avoid getting locked into the .NET ecosystem,I am agreeing to lock myself into Python. If I decide to use Mulesoft or Docker to avoid getting locked into Amazon and Lambda, then I agree to lock myself into MuleSoft, or Docker. At some level, the decisions you make are resulting in some form of vendor lock-in, it really comes down to how strong the lock is, and the risk that you have actually to open the lock. Some vendors will make that lock as difficult as they possibly can to open, while others give you the key and focus on making you not want to use it.
As a Solutions Architect, if my customers felt having an exit strategy was important, then I felt it was my job to help them build that exit strategy. It was important to me that my customers knew I was not going to lead them down a path of being trapped. My customers had to trust that I was doing what I felt was in their best interests, and I can honestly say that I did. My job wasn't to make it hard for my customers to leave AWS, my job was to make them not want to leave.
Understand the value
When it comes to Function As A Service, all of your code falls into two broad categories.
First, you have the code that plugs into the service. This is going to be a handler method in your class, code to retrieve parameters, and the code necessary to formulate a return value to the service. This code is unique to the environment and has no real value.
Yes, I said it... Lambda handler code has no value, same for Azure Function handlers, the code exists to make the service happy and to perform the basics of integration. You can tell that it doesn't have any value because the vendor tells you exactly how to write it.
The second category of code is the business logic. What happens once the service has kicked off your function? How do you calculate that value? What do you do with the file? This code has all the value in it, and this code, as long as it isn't locked in the middle of some service-specific code, can be completely portable.
Understanding these two buckets is your key to avoiding vendor lock-in while enjoying all the benefits of Function As A Service. Write your function handler to suit the specific environment, extract your parameters, etc. Then, write your business logic in a separate class or even a separate DLL. Call the business logic function from the handler. In this way, you can have multiple different handlers, one for each cloud provider, and keep the business logic the same.
Want to see this done in a sample project?
Check out the GitHub repo here.
Did you find this article valuable?
Support Tom Moore by becoming a sponsor. Any amount is appreciated!