How to include app pool specification in asp.net deploy script? - asp.net

I have an MSBuild script that is generating a deployment script for my web app.
Project.build (excerpt)
<MSBuild Projects="xxxxx.sln" Properties="
CreatePackageOnPublish=true;
DeployOnBuild=true;
IncludeIisSettings=true;
IncludeAppPool=true;" >
<Output TaskParameter="TargetOutputs" ItemName="CompiledAssembly" />
</MSBuild>
When this is executed, it does produce a Package folder in the output that contains a deployment .cmd file and associated .zip file.
xxxx.SetParameters.xml (generated)
<?xml version="1.0" encoding="utf-8"?>
<parameters>
<setParameter name="IIS Web Application Name" value="Default Web Site\xxxxx" />
<setParameter name="DefaultConnection-Web.config Connection String"
value=" ... snipped ..." />
</parameters>
As you can see, there is no reference to app pool here. Likewise, there is mention of app pool in the generated xxxx.zip\parameters.xml
When I execute xxxxxx.deploy.cmd /Y, it correctly creates the application in IIS. The problem is, it seems to use the default application pool for the machine. It's a .net 4 app, so if the default is .net 2, the app fails to run.
Is there a way to make the deployment script include an app pool definition so that it won't require manual app pool changes to run?
I did find this question, which seems to be the same. However, as you can see, I've already included the answer from that question, and it has no effect.

If you're trying to deploy a 4.0 app to a 2.0 default app pool without providing an override it will not fail to run but fail to deploy, MSDeploy would simply fail to precreate a virtual app with ERROR_APPPOOL_VERSION_MISMATCH error.
IncludeAppPool is the correct property, but it only tells the packager to include the settings, you have to provide the source, i.e. the "master" virtual app with correct app pool to copy from.
Open project properties and switch from IIS Express to Local IIS, this will enable app pool flag under the package/publish options. I believe you can switch back afterwards, the settings will remain.
This would basically do 2 things, add <IncludeAppPool>true</IncludeAppPool> as well as add the master app under <WebProjectProperties> section. Now when you build or package your source manifest will not have the managedRuntimeVersion requirement but your parameters will now have IIS Web Application Pool Name to customize.
If you want to actually create a new app pool then it gets tricky. I'm not aware of a way to create it during iisApp creation or with some MSBuild flag, but with MSDeploy (the tool behind your .cmd) it would require a dump of your local pool and sync up with appPoolConfig provider, probably as part of your .build script before the .cmd call.
msdeploy -verb:sync -source:appPoolConfig=Foo -dest:package=foo.zip
msdeploy -verb:sync -source:package=foo.zip -dest:appPoolConfig=Foo,computerName=Bar
Keep in mind that without specifying individual appPoolConfig the sync, as it should, would destroy other pools, so do -whatIf first just in case.
You can probably try to merge the archive.xml of your package and the archive.xml with the app pool definition, but I can't image how it would work and what relationship between iisApp and appPoolConfig providers is there.
Edit: You can use manifest provider to combine package or iisApp with appPoolConfig

Related

Azure DevOps - How to Publish an ASP.NET application

I have an ASP.NET (4.7.2) app that successfully runs and starts on my machine. This app has a web.config file that contains the following:
Web.config
<appSettings>
<add key="username" value="someone#email.com" />
<add key="port" value="25" />
</appSettings>
These are the configuration values I want to use while working. However, when I deploy the app to my Azure App Service for test purposes, I want to change the port value. For that reason, I've added a config transform named "Web.Test.config" with the following:
Web.Test.config
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="port" value="58" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
</appSettings>
</configuration>
Unfortunately, it doesn't seem like the transform is happening. I've ready that the transforms only happen during "publishing". At this time, I'm deploying via an Azure DevOps Pipeline that includes the following tasks:
NuGet
Restores the packages based on the .sln file
MSBuild
Builds the .csproj that defines my ASP.NET app. The "Configuration" property is set to "Test".
Azure App Service Deploy
Attempts to deploy the ASP.NET app as a "Web App on Windows" to my deployment slot. The "Package or folder" is set to MyAspNetApp. The
While this build pipeline successfully runs, the configuration transforms do not seem to be taking effect. How do I do a "publish" via an Azure DevOps Build Pipeline to an Azure App Service so that my config transformations will be generated.
For App.Config or Web.Config (XML) file there are two options.
File Transform task suggested by #Jabberwocky in the comment.
Variable Substitution as per below image in the release pipeline.
Sample XML variable substitution
For modern .NET apps where we use json configuration, variable substitution is the only way. Even though File Transform task promises to work for both it is not clear as per this thread
For JSON variables, you have to enter the full path hierarchy like this
Sample JSON variable substitution
How do I do a "publish" via an Azure DevOps Build Pipeline to an Azure App Service so that my config transformations will be generated.
First, we need to make sure the web.*.config files are included in the build output and the file is transformed correctly. Check it locally first.
Besides, the following steps should help:
Remove the nesting of the web.dev/stest/atest/prod.config files
either by removing the element in csproj, a nesting
add-on for VS or the File Nesting context menu item in VS 2017
A note from the documentation stated XML transformation notes that:
By default, MSBuild applies the transformation as it generates the web
package if the element is already present in the
transform file in the *.csproj file. In such cases, the Azure App
Service Deploy task will fail because there is no further
transformation applied on the Web.config file. Therefore, it is
recommended that the element is removed from all the
transform files to disable any build-time configuration when using XML
transformation.
Make sure that the *.config files have the 'Copy to Output Directory'
property set to if newer or always
Build the solution locally and check the contents of bin\release
folder and make sure the web.*.config files are included
Run a build in VSTS and make sure the web.*.config files are included
in the zipped package
Check the checkbox XML transformation on the Azure App Service Deploy task:
There is a great document about how to Using XML Transformations when deploying to Azure App Service using VSTS, you can check it for some more details.
BTW, since you just need to change the port value, you can use the option XML variable substitution on the the Azure App Service Deploy task.
Ticket for details: How to transform Web.Config file 'Properly' with VSTS!
Hope this helps.

