MSdeploy deploys an MVC 2 application with wrong virtual directory name - iis

I'm using MSbuild(v4.0.30319.1) and MSdeploy(v7.1.618.0) to deploy my ASP MVC 2 application on IIS(v7.5).
Here are the commands I run to do it:
msbuild.exe <path to my csproj>/MyMvcApp.csproj /t:Package /p:configuration=release;outDir=<my output dir>
and msdeploy:
msdeploy.exe -verb:sync -source:package='<MSBuildOutputDir>\_PublishedWebsites\Webui_Package\MyMVCApp.zip' -dest:auto
After build and deploy the application is deployed by address http://localhost/MyMVCApp_deploy and not by address http://localhost/MyMVCApp.
I did not expect that the _deploy will be in the address.
How can I fix this?

As Portalus commented you can control the name of the app in the properties page. I'll expand a bit on that answer here.
Configure the default value on PP/Web tab
By default when you package/publish your web project we will create an Web Deploy parameter named IIS Web Application Name which controls this value. The default value for this is
ProjectName_deploy. The reason why we put the _deploy suffix there is for IIS scenarios. So you may already have an IIS app with the name of ProjectName but its much less likely that you will have one named ProjectName_deploy. You can customize this value on the Package/Publish Web tab of the project properties. One thing to keep in mind if you go this route is that all of these settings are tied to a specif build configuration. So if you configure the settings on Debug and the create your package using Release those settings will not apply. See image below.
When you set this value it sets the MSBuild property, DeployIisAppPath, and you can use that if you want to have some logic relating to the value it gets.
Pass the parameter value on publish
If you want you can also just specify the value of this parameter when you are publishing. You have two primary approaches here.
Specify the value for the individual property
Specify the value for this and other properties in a file
1. Specify the value for the individual property:
You can use the -setParam parameter when calling msdeploy.exe to give a new value for that parameter. For example:
%msdeploy% -verb:sync -source:package=WebApplication3.zip -dest:auto -setParam:name="IIS Web Application Name",value="Default Web Site/FooBar"
2. Specify the value for this and other properties in a file
When you create a package in VS we automatically create for you a file named {ProjectName}.SetParameters.xml. This file is a simple XML file and it will contain all the parameters, along with their default values. You can update that file to include the correct parameter values and then pass it into msdeploy.exe (note: the file doesn't have to be named ...SetParameters.xml you can rename it to whatever you want). If you want to use this approach then just use the -setParamFile parameter when calling msdeploy.exe. Here is an example of the command line syntax for this:
%msdeploy% -verb:sync -source:package=WebApplication3.zip -dest:auto -setParamFile=WebApplication3.SetParameters.xml

Change the application name in the settings.
Right click the web project hit properties. Go to package/publish web, change the application name to use on the destiantion server from "default web site/mymvcapp_deploy" to "default website/mymvcapp"

Related

Why does triggering Azure Function from Logic Apps return "Bad Request"

My Azure Function works well if run from the browser
https://examplefunction.azurewebsites.net/api/HttpTrigger-Java?name=testEUR.txt&code=mycode
I configured the function to run as a stage in "Logic Apps" - hard-coding the "name" parameter for testing purposes
But then I get "Bad Request" when running the function via logic apps
This can be solved by adding "authlevel":"anonymous" to function.json which is in under site/wwwroot/examplefunction
Instructions to set the authentication level are as follows
select Platform features. Under Development tools, select Advanced tools (Kudu).
On the Kudu website's title bar, from the Debug Console menu, select CMD.
After the next page appears, from the folder list, select site > wwwroot > examplefunction.
Open the function.json file for editing.
In the bindings object, check whether the authLevel property exists. If the property exists, set the property value to anonymous. Otherwise, add that property and set the value.
Once this has been done, then in the Request body of the logic app, just putting "testEUR.txt" works
Obviously, a better answer would be one that does not seem to apparently disable authentication.

AzureWebJobsScriptRoot variable is not defined on Azure Functions, but returns correct value locally

AzureWebJobsScriptRoot variable is not defined on Azure Functions. The code below returns no value.
System.Environment.GetEnvironmentVariables(EnvironmentVariableTarget.Process)["AzureWebJobsScriptRoot"];
However, %HOME%\site\wwwroot will be returned based on below:
AzureWebJobsScriptRoot
AzureWebJobsScriptRoot
The path to the root directory where the host.json file and function folders are located. In a function app, the default is %HOME%\site\wwwroot.
Key Sample value
AzureWebJobsScriptRoot %HOME%\site\wwwroot
It returns correct value locally, not %HOME%\site\wwwroot
Update
Is this a bug with Azure Functions?
If so, what is an alternative solution?
Before the issue is fixed by Microsoft, can this variable, AzureWebJobsScriptRoot, be defined myself to "%HOME%\site\wwwroot" on Azure?
https://github.com/Azure/Azure-Functions/issues/1146
https://github.com/MicrosoftDocs/azure-docs/issues/26761
I test in my site and get the same problem with you. As the article said, when running in Azure, will default to %HOME%\site\wwwroot and it set the function folder under home\site\wwwroot.
However, when I set AzureWebJobsScriptRoot in Azure funtion Application Settings, it will show in the output like below:
If you configure a function app with a different value for AzureWebJobsScriptRoot, then the functions host should honor that new value. For example, if you set AzureWebJobsScriptRoot = D:\home\site\wwwroot\foo then the functions host would look for a host.json file and function directories in the D:\home\site\wwwroot\foo location.
By default, this environment variable is not set. So it is expected that if you did not set it yourself, then System.Environment.GetEnvironmentVariable("AzureWebJobsScriptRoot") will return null.
Be aware that if you modify this setting, other components like the portal, visual studio, visual studio code, etc will not be aware of setting and will deploy your code to the normal default location. If you want to customize this setting, its up to you to make sure the application code is deployed to the right location.
Please refer the full details here

Substitute Service Fabric application parameters during deployment

I'm setting up my production environment and would like to secure my environment-related variables.
For the moment, every environment has its own application parameters file, which works well, but I don't want every dev in my team knowing the production connection strings and other sensitive stuffs that could appear in there.
So I'm looking for every possibility available.
I've seen that in Azure DevOps, which I'm using at the moment for my CI/CD, there is some possible variable substitution (xml transformation). Is it usable in a SF project?
I've seen in another project something similar through Octopus.
Are there any other tools that would help me manage my variables by environment safely (and easily)?
Can I do that with my KeyVault eventually?
Any recommendations?
Thanks
EDIT: an example of how I'd like to manage those values; this is a screenshot from octopus :
so something similar to this that separates and injects the values is what I'm looking for.
You can do XML transformation to the ApplicationParameter file to update the values in there before you deploy it.
The other option is use Powershell to update the application and pass the parameters as argument to the script.
The Start-ServiceFabricApplicationUpgrade command accept as parameter a hashtable with the parameters, technically, the builtin task in VSTS\DevOps transform the application parameters in a hashtable, the script would be something like this:
#Get the existing parameters
$app = Get-ServiceFabricApplication -ApplicationName "fabric:/AzureFilesVolumePlugin"
#Create a temp hashtable and populate with existing values
$parameters = #{ }
$app.ApplicationParameters | ForEach-Object { $parameters.Add($_.Name, $_.Value) }
#Replace the desired parameters
$parameters["test"] = "123test" #Here you would replace with your variable, like $env:username
#Upgrade the application
Start-ServiceFabricApplicationUpgrade -ApplicationName "fabric:/AzureFilesVolumePlugin" -ApplicationParameter $parameters -ApplicationTypeVersion "6.4.617.9590" -UnmonitoredAuto
Keep in mind that the existing VSTS Task also has other operations, like copy the package to SF and register the application version in the image store, you will need to replicate it. You can copy the full script from Deploy-FabricApplication.ps1 file in the service fabric project and replace it with your changes. The other approach is get the source for the VSTS Task here and add your changes.
If you are planning to use KeyVault, I would recommend the application access the values direct on KeyVault instead of passing it to SF, this way, you can change the values in KeyVault without redeploying the application. In the deployment, you would only pass the KeyVault credentials\configuration.

APPCMD how to test if binding exists before I add it to a website?

We use appcmd in our deployment scripts to setup servers , I need to ensure that adding bindings to existing sites doesn't throw an error
C:\Windows\System32\inetsrv\appcmd.exe set site /site.name:"abc.com"
/+bindings. [protocol='http',bindingInformation='*:80:alias-abc.com']
works but in the next script run I get the error ..
cannot add duplicate collection entry of type 'binding' with combined key attribuites 'protocol, bindingInformation' respectively set to '
http, *:alias-abc.com'
Is there a way I can check if the binding exists before adding it in appcmd
(powershell is not allowed - so has to be either appcmd or other command line exe)
Thanks
appcmd is a bit lacking in the search department, but something like this should work:
C:\Windows\system32\inetsrv\appcmd.exe list site "abc.com" | findstr bindings:http/*:80

Associate an application pool to site with appcmd

I want create a site by command line using appcmd.
How can I associate a specific application pool to site?
To create a site, I write in this way:
appcmd add site /name:"prova" bindings:http://localhost:8080 /physicalPath:c:\sites\prova
You can do this:
APPCMD.exe set app "prova/" /applicationPool:"YOUR_APP_POOL_NAME_HERE"
Note the trailing slash appended to prova, that's important.
For example if I wish to set the application pool for prova to the DefaultAppPool I would issue the following command:
APPCMD.exe set app "prova/" /applicationPool:"DefaultAppPool"
Picking up from Chris's comment below, if you have an existing application in your site, say /mybloggy and you wish to change application pool it belongs to then you'd issue the following:
APPCMD.exe set app "prova/mybloggy" /applicationPool:"DefaultAppPool"
Alternative syntax:
APPCMD.exe set site /site.name:"Site name" /[path='/'].applicationPool:"App Pool Name"
Found in Windows Server docs:
https://technet.microsoft.com/en-us/library/cc732992(v=ws.10).aspx
Although the OP was looking to assign the app pool within the "add site" command, I couldn't find a way to include it with the original "add site" command. I got it working using "add site" followed by "set site" using syntax by Kev above.
On the other hand, if you ever need to add an "application" under that "site", you can specify the app pool when you use the "add app" command with the applicationPool argument as here:
APPCMD add app /site.name:"prova" /path:/App1 /physicalPath:c:\sites\prova\App1 /applicationPool:"provaAppPool"
p.s. You may need to prefix APPCMD with %systemroot%\system32\inetsrv\ and call
%systemroot%\system32\inetsrv\APPCMD /site.name:"prova"...

Resources