Visiting an Azure Website while Publishing displays IIS Errors - azure

I have an MVC app hosted on an Azure Website.
I have custom errors enabled and working (when not publishing):
<customErrors mode="On" defaultRedirect="~/Error/NotFound" xdt:Transform="Replace">
<error redirect="~/Error/NotFound" statusCode="404" />
<error redirect="~/Error/NotFound" statusCode="403" />
</customErrors>
When I publish the website from Visual Studio, if I try to visit the site while the dlls are being updated, I get a nasty IIS error.
I'm surprised that Azure doesn't wait to "tie down" the new version until the publication is complete, to avoid this scenario. Is there a way to achieve this "instantaneous switch" behavior?
And/Or - How can I prevent this error from being displayed?

I can't say this would be unusual. Depending on size of the deployment it may take a while for IIS to restart and reload leading to 503 Service Unavailable or similar errors in the meantime. CustomErrors won't help you here as the ASP.Net pipeline isn't even being reached at this point. What Azure Website level are you running on (Free, Shared or Standard?) If you can up the size of the instance to try and get things moving again more quickly.

I think you deployment is too slow. IIS detects changes in dll files and restart the app-pool automatically without waiting for the other dll files.
Try to set custom values in waitChangeNotification and maxWaitChangeNotification in web.config. Doing so you can ask IIS to wait for some seconds before restarting app-pool. I'm not sure if it works on Azure. On my on-premises IIS I use custom values that allow me to do a long deploy (about 5 seconds).
Documentation: http://msdn.microsoft.com/en-us/library/e1f13641(v=vs.85).aspx

Related

IIS rewrite rules in a separate file to web.config needs to restart IIS itself to pick up changes

I have an ASP.NET WebForms website which has a few Web.Config files for dev/UAT/production (the appropriate web.config is deployed to the relevant environment) - all of which reference a shared rewrite rule file - so that the rewrite rules themselves don't have to get duplicated into each web.config. This works great
<rewrite>
<rules configSource="WebConfigRewrites.Config" />
</rewrite>
However, if I add a new rewrite rule to this file, then the rule doesn't take effect until I restart IIS. If I recycle the application pool, or restart the website in IIS the new rule doesn't work (e.g. a rewrite URL will throw a 404 until I restart IIS)
Is there any way around this? If I bring in the rules into the web.config then recycling the apppool, or even updating the web.config will cause these new rules to work - but at the cost of having to duplicate all the rules across several files.
Having to restart IIS itself is really rubbish, as it causes the site to instantly respond with a "service unavailable" 503 error.
Is there any other way around this?
Server is Windows Server 2016, IIS 10.0.14393
As the discussion under comments is lengthy, post a summary here to avoid confusion.
Usually your edits in URL rewrite rule section in web.config takes effect immediately, as IIS monitors <system.webServer> actively in web.config files.
But, when you moved the rules to an external file via configSource, you observed that changes to those rules are no longer picked up by IIS immediately. That seems to indicate IIS does not monitor such external files actively. If you want to confirm that's by design or not, the only way is to contact Microsoft support via https://support.microsoft.com.
The workaround is also easy that you "touch" the monitored files like web.config, so that manually trigger configuration refresh.
Normally we do not need to restart IIS after changing web.config.
Changes web.config will trigger the app to be reloaded by IIS as soon as there are 0 connections left to the app. You can stop and restart the app pool. Recycling app pool is not recommended and you should stop/start the respective app pool where you update.
Have you tried stopping the site first and then restarting it? 404 error means that IIS has detected that web.config has been updated. You can also generate logs to view details.

Azure Web App swap happening BEFORE warmup