Datadog - Monitoring multiple applications in the same site hosted by IIS

I'm trying to monitor several applications within the same site in IIS.
With just running the msi of the tracer dd-trace-dotnet, I started to see the events, but these are registered as [site name]/[application] e.g default_web_site/docs_webhook
I would love to be able to logs them under a custom service name for each application, but according to the documentation, this is only possible at the site level.
Manual instrumentation is described for windows services, setting the environment variable DD_SERVICE_NAME in the registry entry HKLM\System\CurrentControlSet\Services\{service name}\Environment is enough, but does not apply to IIS applications.
NOTE: Creating separate sites for each application is not an option right now.
For each web application that you want to configure with a different Datadog APM service name, you need to set the environment variable DD_SERVICE_NAME. If they're all running under the same IIS process, that's not possible.
In IIS there's a feature named Application Pool, which can be used to isolate multiple web applications by running them under different processes.
The first thing you need to do is to create a separate application pool for each web application. Once you're done with that, you can set a different DD_SERVICE_NAME for each application pool. The command to set an environment variable scoped to a specific application pool is
appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='MyAppPool'].environmentVariables.[name='DD_SERVICE_NAME',value='my-service']" /commit:apphost
where MyAppPool is the name of the application pool, and my-service is the service name that you want to use for the Datadog APM.
After running the above command, you have to restart IIS for the changes to take effect:
net stop was /y
net start w3svc
Starting with version 1.0 of Datadog's .NET Tracer, you can set most settings in your application's app.config/web.config file. For example, to set DD_SERVICE_NAME:
<configuration>
<appSettings>
<add key="DD_SERVICE_NAME" value="my-service"/>
</appSettings>
</configuration>
[Disclaimer: I am a Datadog employee]

How to Setup and Deploy a .net web app Build Using TFS 2015.Update3.RC1 CI on Prim

