Creating a server-level Web Deploy package - asp.net

I can use Web Deploy to create packages that can be imported in existing IIS sites after the IIS server administrator manually creates the site for me.
Can I use Web Deploy to create packages that can be imported as a site instead of an application?
When I try to import my existing packages, I get this ugly error.

This might not be an answer to the question as was not able to find information on how to create a site package.
But as you asked for it in the comments, here's my approach on how to use the .cmd file created by the package process to install on site level.
Step 1
I create a package in our build process with msbuild. I've just added an extra step to our normal build that creates the project files in a deploy directory.
<Target Name="CreateDeploymentPackage">
<MSBuild Projects="$(CurrentProject).csproj" Targets="Package"
properties="Platform=$(Platform);
Configuration=$(Configuration);
DeployOnBuild=false;
DeployTarget=Package;
PublishProfile=$(Environment);
PackageLocation=$(DeployDirectory)\_PublishedWebsites\DeployPackage\$(CurrentProject).zip;
PackageAsSingleFile=true;
_PackageTempDir=$(PackageOutputDir)\temp;">
</MSBuild>
</Target>
I did set a specific PublishProfile to be able to pass a Web.config transformation for everything I know at build time.
Step 2
I've created a Parameters.xml in my project to be able to change params on install time of the package.
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<parameter name="Log4net to email"
description="Please provide the email address for Log4net."
defaultValue="itsupport#ourcompany.com"
tags="">
<parameterEntry kind="XmlFile" scope="\\web.config$" match="//log4net/appender[#name='SmtpAppender']/to/#value" />
</parameter>
<parameter name="Webservice address"
description="Please provide the endpoint address for the document web service"
defaultValue="http://test.services.ourcompany.com/Service.svc"
tags="">
<parameterEntry kind="XmlFile" scope="\\web.config$" match="//system.serviceModel/client/endpoint/#address" />
</parameter>
<parameter name="Elmah error email subject"
description="Please provide the elmah errormail subject"
defaultValue="Our Portal (Production) | An unexpected error occurred"
tags="">
<parameterEntry kind="XmlFile" scope="\\web.config$" match="//elmah/errorMail/#subject" />
</parameter>
</parameters>
You might think why there is no sitename and connection string in the Parameters.xml. But these are created automatically configurable when the deploy package is created and can be set with the SetParameters.xml
Read here: Why are some Web.config transforms tokenised into SetParameters.xml and others are not?
Step 3
Then I created a SetParameters-.xml for every environmen we have (prod, staging, test, dev). Here's one example for staging:
<?xml version="1.0" encoding="utf-8"?>
<parameters>
<setParameter name="IIS Web Application Name" value="staging-sitename.ourcompany.com" />
<setParameter name="Log4net to email" value="webdev#ourcompany.com" />
<setParameter name="Webservice address" value="http://staging.services.ourcompany.com/Service.svc" />
<setParameter name="Elmah error email subject" value="Our Portal (Staging) | An unexpected error occurred" />
<setParameter name="PortalEntities-Web.config Connection String" value="metadata=res://*/Src.Entity.PortalEntities.csdl|res://*/Src.Entity.PortalEntities.ssdl|res://*/Src.Entity.PortalEntities.msl;provider=System.Data.SqlClient;provider connection string="Data Source=test.sql.ourcompany.com;Initial Catalog=Portal_Staging;User Id=<userid>;Password=<password>;Application Name ='OurPortal';Connection Timeout=180;MultipleActiveResultSets=True"" />
</parameters>
Step 4
Then I excecute the install on the server with the following command
Portal.Web.deploy.cmd /Y -setParamFile:"Portal.Web.SetParameters-STAGING.xml"
There's still a lot of room for improvement, and I would like to automate more but this is what I have right now.

Basically instead of installing at the root of the site, deploy to a folder within the site!

Related

MSDeploy setParameter.xml not transforming web.config

