In this article you'll learn how to deploy your source code to Azure Functions using just a few lines of C# powered by Pulumi.
We'll start by creating a regular new Azure Function project, which you can either do from Visual Studio 2019 or using the func command line tool. The Visual Studio template will already create an HTTP-triggered function as an example, using the
func cli will require you to call
func new after creating the project using
Implementing, testing and building the Azure Function project is absolutely not affected by using Pulumi for creating Azure resources & deploying your application — this article will focus on the part that comes after you ran
dotnet publish on your function project.
Friends don't let friends right-click publish
While Visual Studio offers the option to publish an Azure Function project directly to an existing or newly created Azure Function resource, without requiring you to head to the Azure Portal to create the resources manually, you'll be left with no means to automate the creation of all the required resources and deploy your application. In this article, we'll use Pulumi to implement an automated infrastructure-as-code style approach for resource creation and application deployment.
In addition to your Azure Function project, you'll need a second project for your infrastructure code. This can be a regular .NET Core command line project — you'll just have to add a reference to the Pulumi.Azure nuget package. But we're getting ahead of ourselves — lets start with some installation requirements.
Since we will be using Pulumi for creating Azure resources and deploying our application, you'll need the Pulumi CLI installed. The documentation shows a range of installation options for various operating systems. You can verify if the installation was successful by running
Also, you'll need to install the .NET Core SDK.
Lastly, installing the Azure CLI is required - Pulumi uses it under the hood. After installation, you'll need to run
az login in order to create the resources in the right target subscription. There are other ways to configure the target subscription for pulumi programs, but this is the one we'll stick with for this article.
With that, you should be ready to go.
Now, let's continue where we left of — with a completely empty .NET Core command line project, in which you just added a dependency to the Pulumi.Azure nuget:
The only thing you'll need to add in addition is a
Pulumi.yaml file next to your
Now let's add a stack — stacks are Pulumi's notion of a deployed environment. A stack defines all the required resources, and can be instantiated multiple times in order to create a range of environments. The documentation puts this as
Every Pulumi program is deployed to a stack. A stack is an isolated, independently configurable instance of a Pulumi program. Stacks are commonly used to denote different phases of development (such as development, staging and production) or feature branches (such as feature-x-dev, jane-feature-x-dev).
Using the .NET SDK, a stack is nothing else than a class creating all the required resources in its constructor. Deploying the stack when running your pulumi program is a one-liner in the
This pulumi program can be run by calling
pulumi up within the pulumi projects directory and will create the resources defined in the stack:
A resource group, and within that...
A consumption based app service plan
A storage account
A function app configured to use both the plan and the storage account
pulumi up will — at least on your first run — ask you for a name for the stack to create. Just choose something that makes sense to you — I chose "dev". The stack name will be reflected in the names of the created resources.
Now that you've got a brand new Azure Function App created (it should show up in your Azure Portal), let's run
dotnet publish on the function app project (not the pulumi program) and deploy the files created as a build output to the Function App. We'll do this by creating a .zip file as a new blob in our storage account, and then configure the function app to run from that .zip file:
GetSignedBlobUrl in the snippet above is a helper function you can find here.
And that's it — your next call to
pulumi up will bundle the output of your earlier call to
dotnet publish into a .zip file, upload it into a new blob, and configure the Function App to use the contents of this blob.
Christian Eder is a Lead Software Architect working for Zühlke Engineering and has a strong background in all things cloud, with a focus on IoT projects. He helps his customers in finding the right solutions, defining suitable architectures and efficient implementation.