A while ago I talked about “Faas/Serverless” in relation to vendor lock-in. Today we’ll be continuing in that road, where we’ll be doing a small proof-of-concept (PoC). In this PoC, we’ll be replatforming existing Azure Functions code into an Azure Functions container!
Things to know
Since Azure Functions 2.0 (in preview at the time of writing this post), you are able to leverage containers. Though be aware that there are several known issues. Do check them out first before embarking on your journey!
So first, we’ll start off with testing the Azure Functions Core Tools! If you’re looking to follow this guide, be sure to have the Azure Functions Core Tools installed, which also depends on .NET Core 2.0 and Nodejs. Once you have those installed, do a “func –help”, and you’ll see what capabilities are at hand…
We’ll be kicking off with creating a small sample project ; func init MyFunctionProj
That’ll create some basic files… Though not enough to have something to show right away.
So let’s add a function ; func new –language C# –template HttpTrigger –Name MyTestFunctionCOntainer
And that will create something “useful”! 😉
Let’s see if that would suit our “helloworld”-demo? We’ll be starting the function host via ; func host start
We’ll see that our function has been loaded and it’ll show the URL that we can use to call the function.
The function replied, as expected, and told us to provide additional parameters. In our console, we’ll see that the call was registered at our host.
Easy peasy?!? Correct! But that wasn’t the objective I promised you… Now let’s crank it up and switch to the next gear.
Azure Functions 2.0 – Container Style!
For our next test, we’ll do the same thing, but by leveraging containers! Let’s initialize our project ; func init –docker
If we take a look at the Dockerfile, we’ll see that the recipe is quite simple and is leveraging a docker hub image.
Let’s try out our “virgin build” first.
It’ll retrieve the base image we’ll start building from, and then do it’s regular “docker magic”.
Now that we have our image build, let’s run it…
And when we connect to our host, we’ll see that we’re greeted by a nice landing page. 😉
Adding a new function to our virgin build / container
Let’s create a function like we did in the first “helloworld”-demo ; func new –language c# –template HttpTrigger –name HttpTriggerTestInCSHarp
Now we’ll see that our Dockerfile is left untouched, and that we have an additional folder in our project ;
If we check out that one, it’ll show the contents of a typical Azure Functions. Which is a very good thing, because this means we don’t need to refactor anything!
Building things again…
Though, on a side note, when testing things… I would advise to change the authLevel to reduce the friction at this time. 😉
Now let’s run our container and see if we get a result… Jihaaaahh!!! 😉
Still going Easy Peasy?!? Correct 😉 Let’s crank it up another notch!
Replatforming existing code into our container
I’m going to clone an existing repo and pick one existing function from there…
Now that I have my repo, I’m going to use “getVmSize” as the function I’m going to replatform during this PoC.
And again, let’s quickly change the auth level for our PoC.
And let’s build our container again.
Take a quick glance at the code, and you’ll see that the configuration is triggered by an environment variable.
And this fits right into a typical container strategy too of course! So we’ll set the config via the “-e” setting. (more on this later)
During the startup we can see that the function has been loaded.
And when we call the URL, I saw that the function wasn’t being routed.
Here I did added a function with the same name via the Azure Functions Core Tools and added the code to that newly created directory.
When starting, I saw the following error message. Due to my bad coding, I had installed the mongodb module by hand in my previous setting… (bad boy, I know)
So let’s add that again…
Where now we are greeted by a different error message ;
This was due to the way the new mongodb libraries handle passwords with “special” characters in them…
As it seems “=” is seen as a special character, we’ll need to “URI Encode” it.
Once that was adjusted, our function loads pretty nicely!
And we’ll see that in our console log too… 😉
Investing in Azure Functions isn’t a foolish thing to do. My personal advice to organizations is typically to start off with functions… There are use cases where containers (AKS/ACI) and/or ServiceFabric immediately proof their value. Though I really like the low entry barrier of Azure Functions in combination with the vast amount of power it can provide to your project(s). And in case that, at a give time, you “outgrow” Azure Functions. Then I think we can conclude that the investment in’t lost. You can rehost it into a container and build further from there. So there isn’t a necessity to do refactoring, unless you see it fit for other reasons. And in a container, you can port it to any location you want ; Azure AKS, Azure ACI, … OnPrem… other cloud vendors. Whatever you want.