Using Visual Studio 2015 update 3
and Team Foundation server Update 3 (on-site)
I'm attempting to setup up and auto deploy for a .net core boilerplate app targeting full framework 4.61. Currently my app is mostly the stock app you get when selecting new->Project->Templates->Visual C#->Web->ASP.NET Core Web Application(.Net Framework). My Goal is to Push via Git and then have the website show up correctly on the test server.
I was able to use the instructions I found at the MVA
However, they did not go into any detail on how to deploy to an on-prem server. But they clearly stated that it was possible.
I have Setup this web project in TFS2015 using Git as source control. For my Build Definition I'M using the Visual Studio default build ScreenShot of TFS build Definition, I also have the site building whenever I push new code.
The problem I have is I don't understand what to do next.
my thought is that I would need to:
turn off IIS (iisreset -stop) via PowerShell.
Move the built files to my iss location. In this example, it is C:\inetpub\apps\My
run scripts to update database schema(note currently there is no database setup but that is my next step. planning to use "code first" with "Entity Framework"
I would have to turn IIS back on.
I did get a big clue to add the following in my Visual Studio Build Step. MSBuild Arguments.
/p:DeployOnBuild=True /p:DeployDefaultTarget=WebPublish
/p:WebPublishMethod=FileSystem /p:DeleteExistingFiles=True
/p:publishUrl=$(build.artifactstagingdirectory)\for-deploy\website
From Benjamin Day Blog www.benday.com/2016/09/08/an-asp-net-mvc-site-thats-easy-to-deploy-from-a-tfs-build/ (sorry can't link due to lack of rep points)
using those build MS build arguments I can find my built website and it appears to be working correctly except for the Web.config file is showing
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
When is should be
<aspNetCore processPath=".\My.Multnomah.exe" arguments="" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
My Release Definition is in three steps
PowerShell on Target Machines
Machines = the server I'm going to deploy to
Admin Login = My AD username.(will switch to service account after working)
Protocol = Https
PowerShell Script = file location on the Script I have on the agent PC/which is also the test web server
here is the PowerShell script to turn of IIS.
iisreset -stop
Windows Machine File Copy
this step is working correctly
PowerShell on Target Machines
same as step 1. but
Currently, the Release is working if I manually turn off IIS then manually update the web.config file.
So, in short here are the questions?
How can I automatically Correct the web.config?
How can I arrange to have IIS Stopped before the file transfer and Started after the Transfer or is there a better way?(Current the release is failing if I don't have IIS off)
Is my understanding how I explained this correct/ What are the Build steps you would use to deploy on-prem?
1.How can I automatically Correct the web.config?
You can replace corresponding values with variable values (Open your build definition=>Variable) by using Replace Token task.
For example: Add variables to your build/release definition (e.g. name:LAUNCHER_PATH value:.\My.Multnomah.exe), change your web.config (replace %LAUNCHER_PATH% to #{LAUNCHER_PATH}# and others)
2.How can I arrange to have IIS Stopped before the file transfer and Started after the Transfer or is there a better way?
You don’t need to stop IIS before update web.config file, you can update it directly. After updating web.config, the website will be recycled automatically.
3.Is my understanding how I explained this correct/ What are the Build steps you would use to deploy on-prem?
These steps are ok, there are IIS Web App Deployment Using WinRM and IIS Utilities task that can help you to deal with IIS.

Windows Azure Startup task not firing

I have a standard ASP.Net application to which I added an Azure Deployment project to deploy to Azure. The app deploys fine to Azure.
I then wanted to extend it to have a startup task.
I added the following to the ServiceDefintion.csdef
<Startup>
<Task commandLine="startup.cmd" executionContext="elevated" taskType="simple"/>
</Startup>
startup.cmd is located in the applications bin folder. I have logging the command file so I can see it is not being executed.
When I deploy the same application to the Compute Emulator on my local machine the startup task executes correctly.
Am I missing something?
Your "startup.cmd" shall not just be in your app BIN folder, but instead in the root folder and marked as "Content" and "Copy to output directory" -> "Copy always". Otherwise it will not get deployed to the Azure.
Another moment to pay attention with Web Applications is that you most probably shall put the bin folder also in the startup task definition. Something like:
<Startup>
<Task commandLine="./bin/startup.cmd" executionContext="elevated" taskType="simple"/>
</Startup>
Hope this helps.
A bit late to the party.
I had this issue as well and for me it was that I had set the Web Role project to the startup project instead of the Azure Cloud Service project. By setting the Azure Cloud Service as the startup project you start the project with the azure emulator, which is needed to get start, run and stop events to work as in your azure environment.

Where is web.config file when running Azure web role in Compute Emulator?

I created an empty Azure Cloud Service project, then added a web role there. The role project has a web.config file.
When I hit F5 the role is deployed in Compute emulator. I went into the folder where role binaries are deployed - there's no web.config file there.
What's happening? Is that because I didn't set "copy always" on web.config file? What web.config does my role use?
If your role is configured for Full IIS mode (for those unaware of the difference between Hosted Web Core and Full IIS, see this blog post), the compute emulator should deploy the web role to IIS where it can be viewed in IIS Manager. On my machine (I'm running Azure SDK 1.5), the deployed web role's physical path is my source code directory.
I think web.config is compiled into your assembly as content in your development environment, and is not directly accessible like in staging/prod. You don't need to use Copy Always, if its marked as Content its all you need. You can use Environment.CurrentDirectory to see your web root path.
Even though the preferred way of storing configuration in Windows Azure applications is in the ServiceConfiguration.cscfg file, there are still many cases when you may want to use a normal .NET config file - especially when configuring .NET system components or reusable frameworks. In particular whenever you use Windows Azure diagnostics you need to configure the DiagnosticMonitorTraceListener in a .NET config file.
When you create your web role project, Visual Studio creates a web.config file for your .NET configuration. While your web application can access this information, your RoleEntryPoint code cannot-because it's not running as a part of your web site. As mentioned earlier, it runs under a process called WaIISHost.exe, so it expects its configuration to be in a file called WaIISHost.exe.config. Therefore, if you create a file with this name in the your web project and set the "Copy to Output Directory" property to "Copy Always" you'll find that the RoleEntryPoint can read this happily. This is one of the only cases I can think of where you'll have two .NET configuration files in the same project!
All info is from Azure Team Blog and I have used this solution successfully- http://blogs.msdn.com/b/windowsazure/

Resources