Since about a week when I publish a new version of our Web App and do a Swap from Staging to Production, it actually seems to swap before the warmup initialization is done.
As it is a large application it will takes more then five minutes to warmup the site, making the application unresponsive.
I have official Azure support, but it is taking a long time to respond to this request and I still have no answer that works.
I can't fix any issues on our platform or publish a new version without bringing the whole site down for eight minutes. This is a highly visited website, with paying clients.
Does anyone know:
anything that I could investigate myself?
a workaround or any tips that I can take a look at myself to try to fix or work around this issue?
Extra information
I do use applicationInitialization, and I see that Azure is hitting the pages - it just happens after the swap instead of before.
<system.webServer>
<applicationInitialization>
<add initializationPage="/nl" hostName="mydomain.com" />
<add initializationPage="/warmup-application-for-azure" hostName="mydomain.com" /> (special page just for warming up services)
<add initializationPage="/deeplink1" hostName="mydomain.com" />
<add initializationPage="/deeplink2" hostName="mydomain.com" />
[etc]
</applicationInitialization>
</system.webServer>
Maybe not 100% relative to this question but since I had similar issue with warm up I want to share how I solved it.
I used to have issue with auto-scaling because my nodes were not warmed up due to url rewrite module. So what if you have url rewrites in your app make sure that you are checking for
<add input="{WARMUP_REQUEST}" pattern="1" negate="true" />
Now this is in official documentation and it has link to common problems
This was an Azure bug, confirmed by the Microsoft Azure team.
Sometimes hitting the site’s root URL is not enough to completely warm up the application. For example it maybe necessary to hit all important routes in an ASP.NET MVC app or to pre-populate the in-memory cache. That is where the Application Initialization Module can help.
When you use the warmup-functionality provided by IIS (and Azure) instead of those old-fashioned methods and if deploying to an App Service, just add a slot setting to make sure it always triggers such as below:
This tutorial explains how you can use the recently enabled Application Initialization Module to completely warm up your application prior to swapping it into production.
So here is the important thing you should consider:
Unless you specify which url address azure needs to request to your website, how can it knows. If you don't do that, it only calls the root of the application
Even if you specify the url and your url needs to authorisation/authentication, how can azure sign in your website automatically and call the url that you specify.
You have got two option to deal with it.
1) Write your own warming up api to call your web application with authorisation/authentication. Then create a scheduler to call the application every hour or half an hour. It also allows you to keep the entire application up & running & warm. You can also set AlwaysOn feature under the Application Settings. You can also trigger this api on your CI/CD pipeline after the staging slot deployed successfully.
2) If you don't want to touch your CI/CD pipeline or whatever reason and don't want to write api, you should sign in to your web application, go through each page and warm it up manually. Then you can swap without any problem.

Windows Azure and Unity3d

Been interested in Unity3d for certain projects for some time now, and decided to bite the bullet! I started toying around, and fancied the idea of running Unity3d in windows azure.
However, despite my efforts, I was unable to get this running!
Here is what I have tried so far:
Including the Deployment Output from unity directly with my deployment to azure. While it is probably to keep the unity3d file in blob storage in azure, this was just for testing purposes.
I have included the mime type to allow iis to use the unity file (via the web.config):
Code:
<staticContent>
<mimeMap fileExtension=".unity3d" mimeType="application/vnd.unity"/>
</staticContent>
Lastly, I have included the UnityWebPlayer.exe file, and added a Startup task to install the UnityWebPlayer on the server. Also here another best practice would be to download the file instead, as it would be the latest version, but again, only for testing at the moment . My service definition of the start up is below:
Code:
<Startup>
<Task commandLine="UnityWebPlayer.exe /S" executionContext="elevated" taskType="simple" />
</Startup>
I am curious to reach out to the community to see if anyone else has had any success getting their games to the cloud with windows azure?
EDIT:
I should add then when trying to deploy such a web role, the role is stuck cycling and never deploys. Thanks!
I figured it out!
A shout out to smarx for pointing out that you DO NOT need to install the UnityWebPlayer on the server.
As to get the unity file to load correctly, you do have to add the mime type to IIS, it is as above, except without the "."!
Silly me.
Enjoy!

Disable Compression in Windows Azure Preview

