Deploying a nuget package to an azure function

martenolofsson's Avatar

martenolofsson

04 Feb, 2018 04:35 PM

Hi,

First of all, thanks for an amazing product. I've been using octopus for some years now, always a pleasure. :)

Now to my question. I have a project containing an azure function which I package as a nuget package using octopack in VSTS and then sends the nuget package to my octopus deploy instance. In my octopus steps I use an ARM-template to create the function app and then I'm deploying the nuget package using "deploy an azure web app". The deployment succeeds and I can see that the files have been deployed to the function. The problem is that the structure when deploying an azure function is different, which has the end result that my functions are not runable. I'm guessing that either the nuget package structure should be different, or that I should use another type of template when I'm deploying my function? Is there a preferred way of solving this?

Best,
Mårten Olofsson

  1. Support Staff 1 Posted by Dalmiro Grañas on 09 Feb, 2018 02:15 AM

    Dalmiro Grañas's Avatar

    Hi Mårten,

    Thanks for reaching out!

    Your question actually brought up to our attention that Azure Functions show up in the dropdown list of the Deploy an Azure Web App step. We honestly did not know about this, and we are pretty sure it wasn't always the case. Sometime in the last couple of months Microsoft must have changed something on their end in a way that when we call their API to get the list of web apps, it also pulls Azure functions.

    This is great news for us because we were planning to add first class support to Azure Functions (as in a dedicated step) in the upcoming months. We will still do this, but its great to know that the Deploy an Azure Web App step gets 90% of the job done.

    So after reading your question, I did some research on how to deploy functions using Octopus, and turns out it works very well. The only caveat is exactly what you asked: "How are the files supposed to be arranged on the package so the function works when Octopus pushes it to Azure?"

    There are 2 ways of getting the right output:

    1) From the Visual Studio UI - If you Right click -> Publish on your function project, you'll be prompted to create a publish profile. Select the option to publish to a Folder (see attached screenshot) and run it. MSBuild will compile the app and drop the output to a folder. If you package up exactly what's in that folder, and use it on the Octopus step, the function will work as expected.

    But we have a saying at the Octopus office that goes friends don't let friends do [Right click] - [Publish], so instead I recommend you use the next option

    2) From MSBuild commandline/buildserver (Recommended) - Do Right click -> Publish on your project and create the profile to publish the build output to a folder. This will add a profile file to your solution which you should commit to source control. Then follow the instructions on this StackOverflow post (which is exactly what I did) to run MSBuild using that profile. This approach will work a lot better in automated scenarios using build servers.

    Whether you go with (1) or (2), once you have the output on a folder, put it in a Nuget package and deploy it with Octopus.

    The reason why you need to use the MSBuild Publish method is because MSBuild doesn't just compile your azure function, but it also adds some secret sauce to the output (typical Microsoft) to make it work when you push it to Azure.

    I have attached a zip with a nuget package that contains the test azure function app that I used on my end. Try to use to get an idea of how the package should look like.

    Hope that helps!
    Dalmiro

  2. 2 Posted by Tim Duncan on 15 Feb, 2018 06:42 AM

    Tim Duncan's Avatar

    Hi Mårten,

    Is there also some guidance on how to update the appSettings for the Function App using the Octopus project variables or library variables?

    Either as part of the deployment step or a separate step would be fine.

    Regards,
    Tim

  3. 3 Posted by martenolofsson on 15 Feb, 2018 02:40 PM

    martenolofsson's Avatar

    Hi Dalmiro,

    Oh, cool. I actually tested this exact procedure earlier and it did not work, but later doing the same thing the function app showed up, I just figured I made some mistake but probably there were som api updates in azure. :)

    Your suggested approach would probably be the best solution. Thanks for the suggestion. I was exploring if there was some build in functionality, either in octopack when creating the nuget package or in the deployment process. What I ended up doing was just adding a copy files step in VSTS and included the files needed and from that created a nuget package which also worked fine.

    @Tim - I've been using ARM-templates to set my appsettings so that have not been a problem for me, I guess you could do the same thing using powershell but I have not tried it.

    King Regards,
    Mårten

  4. Support Staff 4 Posted by Dalmiro Grañas on 15 Feb, 2018 08:02 PM

    Dalmiro Grañas's Avatar

    @Marten - Glad to hear you sorted it out :)

    @Tim - During my tests I also used an ARM template like Tim did. In these lines I'm declaring 4 AppSettings. You can ]deploy your ARM template from Octopus using our built-in step](https://octopus.com/docs/deploying-applications/azure-deployments/r...). I encourage you to try it this way.

    If instead you want to stick with Powershell, you can do it the following way:

    1) In your Deploy web app step, enable the feature Custom Deployment Scripts and add the below script as a Post-deploy script:

    $FunctionName = "TestFunctionName"
    $ResourceGroupName = "TestResourceGroupName"
    
    $webapp = Get-AzureRmWebApp -ResourceGroupName $ResourceGroupName -Name $FunctionName
    
    $currentAppSettings = $webapp.SiteConfig.AppSettings
    
    $updatedAppSettings = @{}
    
    foreach($appSetting in $currentAppSettings){
        $updatedAppSettings[$appSetting.name] = $appSetting.value
    }
    
    $updatedAppSettings["NewAppSetting1"] = $ValueOfNewAppSetting1
    $updatedAppSettings["NewAppSetting2"] = $ValueOfNewAppSetting2
    
    Set-AzureRmWebApp -Name $FunctionName -ResourceGroupName $ResourceGroupName -AppSettings $updatedAppSettings
    

    make sure to change the name of the function and resource group in the script accordingly

    2) Create 2 new variables in Octopus with the same names as the variables you are using in Powershell to set the value of your app config. In the case of this script we are using $ValueOfNewAppSetting1 and $ValueOfNewAppSetting2, so we should create 2 Octopus variables called ValueOfNewAppSetting1 and ValueOfNewAppSetting1 (see attached screenshot).

    3) Once you run the deployment, you should end up with 2 new AppSettings in Azure as shown in the attached screenshot.

    Hope that helps you get up and running :)

    Dalmiro

Reply to this discussion

Internal reply

Formatting help / Preview (switch to plain text) No formatting (switch to Markdown)

Attaching KB article:

»

Attached Files

You can attach files up to 10MB

If you don't have an account yet, we need to confirm you're human and not a machine trying to post spam.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac