Going serverless with PowerShell

Why should JavaScript developers have all the fun?

PowerShell + Azure Functions = ❤

One of the current hype buzzwords going around is “serverless”, very (very) simplified there’s still a server you just don’t see or manage a server and you can be billed by individual usage of “functions” instead of per web app basis. Making scale and cost much more granular and also less ceremony to get a piece of code up and running.

Microsoft serverless offering is called Azure Functions and in this post I will go thru how to setup a continuously deployed HTTP API powered by PowerShell. I’ll assume you already have an Azure Subscription in place and some basic Azure Portal knowledge. One word of warning, while Azure Functions is released and stable, using PowerShell to write functions is still in preview and might be subject to change.

Developing from source control

Even though you can create/edit your functions directly in the portal, that’s not how I roll, I want all my code in source control, versioned and backed up outside the environment it’s deployed to. Which also lets you easily reuse your functions between subscriptions for i.e. different environments like staging and production. Also where’s the fun in doing it the easy way?

Starting from scratch

In this case I will be using a GIT repository on GitHub, but there’s several other good options like Visual Studio Team Services, Bitbucket and more.

So what are the minimum pieces needed to get Azure functions going? Well first we need an GIT repository.

Once a repository is created we need to create a host.json file in the root of the repository, it contains global configuration options affecting all functions. I’ve created a small PowerShell script letting me create a host.json file in a somewhat typed and validated way (I’ll include that script at end of post for reference), example usage:

Above will create a minimal host.json like below, where id is a unique GUID for this function app job host, functionTimeout is duration timeout for all functions allowed execution time and http/routePrefix is the site prefix for HTTP function routes.

With host.json you can override allot of Azure Functions default behaviors around storage queues, ServiceBus, Event Hubs, concurrency, etc.

Now we’re all set to create our first function, each function has it’s own folder and the function name is based on that folder name. What triggers the function is defined in a function.json in that folder, in this case I want to be triggered by an HTTP request via GET method and return response over HTTP without using authentication.

Next we’ll create the actual PowerShell Azure Function, the convention here is to create an run.ps1 which will be the entry point for the Azure Function. It’s basically just a PowerShell script that has a few predefined variables, you can return just a string or a JSON structure letting you control HTTP status codes and headers.

Worth nothing with PowerShell request and response body is file based, so any output from the script will be logged and available as debug output and what’s written to the supplied response file path is what’s returned from the API.

If all works as expected the above should as JSON output greeting to name if specified, if no name specified it should greet the “World”

Now we have our function ready to be deployed and tested!

Creating a “Function App” from within portal

A “Function App” is basically the container for where you put your functions, to create a new Azure Functions app, click the new button and type in “Function App” in the search box:

New search for Function App

Then select “Function App” among the search result

Select Function App

This will open a new “Function App” blade

A new blade will open and you enter the basic information location, subscription, resource group, etc. for the Function App Service, the stand out here though is the “Hosting Plan” where the Consumption plan lets you pay-per-execution and dynamically allocates resources based on your app’s load. App Service Plans let you use a predefined capacity allocation with predictable costs and scale.

After successful creation you should end up at a welcome screen like this

If not you should be able to find your “Function App” under App Services

Creating “Function App” outside portal

For one subscription “Function Apps” wouldn’t show up under available services to add in the portal. Don’t know why yet but I found a workaround for this. Going azure.microsoft.com/en-us/marketplace/partners/microsoft/functionapp/ got me to below website

Clicking “Create Web” got me to the create “Function App” blade letting me setup the rest from within the portal as described previously.

Setting up continuous delivery

With the “Function App” now in place we need to configure that the Azure Functions should be fetched from our GitHub repository, go to “Function app settings” and then “Configure continuous integration”

Then click “Setup”

Choose your deployment source, in this case GitHub

If you haven’t already you’ll need to authorize against GitHub Then if not personal repository chose desired organization Then choose which repository to use And then which branch to use Hit OK to trigger initial deploy

If you close and go back you should see that it’s deploying and once done you should see a successful deploy like below

If you go back and refresh your “Function App” the function should now be listed

Testing your PowerShell Azure Function

Once deployed you’ll be able to reach your functions via https://{yourfunctionapp}.azurewebsites.net/api/{yourfunction}

You can test it directly in the portal using it’s develop and test capabilities

But obviously we want to use PowerShell here too, using the Invoke-RestMethod command makes it easy to do so like below:

Conclusion

It’s relatively easy to get started using PowerShell with Azure Functions, it’s a preview, so not yet as polished or well documented as with C# or JavaScript, there’s parts that doesn’t have a PowerShell feel to it and global variables for parameters, headers, etc. feels a bit unnecessarily “untyped” (almost leaves an icky PHP feel to it). Microsoft are actively taking feedback so if you have any issues or suggestions please let them know by raising and issue on the Scripting Azure WebJobs SDK GitHub repository or enter an idea on their UserVoice.

I’ve done a shared helper PowerShell scripts that I dot source include in my functions, which makes my life easier working with parameters, headers, response etc. cutting down the boiler plate needed between functions. If there’s any interest I might just clean those up and share in a future blog post.

One gotcha as that Azure Functions are still on PowerShell version 4 (version 5 was released shipped with Windows 10, 5.1 shipped with Windows Server 2016 and Windows 10 anniversary update), so you might run into some compatibility issues with scripts that work fine locally.

But that said it’s an excellent service and it has a much lighter feel to it than i.e. Azure Automation — for certain tasks functions is a great fit. And the fact that it’s very basic and regular plain PowerShell makes it very easy to get started, mock inputs/outputs for local debugging and Pester tests.

I’ve found the combination of VS Code, GIT and continuous deployment really appealing. Making it super easy to share functions, setup dev/test/staging environments (deployment slots not yet available but planned to be available in preview soon). Being based on the Azure App Service gives you access to things like Kudu which is really helpful for troubleshooting, advanced deployment scenarios and so on.

So definitely worth trying out!

Please feel free to ping me if you have any questions, feedback or comments in general! ❤