This might sound like a strange request, but I need to test something and need the ability to disable compression on a Windows Azure website. The site is running as a website in preview mode and this means I am not able to log into the VM to adjust the IIS settings.
I updated the web.config file accordingly, but this didn't make a difference.
<system.webServer>
<urlCompression doStaticCompression="false" doDynamicCompression="false"/>
</system.webServer>
Compression is still enabled and it seems that it is enabled by default. There are a lot of questions on SO about enabling compression, but I cant seem to find any about disabling compression!
Does anyone have any advice!?
Not every setting in web.config is delegable when deploying your web application to Windows Azure Websites. Some of the settings in web.config are delegable and they reflect in your websites while other settings are respectfully ignored and disabling compression is one of them and that is why you see the above results. Using same exact web.config setting or using Appcmd, you sure can disable compression only if you have enough control on your IIS server. So far if this feature is must important for you, your other options are to use Windows Azure Cloud Service and deploy a Web Role or use Windows Azure Virtual Machines as well.
I am sure that disabling compression feature in Windows Azure Websites is still not delegable and that's why it is not supported in current preview release of Windows Azure Websites. I can say that it sure is a feature in consideration to include in later releases however, about it's availability when or if possible, i do not have any comment.
I know that this question has been posted since a long time ago, at this date I was able to turn off http compression by setting it up in IIS.
the same way as #Deano suggested
<system.webServer>
<urlCompression doStaticCompression="false" doDynamicCompression="false"/>
</system.webServer>

Most Strange IIS Windows Authentication behavior