In my "myconfig" config profile transform for web.config i have this under appSettings:
<add key="my.config" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" value="derp" />
When I msbuild with this transform the value is transformed correctly. Now I want to build an msdeploy package and transform this value at deploy time.
I drop this parameters.xml in my project root:
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<parameter name="my.config" description="sdfsdfsdfsd" defaultValue="fart">
<parameterEntry kind="XmlFile"
scope="\\Web\.config$"
match="/configuration/appSettings/add[#my.config]/#value/text()" />
</parameter>
</parameters>
I build my package
msbuild app.csproj /T:Package /p:Configuration=myconfigprofile;PackageLocation=mydeploy.zip
I look at mydeploy.SetParameters.xml
<?xml version="1.0" encoding="utf-8"?>
<parameters>
<setParameter name="IIS Web Application Name" value="Default Web Site/myApp_deploy" />
<setParameter name="my.config" value="fart" />
</parameters>
Then I go into parameters.xml inside of mydeploy.zip and see its there too:
<parameters>
<parameter name="my.config" description="sdkflsdjfldfj" defaultValue="fart">
<parameterEntry kind="XmlFile" scope="\\Web\.config$" match="/configuration/appSettings/add[#name='my.config']/#value/text()" />
</parameter>
</parameters>
looks good so far, then i deploy:
mydeploy.deploy.cmd /Y /M:server1
I look at web.config on the deploy server and the value is not transformed. I see no errors either, how do i debug this even?
When I run msbuild with parameters.xml present what magic happens there? How is the package preps to be able to transform web.config via parameters to web deploy?
This:
add[#name='my.config']
Had to be changed to this:
add[#key='my.config']
But the bigger question remains, how do I debug? I had to try a million times and just guess because I had zero errors/logs to help troubleshoot this. Is there verbose logging or some kind of validator or anything at all?
For debugging technet gave me this to try:
msbuild MyProject.proj /t:go /fl /flp:logfile=MyProjectOutput.log;verbosity=diagnostic
If you are using MSDeploy you can get the full output of the deployment by using the following:
msdeploy -verb:sync -source:dirpath=C:\WebDeployDemo\Src -dest:dirpath=C:\WebDeployDemo\Dst -setParamFile=C:\WebDeployDemo\ParameterFile.xml -verbose >msdeploysync-verbose.log
This helps with VSTS WebRM deployment debugging if you use the -verbose flag.
Sources:
https://learn.microsoft.com/en-us/iis/publish/troubleshooting-web-deploy/troubleshooting-web-deploy
https://blogs.msdn.microsoft.com/spike/2012/10/12/using-msdeploy-to-update-and-remove-sections-in-web-config-a-simple-example/

Azure web app delete logs directory on swap

I have multiple ASP .NET MVC and Web Api apps hosted on Azure.
I use two differents stages for deployment : stage and PROD. Basically, I want to have two different folders for logs : logs-stage and logs-PROD. This is working well based on my web.config and properties set directly in Azure.
The issue is that each time I deploy, all the previous logs are deleted. How can I avoid that ?
My NLog config looks like the following :
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target xsi:type="File" name="f" fileName="${basedir}/logs-${appsetting:name=Version:default=DEV}/website.${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${logger} - ${message}" />
<target name="email-Errors" xsi:type="Mail"
smtpServer="smtp.sendgrid.net"
smtpPort="myPort"
enableSsl="false"
smtpUsername="myUsername"
smtpPassword="myPassword"
smtpAuthentication="Basic"
from="myEmail"
to="${appsetting:name=WEBSITE_EMAIL_DEVELOPERS:default=myEmail}"
subject="[${appsetting:name=Version:default=DEV}][WEB][${uppercase:${level}}]"
layout="${longdate} ${uppercase:${level}} ${logger} - ${message}"
html="false" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="f" />
<logger name="*" minlevel="Error" writeTo="email-Errors" />
</rules>
</nlog>
The issue is that each time I deploy, all the previous logs are deleted. How can I avoid that ?
According to your description, it seems that when you publish the WebApp then remove additional file in the Azure WebApp. If it is that case please have a try to uncheck the [Remove additional files as destination] option during publish the WebApp.
Updated:
From the blog, we could know that if we swap the slots, just the DNS pointer changes, so if you have the nlog in the product after swap then the Nlog file is in the staging slot that not deleted. The following the snippet from the blog.
In short, the Swap operation will exchange the website's content between 2 deployment slots.
Swapped and what is not but note that swap is not about copying the content of the website but more about swapping DNS pointers.

publish a website through MSBuild

I am trying to publish an asp.net website through msbuild on command prompt, but I did not get success.
I tried by creating a new web application and execute below command, it works.
C:\Windows\system32>msbuild.exe "C:\VisualStudio 2012\Projects\HelloWorldSample\HelloWorldSample\HelloWorld\HelloWorldSample.csproj" /p:DeployOnBuild=true /p:PublishProfile="HelloDeploy"
But my problem is, in website I don't have .csproj file. That's why I am unable to execute above command for that.
So please any one help me how I can do deploy for a web site.
Thanks.
If your website has no csproj project file it most likely is a directory containing just your website files. You can convert it to a Web Application (thus getting a csproj file) or directly use msdeploy to generate a deployable package and then use msdeploy to deploy it to your website. This is wat actually would happen under the hood when you run msbuild /p:DeployOnBuild
To create a msdeploy deployable website you can use the following snippet
msdeploy.exe
-verb:sync
-source:iisApp="C:\development\mywebsite\the-website-dir"
-dest:package="C:\temp\mywebsite-package.zip"
-declareParamFile:"C:\development\mywebsite\parameters.xml"
You will need to create at a parameter for the site name in the parameters.xml file which will be packaged with the zipped website project
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<!--
This file contains (among others) references to web.config fields (xpath)
which will be 'parameterized' on package before deploy. The actual values will then be filled in based on the given deploy environment.
-->
<parameter name="IIS Web Application Name" tags="IisApp">
<parameterEntry kind="ProviderPath" scope="iisApp" match="" tags="IisApp" />
</parameter>
</parameters>
This will generate a deployable msdeploy package which you can upload to your IIS by using:
msdeploy.exe -source:package=c:\temp\mywebsite-package.zip -dest:auto,computerName=https://mysite.example.com:8172/MsDeploy.axd,userName=USERNAME,password=PASSWORD,authtype=Basic, -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:example-setParameters.xml -allowUntrusted
Together with a setParameter file
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<setParameter name="IIS Web Application Name" value="mysite.example.com" />
</parameters>

BizTalk ListApp command line

I used the following code in c# to get policies\rules from deployed application in BizTalk server.
BTSTask.exe ListApp -ApplicationName:"EAISolution" -ResourceSpec:"c:\EAISolution.PolicyInf
o.xml" /Server:VHYDTRBELSUP-02 /Database:BizTalkMgmtDb
From above command I got the output as below
<?xml version="1.0" encoding="utf-16" ?>
<ResourceSpec xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ApplicationName="EAISolution" xmlns="http://schemas.microsoft.com/BizTalk/ApplicationDeployment/ResourceSpec/2004/12">
<Resources>
<Resource Type="System.BizTalk:BizTalkAssembly" Luid="EAIOrchestration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=97e0f507fd7fd10d" />
<Resource Type="System.BizTalk:BizTalkAssembly" Luid="EAIServices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=97e0f507fd7fd10d" />
<Resource Type="System.BizTalk:BizTalkAssembly" Luid="FFSchemasTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=97e0f507fd7fd10d" />
<Resource Type="System.BizTalk:Rules" Luid="RULE/ProcessPurchaseOrder/1.0" />
<Resource Type="System.BizTalk:BizTalkBinding" Luid="Application/EAISolution" />
</Resources>
</ResourceSpec>
and from BizTalk server I got the below output using policy export in BizTalk server administration
<?xml version="1.0" encoding="utf-8" ?>
<brl xmlns="http://schemas.microsoft.com/businessruleslanguage/2002">
<ruleset name="ProcessPurchaseOrder">
<version major="1" minor="0" description="" modifiedby="username" date="2013-05- 27T12:04:55.6121122+05:30" />
<configuration />
<bindings>
<xmldocument ref="xml_31" doctype="RuleTest.PO" instances="16" selectivity="1" instance="0">
<selector>/*[local-name()='PurchaseOrder' and namespace-uri() ='http://EAISolution.PurchaseOrder']/*[local-name()='Item' and namespace-uri()='']</selector>
<selectoralias>/PurchaseOrder/Item</selectoralias>
<schema>....\PO.xsd</schema>
</xmldocument>
<xmldocument ref="xml_32" doctype="RuleTest.PO" instances="16" selectivity="1" instance="0">
<selector>/*[local-name()='PurchaseOrder' and namespace-uri()='http://EAISolution.PurchaseOrder']
</selector>
<selectoralias>/PurchaseOrder</selectoralias>
<schema>....\PO.xsd</schema>
</xmldocument>
</bindings>
<rule name="ApprovalRule" priority="0" active="true">
<if>
<compare operator="less than or equal to">
<vocabularylink uri="3f0e9bcc-6212-4e6a-853c-e517f157a626" element="d4eb2deb-06d3-42c4-af49-ceb21331b1cc" />
<lhs>
<function>
<xmldocumentmember xmldocumentref="xml_31" type="int" sideeffects="false">
<field>*[local-name()='Quantity' and namespace-uri()='']</field>
<fieldalias>Quantity</fieldalias>
</xmldocumentmember>
</function>
</lhs>
<rhs>
<constant>
<int>500</int>
</constant>
</rhs>
</compare>
</if>
<then>
<function>
<xmldocumentmember xmldocumentref="xml_32" type="string" sideeffects="true">
<field>*[local-name()='Status' and namespace-uri()='']</field>
<fieldalias>Status</fieldalias>
<argument>
<constant>
<string>Approved</string>
</constant>
</argument>
</xmldocumentmember>
</function>
</then>
</rule>
</ruleset>
</brl>
So please let me know how to get the output of second using command line.
BTSTask will only export the policy as part of an MSI (see below).
You could then extract the MSI (see How to extract msu/msp/msi fileds from the command line) to get the policy file.
From How to Import a Policy
BTSTask does not provide a specific command for importing (or exporting) policies; however you can use the ExportApp command of BTSTask to selectively export only the policies in an application that you want, including no other application artifacts. Then you can use the ImportApp command to import the .msi file into an application in a different BizTalk group. This is the approach described in this topic. When you do this, the policy is automatically imported and published in the BizTalk group and added to the specified application.
The below steps will get export the policy, but as part of an MSI.
From How to Export a Policy
Use the BTSTask ListApp command with the /ResourceSpec option to generate an XML file that lists the artifacts in the BizTalk application from which you want to export a policy, as described in ListApp Command.
Edit the XML file generated in the previous step, deleting all of the artifacts except for the policy or policies that you want to export.
Use the BTSTask ExportApp command, and specify the modified XML file for the /ResourceSpec parameter. For more information, see ExportApp Command.
BTSTask exports the specified policies and all of their associated vocabularies into an application .msi file.

How do I target an already existing application pool with webdeploy?

I am trying to make sure that my app gets deployed to a specific application pool that already exists when using Web Deploy. The application pool should be configurable by the user using the GUI when installing app through IIS Manager or by changing the value in the .setparameters.xml file when installing via the commandline from a web package. Inserting the following parameter entry into my parameters.xml doesn't do the trick.
<parameter name="Application Pool" description="Application Pool for this site" tags="iisApp" defaultValue="ASP.NET v4.0">
<parameterEntry kind="providerPath" scope="IisApp" match="applicationPool" />
</parameter>
Is there a straightforward way to accomplish this? If not, how would I go about getting this done?
Here's what I did to set the application pool via command line or SetParameters.xml after lots of reading on SO and elsewhere:
Add a Parameters.xml file to the project.
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<parameter name="AppPool" defaultValue="ASP.NET 4.0">
<parameterEntry kind="DeploymentObjectAttribute" scope="application" match="applicationPool/#applicationPool" />
</parameter>
</parameters>
Sources:
How to specify MSDeploy parameters from MSbuild
http://vishaljoshi.blogspot.com/2010/07/web-deploy-parameterization-in-action.html
Add two parameters to msbuild when creating the package:
/P:IncludeIisSettings=true
/P:IncludeAppPool=true
Source:
https://stackoverflow.com/a/13678143/448876
Set via SetParameters.xml:
<setParameter name="AppPool" value="Some AppPoolName"/>
OR
Using command line parameter (msdeploy or *.deploy.cmd):
"-setParam:'AppPool'='Some AppPoolName'"

Resources