-
Notifications
You must be signed in to change notification settings - Fork 451
Function App Zipped Deployment
To enable the feature at runtime, and app setting needs to be set, e.g.
WEBSITE_DYNAMIC_CACHE_ZIP_CONTAINER_PREFIX=web
This string is the prefix for the name of the container zip files. The full zip file name will look like this:
web_2017-01-06T17-14-34.zip
The zip files are deployed to the d:\home\site\wwwroot
folder. They contains everything that would normally exist expanded under the wwwroot folder.
The App Service Infrastructure always uses the latest version of the zip file (in lexicographic order).
From the point of view of the Functions Runtime, the wwwroot folder appears completely normal, with all the expanded files and no trace of the zip.
Under the cover, the files are only unzipped to a temp folder on demand, which can greatly minimize the startup cost. In particular, when the app has a large npm tree, only the files that actually need to be used (typically a small subset) end up getting copied.
There are two main reasons to do this.
The first is that it avoids complex locking/conflict issues that could happen if you try to publish to the same file name that's already being served.
The second is that it opens the door for a revision mechanism. By simply deleting the latest file, the runtime will automatically go back to the previous version. We can also have the App Service runtime enforce a limit, like only keep the last 5 files (configurable).
Initially, only uncompressed zip files will be supported. In most scenarios, the zip files are created by a tool we provide, so this is mostly a black box to the user.
We could go as far as using some custom extension instead of .zip
, but I feel there is enough value in staying with the well known extension, even if creating it in a way that works requires special care.
The Function Runtime should not be affected by the use of this feature, because all the magic is abstracted in a layer below it.
The main difference is that this folder is no longer writable. That means that function files can no longer be added/deleted/modified. The Function Runtime itself never does those things anyway (Kudu does), so it shouldn't affect it.
Note: we have the choice between blocking writes altogether, and allowing write but have them be lost on site restart (and not shared between instances). I prefer blocking, as it makes the semantic clearer, and prevents incorrect user assumptions.
When the zip file is updated with a newer version, the right magic needs to happen to make the Function Runtime start using the new zip. This needs to happen with minimal downtime to the Function Runtime, allowing a smooth deployment workflow even without the use of site slots (though slots can still be used for more advanced scenarios that require staging).
The tentative plan is to rely on overlapped recycling, where a second worker process starts on the new bits while the old one is drained.
The previous section discusses how the runtime handles a deployed zip file. This section discusses the various ways that this zip file can be created and deployed to the app.
While it's possible to build the zip file simply by zipping up a source function folder (and disabling compression), there are additional steps that can be taken to optimize it. In particular, C# functions can be precompiled into assemblies to avoid the need to have to do that at runtime. The tool can also restore npm/NuGet packages.
In order to make these steps easily usable from a variety of deployment scenarios, they can be abstracted into a command line tool (as well as a library). That tool (let's call it the Function App Packager) takes a source function folder as input, and produces the optimized zip file, with the proper naming pattern (per above). The caller doesn't need to be aware of all the transformations/optimizations that come into play.
This tool will be made available on NuGet. The following sections discuss some of the scenarios in which it is used.
Generally, the way Kudu deploys things is by taking a sequence of steps that turn whatever files are in the repo into files that end up in wwwroot.
For our zipped Functions scenario, that makes it a perfect use case for the Function App Packager tool. Basically, the Kudu deployment script becomes as simple as invoking the tool, passing it %DEPLOYMENT_SOURCE%
as input folder, and %DEPLOYMENT_TARGET%
as output folder. Note that there is no need to use kudusync in this scenario.
In order to do this, Kudu will need to either include the Function App Packager tool, or obtain it dynamically using NuGet.
When using a Function App in 'dev mode', the user directly edits function files using the portal, and tests them in the dev app. When they're ready to push to a production (or staging) app, they hit a publish button, which works as follows:
- When the user sets up publishing from the dev app to another app (or slot), an app setting is created on the dev site, containing the publishing URL of the target app. e.g. it might look like
AzureWebJobsPublishingUrl=https://$MyProdApp:SiteCredPassword@MyProdApp.scm.azurewebsites.net/
. - When the publish button is clicked, the Portal calls a new Kudu function publishing API.
- The API first uses the Function App Packager tool to create a zip file from the function files. This is similar to what Kudu does during continuous deployment, except that here wwwroot is the source instead of the target.
- It then calls the Kudu vfs API on the target app to copy the zip file. Then the target app's runtime takes it from there.
The standard way the VS deploys to Web Apps is using msdeploy, and this can also be the case here. VS needs to add the right msbuild target files that do the magic of calling the Function App Packager tool to create the zip file. The zip file then becomes what it deploys using msdeploy, just like it would deploy anything else.
The fact that the Function App Packager logic is abstracted by msbuild target files means that everything related to deployment works using completely standard msbuild commands. This allows all those other msbuild-based workflows to just work without needing much special knowledge about Azure Functions (they just need the right target files).
- Configuration Settings
- function.json
- host.json
- host.json (v2)
- Http Functions
- Function Runtime Versioning
- Official Functions developers guide
- Host Health Monitor
- Managing Connections
- Renaming a Function
- Retrieving information about the currently running function
- Site Extension Resolution
- Linux Consumption Regions
- Using LinuxFxVersion for Linux Function apps
- Out-of-proc Cancellation Tokens
- Assembly Resolution in Azure Functions
- ILogger
- Precompiled functions
- Official Functions C# developer reference
- Contributor Onboarding
- Development Process
- Deploying the Functions runtime as a private site extension
- Authoring & Testing Language Extensions
- Bindings in out-of-proc
- Language Extensibility
- Worker Capabilities
- Investigating and reporting issues with timer triggered functions not firing
- Sharing Your Function App name privately
- Azure Functions CLI release notes [moved here]
- Function App Zipped Deployment [deprecated]