Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Azure Site Extensions
This post introduces the Site Extension UI in the Preview Portal. Also, checkout this blog post for great information on getting started. The info below offers more technical details about how things work.
When you have an Azure Web Site, an IIS applicationhost.config gets generated by Azure for your site. In some scenarios, it can be interesting to tweak how this file is generated. Site Extensions provide a powerful way to do this using XDT Transforms.
There are two main types of Site Extensions:
- Pre-Installed: they live under
Program Files (x86)and are available to all sites. Kudu and Monaco are examples of this.
- Private: installed by the user as part of the site files. Only apply to one site at a time.
Generally, site extensions can modify applicationhost.config in arbitrary ways by applying transforms to it. Some common usage:
- Adding new applications to the 'scm' site: the Kudu service runs at the root of the scm site, but you can add sub-applications. e.g. /foo on the scm endpoint can be an unrelated app. The advantage of running under the scm endpoint is that it is protected by authentication, making it a great place to run admin tools of all kind.
- Adding new applications (and vdirs) to the main site. Note that there is a simpler way to do this via the Azure Portal, so using Site Extensions this way is less common.
- Arbitrary other changes: e.g. tweak the
Pre-Installed Site Extensions
All pre-installed Site Extensions are under
d:\Program Files (x86) SiteExtensions Kudu extension.xml 1.24.12345 scmApplicationHost.xdt kudu bits... 1.24.34567-preview scmApplicationHost.xdt kudu bits...
Note: you should use either
- If only transforming the scm site, use
- If transforming the runtime site (or both, which is very rare), use
extension.xml has the following format:
<extension> <version>latest|beta|1.2.3456|disabled</version> </extension>
version can take the following values:
latest: all sites get the latest non-prerelease version of the Extension. This is the default in case there is no
extension.xml(which is why Kudu doesn't have this file)
beta: all sites get the latest prerelease version of the Extension
disabled: sites don't get the extension at all
- Exact version: e.g. 1.2.3456. Sites get this exact version of the Extension. If it does not exist, they get the latest non-prerelease version.
- Tilde version: ~2 maps to the latest 2.x non-prerelease if any. Failing that, use the latest 2.x prerelease. If no 2.x exists at all, it will use the latest overall non-prerelease.
Each site can override the version by specifying
<extension>_EXTENSION_VERSION in the AppSettings (e.g. from the Azure Portal). e.g. for Kudu you could set
KUDU_EXTENSION_VERSION=beta to make the site get pre-release versions (if any are available).
Note that if newer Pre-Installed versions become available later, all sites will get them if it matches their
version selection. However, as site restart is necessary for the site to get the newer version.
Pre-Installed Site Extensions Package
To become pre-installed site extension, partners must first contact the Kudu team. In order for us to add or update the Windows Azure pre-installed site extension, we will need a single zip package. The zip filename should be in
<extension>.<semver>.zip format (for example,
Monaco.1.0.0-20130906.zip). The layout in the zip file should also be consistent with the zip file name. For instance,
Kudu.1.25.21217.582.zip layout should be
extension.xml /1.25.21217.582 scmApplicationHost.xdt kudu bits...
Monaco.1.0.0-20130906.zip layout should be
extension.xml /1.0.0-20130906 scmApplicationHost.xdt Monaco bits...
After installation on Windows Azure, it will be lay out (unzip) exactly to
Important: please make sure you automate the building of the zip as part of your build. When this is done manually, there tends to be issues and inconsistencies from build to build.
The site owner can overwrite the existing site extensions with their own implementations or introduce a totally new set of site extensions altogether.
Important note: Site Extensions only get applied after the site is restarted. However, if you modify existing extensions without changing the applicationHost.xdt, no manual restart is needed.
Also, note that the Restart button on the Site Extension Kudu tab only restarts the scm site (by just killing the process). If your xdt effects the Main site, you will need to either kill the non-Scm
w3wp.exe in Kudu's Process Explorer, or fully restart the site from the Azure Portal.
There are two flavors of Private site extensions: 'named' and 'top level'.
Named private extensions
These work the same way as the 'pre-installed' extensions discussed above, except they're brought in by the site owner.
Here is a complete Site Extension sample.
All you need to do is upload the extension bits into a
SiteExtensions folder. Below examples illustrate overriding the Kudu extension as well as introducing a new Foo extension. Note that unlike pre-installed extensions, these are not in versioned folders.
/site /LogFiles /SiteExtensions /Kudu applicationHost.xdt kudu bits... /Foo applicationHost.xdt foo bits...
Top level private extension
There can be only one such extension for a given site, and it consists of a single
applicationHost.xdt file living in the
site folder. It is typically used to make general tweaks to your site's
/site applicationHost.xdt /wwwroot /LogFiles
Authoring XDT transforms
There is an awesome site extension written by shibayan that makes it super easy to auther correct xdt's. It's called IISManager, and you can install it using Kudu or the (new) Azure Portal. It let's you edit
applicationhost.config, and automatically generates the xdt for you.
Please check out XDT Transform Samples for a set of examples of what you can do with XDT files.
There are a set of environment variables passed to the XDT to assist in locating the appropriate elements and set the proper property.
XDT_SITENAMEis the current site name
XDT_SCMSITENAMEis the current scm site name
XDT_EXTENSIONPATHis the version specific extension physical path
HOMEis the site root path
Site Extension Gallery
Site extensions can be shared with others using the Site Extensions gallery. See this post for more information.
Updating for site extensions
You can add the ability for your site extensions to auto-update when you publish a new version. See here for more details.
Install/Uninstall scripts for gallery extensions
An extension installed from the gallery can contain install/uninstall scripts. To use this, simply include an install.cmd and/or uninstall.cmd at the root of your extension. You can find an example here (taken from the Image Compressor extension).
Understanding what could go wrong with xdt transforms
There are several categories of issues that could cause things to not work, and it's very important to understand this difference in order to be successful with XDTs.
If your applicationhost.xdt is not valid, the XDT transform operation will fail. This could happen if you have malformed XML, or if you are incorrectly using XDT concepts like
When that happens, you will see an error in the XDT log (see debugging section below).
Valid XDT that doesn't do what you want it to
Here, your XDT file is valid, but it does not modify your applicationhost.config in the way that you expect. The XDT syntax can be tricky, and it can take a few tries to get it right (looking at samples often helps!)
To diagnose this kind of issues, look at the generated applicationhost.config (see debugging section below), and see if it has what you expect.
Transform does what you expect, but applicationhost.config semantic is not what you expect
Here, the transform does exactly what you ask it to, and therefore the generated applicationhost.config looks exactly the way you intended.
However, that applicationhost.config does not work as you expect, possibly due to misunderstanding of the applicationhost.config schema or semantic.
It's important to note that these issues have nothing to do with XDT transforms. They are pure applicationhost.config issues, much like you'd see on your local IIS.
Debugging private Extensions
Finding your applicationhost.config
Before trying to apply any transform, you may want to see what the applicationhost.config looks like. Likewise, after applying a transform, you'll want to look at applicationhost.config to make sure it looks ok.
Here is one way to do it (we should try to make this easier in the future):
- Go to the Kudu Console
- Click the 'planet' icon
- Click the Config folder
- Click the download button for
applicationhost.config. Or you can click the Edit button to look at it directly in the browser (but don't attempt to modify it from here, as it's read only!)
Finding the log of what happened during the transform
If you look under
D:\home\LogFiles\Transform you should see a log that gives info about what happened during the transforms. This can be very useful when errors happen.
Disabling the private extension transform
If you run into problems and hose your site, all you have to do is set
WEBSITE_PRIVATE_EXTENSIONS=0 in the site AppSettings, and none of your XDT will be applied. After disabling it, you can still look at the previous 'bad'
applicationhost.config. You will find it at the root on the %TMP% folder (from the Kudu Console).
Running transforms locally
This is the XDT transformation package used by Azure App Service: https://www.nuget.org/packages/Microsoft.Web.Xdt/1.4.0. You should be able to use it locally to test transform operations outside of App Service.