Azure Websites: "Home" on C or D drive? - azure

I have created a new a new Azure Website (Code deployment) and noticed via the Kudu site, that the the files are now on C:\ instead of D:\, e.g. this is from the Kudu site:
Site folder: C:\home
Temp folder: C:\local\Temp\
A week ago I thought that all my stuff was located on D:\home etc.
I asked this, because we deploy a WebJob via the Zip-Deployment option and need to set an absolute path to our config file, which is now on the "wrong" drive.
Also the Kudu-documentation uses D: for all values.
Has this changed recently? It's not a major problem, but I want to understand why.

Even if the Kudu console takes you to C:\home, D:\home is still accessible and points to the same place but I recommend you to always use the environment variable %HOME% and avoid using absolute paths.
For example, if you plan to use Windows Containers on App Service in the feature, the %HOME% env var also points to C:\home
Additionally, if you use App Service on Azure Stack for example, the %HOME% env var will also point to C:\home

Related

Is is possible to browse an Azure App Service temp directory?

I am using the Kudu Dashboard to browse the folder of my Azure App Service. Specifically, I am browsing the D:\local\Temp\ since that is supposed to be (as far as I understand) the folder used to store temporary files created by my web app. For reference, here is a screenshot of the Kudu dashboard:
You can see from the screenshot that there is a file called xyz.tmp, this file is a file that I created manually trough the Kudu dashboard.
All this is good, however, when I try to read the file from my web app by using code such as:
var fileContent = System.IO.File.ReadAllText(#"D:\local\Temp\xyz.tmp");
I get an error stating that the file can't be found.
So my question is, what is going on? Why do I get the error? Also, I noticed that when I create a file in the same App Service temp director using code such as:
var fn = System.IO.Path.GetTempFileName();
System.IO.File.WriteAllText(fn, "abc123");
and then I try browsing for the file using the Kudo dashboard I don't see it in the temp directory.
So essentially, it all seems to point to the temp folder being displayed by the Kudo dashboard not representing the real temp folder used by the App Service. So if that is not the case then how exactly are you supposed to be able to browser the App Service temp folder?
Thanks.
From https://github.com/projectkudu/kudu/wiki/Understanding-the-Azure-App-Service-file-system:
Another important note is that the Main site and the scm site do not share temp files. So if you write some files there from your site, you will not see them from Kudu Console (and vice versa). You can make them use the same temp space if you disable separation (via WEBSITE_DISABLE_SCM_SEPARATION). But note that this is a legacy flag, and its use is not recommended/supported.

What files are relevant to Azure Web App?

I'm deploying files to an Azure Web App via Octopus Deploy, and want to clean out the Azure Web App directories before deploying new versions. This way I can be sure I'm deploying each app version onto a clean slate. I don't want to entirely delete and re-create the app, because there are some app settings that need to carry over from previous deployments.
Kudu documentation lists the web app file structure here (all under D:\home), but I'm wondering if there's any possibility of other files outside of the D:\home directory that could affect app performance.
I tried running get-childItem D:\ -recursive in the kudu powershell console before and after deployment to compare results and found 268 new files (not counting those in wwwroot) after deployment, all within these directories:
D:\Windows\Temp
D:\Windows\Logs
D:\Windows\security\logs
D:\Users\\AppData\Roaming\Microsoft\SystemCertificates
D:\home\LogFiles
D:\home\Microsoft\Windows\PowerShell
D:\home\data\aspnet\CompilationSnapshots
D:\local\VirtualDirectory0\LogFiles
D:\local\VirtualDirectory0\data
D:\local\VirtualDirectory0\site\wwwroot
D:\local\VirtualDirectory0\Microsoft\Windows\PowerShell
D:\local\Config\
D:\local\Temporary ASP.NET Files\msdeploy
So which files do I need to clear or reset in order to ensure that new versions of the web app run as intended? Is it sufficient to clear out the wwwroot directory?
The only writable folders are d:\home and d:\local. But d:\local is temporary, and gets wiped clean on app restart. So effectively, you should only be concerned about d:\home when it comes to deployment.
Within that, wwwroot is typically the most important, though if you set up virtual directories and applications, you can end up with other folders as part of your app.
See also https://github.com/projectkudu/kudu/wiki/Understanding-the-Azure-App-Service-file-system which has related info.

Web Deploy Set Parameter using external file

We have an Website project that's hosted in Azure, and we use Web.config transforms for setting environment variables. However, our current approach for building the system for different environments is to build the project multiple times (currently this is 3), which is inefficient.
We'd like to move to using Web Deploy, as this would then set us up nicely for using Release Manager.
Our issue is around using Web Deploy parameters instead of web.config transforms; we need to substitute multiple xml elements, rather than single values.
After much research, I found these 2 articles which detail almost exactly what I'm trying to do
http://blogs.iis.net/elliotth/web-deploy-xml-file-parameterization
http://www.iis.net/learn/publish/using-web-deploy/parameterization-improvements-in-web-deploy-v3
Essentially I'm trying to replicate Scenario 5, but using a separate Set Parameter file for the value.
Unfortunately, in the examples, referencing an external xml file only works if it is on the target machine. Some testing with a colleague confirmed this; works on local machine, but not on Azure.
Is there a way I can force Web Deploy to look in a particular location for the external configuration files?
As you've already noticed, Web Deploy is only able to read replacement values on the local machine or on a UNC share. It can't read that specific file over HTTP.
If you're deploying to an Azure Web App, then one thing you could try would be to use Kudu/FTP to manually upload that file one level above your wwwroot folder. Then you could specify the file location like so:
D:\home\site\prices.xml:://book[#name='book1']/price
Of course this implies that you'd have to pre-upload this file before publishing to your site, so it's not a perfect solution, but it should work for what you're trying to accomplish.

access certain folder in azure cloud service

In my code (which has worker role) I need to specify a path to a directory (third party library requires it). Locally I've included folder into project and just give full path to it. However after deployment of course I need a new path. How do I confirm that whole folder has been deployed and how do I determine a new path to it?
Edit:
I added folder to the role node in visual studio and accessed it like this: Path.Combine(Environment.GetEnvironmentVariable("RoleRoot"), "my_folder");
Will this directory be used for reading and writing? If yes, you should use a LocalStorage resource. https://azure.microsoft.com/en-us/documentation/articles/cloud-services-configure-local-storage-resources/ shows how to use this.
If the directory is only for reading (ie. you have binaries or config files there), then you can use the %RoleRoot% environment variable to identify the path where your package was deployed to, then just append whatever folder you refernced in your project (ie. %RoleRoot%\Myfiles).
I'd take a slightly different approach. Place the 3rd party package into Windows Azure blob storage, then during role startup, you can download/extract it and place the files into the available Local storage (giving it whatever permissions the app needs). Then leverage that location from your application via the same local storage configuration entry.
This should help you reduce the size of your deployment package as well as give you the ability to update the 3rd party components without completely redeploying your solution. And by leveraging it on startup, you can guarantee that the files will be there in case the role instance gets torn down and rebuilt.

IIS Config file in virtual directory

I have multiple websites that all have the same code, but different app settings.
I want to place my app settings in a separate configuration file that is located in a virtual directory. This will allow me to have a single copy of all of the code shared across all of the sites with a different virtual directory for each site.
Unfortunately, when I try to configure this, IIS doesn't process the config file when it is in a virtual directory.
If you have a solution to this, I would appreciate your help.
Maybe using the machine.config file on your web server would be a suitable alternative? Otherwise you could create a web.config file in a global folder somewhere and open it using the WebConfigurationManager.OpenMappedWebConfiguration() method.
It's not possible to use a virtual directory (or even files outside of the current website; only the current folder, or a sub-folder).
One possible way to share setting across projects would be to do it at build-time - either by coping it in, or using a Linked File in VS to have it copied to the folder on publish.
If you really need this functionality on the server, you could try (though I can't say how well it would work) a Junction.

Resources