With any coding project it is important to understand how to manage your code assets.
This is good practice to undertake when your project is small enough so it is easy, and it becomes vital when the volume of code increases and you have many people working on it.
App Services in Microsoft Azure have a long history of of version control through a number of popular source control systems, such as Visual Studio Team Services and GitHub, and a number of file-based solutions, such as Dropbox and OneDrive.
Azure Functions were introduced at //build/ in 2016 as the new kid on the block in App Services, and whilst they have recently been removed from Web + Mobile in favour of Compute, they are still part of the core App Service model in Microsoft Azure.
Because of this, they have a lot of the capabilities around source control, and just as importantly continuous deployment, as the underlying platform service.
For this post, I though it would be useful to check out the structure of a Function App and how you can easily set up continuous deployment.
I will use GitHub for source control, and GitHub Desktop to manage my local repository, and cover the use of a file-based solution also, which in this case will be Dropbox.
First I need to create a new Function App and put some functions in it. Strictly speaking putting the functions in to start with doesn’t need to happen as you can deploy directly and immediately from source control without having the function stubs, but it’s useful to first understand the folder structure of a Function App as that is important when you set things up.
A Function App sits in the same file structure as a normal App Service app, with a number of folders off the root. You can use a Debug Console in Kudu to have a browse around the full structure.
The real work goes on under the site folder and it’s under here you’ll find wwwroot, which is the main folder that contains all the functions themselves.
The important part about the wwwroot folder is that the contents are the root for any source control you set up and not the wwwroot folder itself.
I have already created a couple of functions to show some general structure, one containing a timer trigger using C#, and one containing a timer trigger using Node.JS.
Each folder contains the function itself, and possibly a project.json file for C# that allows NuGet package management, or a package.json file for Node.JS for npm package management.
NuGet packages are restored and stored off the main root of the Function App, whilst npm packages are restored and stored under the specific function to which they apply.
So now we know structure, how do we setup source control. Let’s start with doing this for GitHub.
From within Kudu you can easily download a zip file that contains the contents of a folder, so we grab that and unzip to a local folder.
Using GitHub Desktop we create a new local repository and then put the contents of zipped wwwroot folder in it.
This is the important bit, we need to have the repository pointing to the files and folders that are within the wwwroot folder, not the wwwroot folder itself.
We now sync this up to our GitHub account and we’re ready to set things up in the Function App.
Within the Function App we go to App Service Settings, and choose Deployment Options.
We need to hook up our GitHub account, which is just a simple authentication step, and then select the repo we’re interested in.
And that’s really all there is to it.
If we make a change to the local repository and then push, we can see the code is changed accordingly. You’ll also notice that the code view in the browser shows that the file is read only because it is being updated in source control.
You get a bunch of options for looking at what has been happening with deployments and a chance to redeploy if necessary.
So what about file-based deployments. If we copy our code up to Dropbox, again remembering that we need to use the folder structure UNDER wwwroot, and not wwwroot itself, then the process is largely the same.
First we unhook the GitHub deployment, and then attach our deployment process to Dropbox. Again we do the authorisation dance, and choose the folder containing our code. It is important to note, the folder that you’re looking for is under [DropboxRoot]\Apps\Azure\[FunctionAppName]. So that is where you need to stick you wwwroot folder contents.
If we open our code from Dropbox directly, then when we do a Save, we would expect the code to be pushed directly to our Function App. However, I’ve found that you have to manually initiate a sync from the Deployment options blade.
So, again pretty simple to set up and configure.
Now obviously there is no error checking here, or deployment slots like you have with Web Apps, so some caution should be exercised.
Does it work the other way? If we change our code in the online editor does our source code repository get updated?
Well, no it doesn’t I’m afraid because once you’re hooked up and deploying you get the read only message.
So there you have it, the file structure of a Function App is pretty straightforward and taking control of your code is simple enough if you follow the basic rules about which folder level you point to, and just to be 100% sure, that is the wwwroot folder contents, NOT the wwwroot folder itself.