I have an ASP.NET website running on Windows Server R2 in a corporate network, using Windows Authentication.
The app pool of the website is using a domain account and in Integrated pipeline mode.
The authentication is set Windows Authentication, all other authentication modes are disabled.
However, this does not work. Every time I access the website, it pops up a dialog asking for user name and password. I enter the correctly domain user name and password, but it does not continue--the windows pops up again. After three times, it fails and displays a white page. I tried with many different browsers, bu all of them fail. I asked some colleagues to try and they all got failure, too.
I cannot figure out why this error is happening and tried many ways to fix it with no luck. I think it is very strange. However, finally I found a way to fix this problem, this is the most strange part of the problem: I edit the "Physical path" in "Basic Settings" of the website, I just point it to another healthy website, for instance, %SystemDrive%\inetpub\wwwroot, then I try to browse the website, very good, it runs well and displays the default page (iisstart.htm). It looks like it is not very helpful, but then I change the physical path back to my website; suddenly everything goes well -- the windows authentication works! I do not know why it helps, but I am happy with this result -- it fixes my problem though I do not know what the heck is happening.
The happy time is always short, several days later, the server got some patches and restarted, the website can't work again. And again, I can fix the problem using the trick above.
I do not like this! I do not like doing this stupid trick every time IIS resets or the server restarts.
Is there anyone who has some ideas on why windows authentication fails, and why the aforementioned trick can fix it, and why after an IIS reset it fails again?
First off, THANK YOU for creating this post. I have the exact same issue and could not find anyone else without posting the obvious fixes that were of no avail to me. I had been working on this for almost two weeks
To assist the next poor soul that encounters this issue and post, I hope my extra tidbits help.
Your initial solution did not fix my issue in my case, but it did prove that it was custom error page related. After pasting in your code into web.config my problem got worse and I was not able to debug or launch the page (had 500 internal server error related to web.config)
BUT finally what I did was go into the IIS Console and remove all of my custom error pages. It still did not work as had hoped. BUT, I also found entries for ASP.NET ".NET Custom Errors" in the top half of the site console (and the "custom errors" tag in web.config). I had old entries in there and removed them via console, and YESSSS, my site came back to normal with Windows Authentication.
I have since recreated the IIS Custom Errors and I am still up and running as designed.
SO to anyone else that may have this issue, check both ASP.NET Custom Errors AND IIS Custom Errors settings. Maybe there is a conflict, I dont know, but in my case having only the IIS pages set fixed me up (for now :-) )
I just found it seems caused by custome 401 error pages under "Error Pages". I set it to execute an URL when the status code is 401 in my web.config, it looks like:
<httpErrors errorMode="Custom">
<remove statusCode="401" subStatusCode="-1"/>
<error statusCode="401" path="/Error/AccessDenied" responseMode="ExecuteURL"/>
</httpErrors>
Then every time I reset IIS and try to access this website, the problem appears. If I delete it in Web.Config or delete from IIS console, then the problem disappears, what is more funny is another experiment: after I deleted this settings and have been successful opening the website, I added this setting back. Everything works very well. Every domain user can access this website, those that failed passing authorization get the customer error page.
So my solution now is I removed this setting in my Web.Config, every time I reset IIS or restart the server, the server admin need to hit the website first, and then add this customer error page in IIS console.
I feel this is a bug of II7.5 on Windows Server 2008 R2.
I was also struggling with this same issue all my day. I am using windows authentication and Custom error setting in web.config for 401 errors.
After I reset the IIS, the website stop accepting domain users and windows authentication pop up reappear again and again.
I added remove tag in the web.config file with Sub status code.
<httpErrors>
<remove statusCode="401" subStatusCode="-1" />
<remove statusCode="401" subStatusCode="1" />
<error statusCode="401" subStatusCode="-1" path="/Custom401.aspx" responseMode="ExecuteURL" />
<error statusCode="401" subStatusCode="1" path="/Custom401_1.aspx" responseMode="ExecuteURL" />
</httpErrors>
Previously remove tag was only present for substatus code -1 but missing for sub status code "1" . After i added it, everything started woking properly.
In the above post, substatus code is missing for error tag, that could be the cause of the problem. There should be remove tag for all 401 errors there.
I just spent a couple of hours digging up a solution to this problem.
Why IE fails yet the other browsers succeed: IE tries to use Kerberos authentication and the other browsers don't try. The others use NTLM.
Solution: In the situation described in the question, a domain account was being used in the App Pool. Simple solution: switch to using the "Network Service" account. More complex solution: You have to register a service principal name (SPN). Read this article (ignore the fact that it is talking about IIS 6 because it also works fine on IIS 7 and 7.5) - You receive an "HTTP Error 401.1 - Unauthorized: Access is denied due to invalid credentials" error message when you try to access a Web site.
I hope this helps. It gave me a headache until I stumbled upon that article. (Thanks to Paul Lynch who posted the link Windows Authentication Failing in IE8 but not Firefox)
I had this same problem on my Windows 2008 R2 server. I did not have custom 401 error pages. I did use aliased server names (via DNS CNAME records and host header entries on the IIS bindings). I registered the SPNs for Kerberos as suggested, but that did not solve the problem. I resolved it by disabling "Kernel Mode Authentication" (click on the server in the IIS tree -> double-click on Authentication under the IIS group -> click on Windows Authentication -> click on Advanced Settings on the Actions pane -> Uncheck the checkbox -> click OK -> run iisreset). The information on that dialog box recommends against disabling Kernel Mode Authentication when using non-standard service accounts for the application pool identity, but that didn't apply to us since we're using the standard ApplicationPoolIdentity identity.
I had the same issue.. Turnes out I should not have messed with my hostfile.. I changed my hostfile and pointed some fancy address to my machine like so:
www.givemeyourcredentials.com 127.0.0.1
I added a binding to the site "www.givemeyourcredentials.com". I typed in the addres in my addressbar and the site prompted my credentials as expected.. Typed in my credentials and got prompted for my credentials again.. And again and again and again..
Turns out: Bind your website to http://localhost when using windows authentication in an IIS site. That did the trick for me.
Hope this helps somebody...
Add "NT Service\trustedInstaller" to physical folder of the site. Location for this user is local machine name.
The NTLM protocol that is used for Integrated Windows authentication requires a two-step process to authenticate clients. The behavior that is mentioned in the "Symptoms" section occurs when the following conditions are true:
The application pool recycles after the first step of the Integrated Windows authentication process.
However, the application pool recycles before the second step of the Integrated Windows authentication process.
To work around this behavior and to reduce the frequency of these error messages, configure the application pool to recycle less frequently. To configure application pool recycling, follow these steps:
Click Start, click Run, type inetmgr, and then click OK.
Expand the name of the computer on which you want to configure application pool recycling, and then expand Application Pools.
Right-click the application pool that you want to configure, and then click Properties.
On the Recycle tab, configure one of the metrics so that IIS recycles less frequently.
Note IIS 6 application pools support several metrics. These metrics include the time elapsed, the number of requests, and the specified time to recycle an application pool. If an application pool has a metric that causes the application pool to recycle frequently, you will experience this issue more frequently.
Click OK.
[ Copied from https://support.microsoft.com/en-us/kb/902160 for posterity ]

Resources