IT:AD:WebDeploy:HowTo:Understand what File does What
Summary
With one or more *.pubxml files, one or more Parameters.xml going in, one *.zip, one *.cmd, and other files coming out of doing a Publish operation…you would not be the first to be completely lost as to what file does what, and what can be modified to make custom install packages.
Process
Some of the following files are used as inputs required to generate a Web Deploy Package, some of the files discussed below are the files generated by Visual Studio when creating a Web Deploy package.
Input Files
There are several files that are used in the process of creating output Web Deploy Packages:
Project {configuration}.pubxml
The {configuration}.pubxml file: * is an input file. * contains the Publish Profile that describes the settings for Publishing to a target condition (Debug, Release) * Created by: Create a Publish Profile * if an optional Project Parameters.xml/ is found (and potentially an optional Project {Configuration}\Parameters.xml/, will include those settings in its creation of the Web Package Parameters.xml/. * it is an IT:AD:MSBuild file in its own right, imported into the project when building the *.csproj.
As we are talking about configuration files, example file names (relative to project root) would be:
- Properties\PublishProfiles\Debug.pubxml
- Properties\PublishProfiles\Release.pubxml
Project Parameters.xml
The Parameters.xml file: * is an input file. * if created (it's optional) it is used to defined modifiable settings that are updatable per target (whereas the project {configuration}.PubXml/ is per configuration). * Important: is not the same as the Web Package Parameters.xml/ within the output zip Web Package/ (see below). * Created in the Project's root by: IT:AD:WebDeploy:HowTo:Create a Publish Profile/Parameters.xml * Important: is a configuration file – shared between all project {configuration}.pubxml/ files. It is not intended to be an environment specific file. * is used during the IT:AD:MSBuild process of creating the Web Package Parameters.xml/ file inside the output zip Web Package/. * Is not subsequently used either by the IIS Import Wizard or *.cmd deployment process – it really is only used during the IT:AD:MSBuild Packaging process.
Regarding Merging Variables
The final package parameters.xml/ is made up of a combination of these settings and project {configuration}.pubxml/ settings (with the project {configuration}.pubxml/ winning).
It is important to notice that as project {configuration}.pubxml/ settings win, it means that Application name/path and other settings usually defined in the project {configuration}.pubxml/ can not be overridden/set using the associated optional project parameters.xml/ file.
But note that this is not really required either.This isn't a problem regarding Project Parameters.xml/ (as one can only have one shared across pubxml's, which would be poor design to a variable specifically set in a project {configuration}.pubxml/ to be cancelled out en-mass…) but can at first appear to be a problem when considering Project {Environment}\Parameters.xml/. But that too is not a problem. See below (Project {Configuration}\Parameters.props/).
Project {Configuration}\Parameters.xml
This file is an optional custom file that can be added to a .csproj root, to add custom configuration specific settings to both the configuration specific settings defined in project {configuration}.pubxml/ and the Project Parameters.xml/ shared between all project {configuration}.pubxml/ (hence why not suitable for environment-specific parameter transformations).
This file is not in any way part of the default Web Deploy process – it's just a WellKnown/ hack.
The hack is based on the fact that project {configuration}.pubxml/ files are nothing but IT:AD:MSBuild files, and one can simply hand craft the project {configuration}.pubxml/ to include external MSBuild/ files to import additional settings, as follows:
<ItemGroup>
<!-- as we build from *.sln, not *.csproj, we start from there : -->
<ParametersXMLFiles Include="$(SolutionDir)\{ProjectName}\Deployment\Configurations\{configuration}\Parameters.props" />
</ItemGroup>
As we are talking about configuration files, example file names (relative to project root) would be:
- Deployment\Configurations\Debug\Parameters.xml
- Deployment\Configurations\Release\Parameters.xml
Project {Configuration}\Parameters.props
We mentioned above that Project {configuration}.pubxml/ variables always take precedence over any transforms set by Project Parameters.xml/ or Project {Configuration}\Parameters.xml}/.
Note: I am currently not sure of what use-case would demand an external override of *configuration* settings set within the *.pubxml.but this shows that it can be done.
To override settings defined within Project {configuration}.pubxml/ files, we just have to tackle the problem earlier in the build lifecycle.
Remember that Project {configuration}.pubxml/ is an IT:AD:MSBuild file, and therefore can be edited to include an external msbuild file:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>Package</WebPublishMethod>
...
<DeployIisAppPath>Default Web Site\ExampleSite</DeployIisAppPath>
...
<PublishDatabaseSettings>
<Objects xmlns="" />
</PublishDatabaseSettings>
</PropertyGroup>
<Import Project="..\..\Deployment\Configurations\Debug\parameters.props" />
</Project>
that points to something like:
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<DeployIisAppPath>Default Web Site\Example_ST_Site</DeployIisAppPath>
</PropertyGroup>
</Project>
It works, because the MSBuild/ import is processed earlier than the transforms.
As we are talking about configuration files, example file names (relative to project root) would be:
- Deployment\Configurations\All\Parameters.props
- Deployment\Configurations\Debug\Parameters.props
- Deployment\Configurations\Release\Parameters.props
Project {Environment}\Parameters.xml
IMPORTANT: Do *not* confuse the two concepts (Configuration != Environment).
##### Process (Packaging != Deployment)
Whereas an Project Parameters.xml/ is shared across all project {configuration}.pubxml/ files, and one can import custom Project {Configuration}\Parameters.xml/ files into the project {configuration}.pubxml/, one has to think of environment specific parameters as a deployment operation, not a packaging operation.
In other words, one normally bakes in configuration specific fields, directly into the Package, but deal with deploying environment specific fields using {ProjectName}.Deploy.cmd/ switches, or – in the case of deploying using the IIS wizard – by hand-crafting the package's Web Package Parameters.xml/ file (more on that below).
Security
Another reason to consider keeping Environment specific settings out of deployment packages is that to create the deployment packages with environment settings embedded as Default Settings – easing deployment – means that the settings have to be in the source code for the IT:AD:Continuous Integration server to access them.
Technically, one could have the settings on the server, outside of the source control, but in a Cloud CI scenario, that's not going to happen.
Let's do it anyway
But assuming that security is not a high concern…what are our options?
For IIS Import
If we are talking about the package being
- for IIS import
- and we want the package to be pre-prepared with default variables for that environment
the we are quickly running out of options. The reason is that the only thing handed to the target sysadmin is a zip package and a deployment doc. The Package Parameters.xml/ inside the Web Deploy Package/ zip file were baked in at build time.
- If it's a one-off, one can manually crack open the zip and edit the Package Parameters.xml/ file.
- If its a package intended to be made over and over again within a IT:AD:Continuous Integration environment, then we have to edit the Package Setparameters.xml/ in the build process, using
XmlPoke(see: Create a Package From The CLI )- Not a great long story:
- This might work for one or two very static variables, but for more, this process is taking power away from developers being able to add/remove variables for a target environment (they have to work on the build server definitions, rather then their source code), this raises the question as to whether being dogmatic is so good… (see below).
As we are talking about environment files, and we are not concerned about security, example file names (relative to project root) might be:
- Deployment\Environment\All\Environment\Parameters.xml
- Deployment\Environment\CI\Environment\Parameters.xml
- Deployment\Environment\ST\Environment\Parameters.xml
- Deployment\Environment\UAT\Environment\Parameters.xml
- Deployment\Environment\DOIST01S\Environment\Parameters.xml
Merging Configuration and Environment.
Remember when I said above that:
Configuration != Environment
Strictly, that's true. Practically, in an Enterprise environment, less so.
The reason this is the case is in an Enterprise environment, one only has one Release Configuration to contend with, and commonly less than 5 environments to contend with (CI, ST, SIT, PP/UAT, PROD). And the IIS wizard - for all it's lack of features as compared to the scripting approach, is liked by some, so it would be handy if default settings were baked in early, per environment.
But to do that, you'll have to make your {configuration}.pubxml/ files into {configuration}.{environment}.pubxml so that they each publish profile (ie environment) can IT:AD:MSBuild include their own props.
It's a bit of a compromise, but as compromises go, not terrible.
-
- Advantages:
- Developers can still fiddle with settings (the *.props files are in their source).
- Disadvantages:
- Beyond ST/SIT, there is a bit of security breach as developers get access to settings that would maybe better to not share beyond infrastructure personnel.
By Script
If we are talking deploying by script, one has a lot more options than deploying by IIS wizard.
Options at our disposal are
- Invoking {projectname}.deploy.cmd/ using
-setParamfor one or two parameters. - Crafting a custom {{ProjectName}.SetParameters.xml/ file (naming it for the target environment) and invoking the {projectname}.deploy.cmd/ using the
-SetParametersFileswitch.
But remember that these options are only good for scripting -- and doesn't translate to IIS Wizard.
Output Files
Using Visual Studio to create a Web Package creates several deliverables.
- {projectname}.readme.txt
Web Package
The zip package is the primary deliverable (all the rest are there to add value, but are not essential).
The zip package contains:
- archive.xml
- parameters.xml systemInfo.xml * Contents folder
Web Package Parameters.xml
- Important: don't confuse it with the Project Parameters.xml/ file discussed above.
- Hard-baked within the Web Package/ zip file during the build process.
- Is the combination of project {configuration}.pubxml/ and project parameters.xml/ available to it when the Web Package was created.
- Important: is the file that drives the IIS auto import wizards autogenerated forms, as it has name, description, type of field, default value, validation rules, etc.
- is in same format (ie 'parameters/parameterEntry' tags), made from merging the ones in the optional parameters, plus default settings of
IisAppto set target 'ProviderPath' (path to find files used by msdeploy sync provider's target path).
<parameters>
<parameter tags="IisApp" defaultValue="Default Web Site\Test" name="IIS Web Application Name">
<parameterEntry match="^Z:\\Spikes\\XAct\.Spikes\.WebDeploy05\\obj\\Release\\Package\\PackageTmp$" scope="IisApp" kind="ProviderPath"/>
<parameterEntry match="^Z:\\Spikes\\XAct\.Spikes\.WebDeploy05\\obj\\Release\\Package\\PackageTmp$" scope="setAcl" kind="ProviderPath"/>
</parameter>
</parameters>
Note:The ProviderPath is the Path where to find files used by msdeploy sync providers target paththe match filter is a zip file structure specific format in order to find the file *within* the zip...
* The Transformations will be run at deploy time (ie, when invoking the Web Deploy .cmd script, or using the IIS's import tool). Important: As IIS's import tool does not use the SetParameters.xml file (that is outside the package), these are the settings that will be used by IIS's import wizard to provide default values.
{ProjectName}.Deploy.cmd
This is:
* an output product.
* the default script used to deploy packages.
* created by Visual Studio when you click Publish, as long as the Publish definitions are for creating a Web Package.
* Reads settings from the Web Package Parameters.xml/ file, overriding those values with any values found within {ProjectName}.SetParameters.xml/
- Not all parameters in {ProjectName}.SetParameters.xml/ can be used to crush parameters hard baked into the zip Web Package Parameters.xml/.
- I don't understand why yet.
{ProjectName}.SetParameters.xml
The file: * is an output product file. * contains transforms that come from both the project {configuration}.pubxml/ file, and the optional Project Parameters.xml/ (and any optional Web Package Parameters.xml/ inside the Zip, this file is only usable in script scenarios.
When generating the Package file using IT:AD:MSDeploy, it creates a {projectname}.zip package, and a {projectName}.SetParameters.xml file.
This file is:
- Not used by IIS.
- Only used by the WebDeploy generated {projectName}.deploy.cmd
- TODO: Not sure if it required.
- As the { does not provide a UI, this file provides a means to override an externalized means of updating the values in the the
Parameters.xmlfile that is inside the zip. - This is the proper way of installing a package, by script, to set settings per environment
The format of the file is
<?xml version="1.0" encoding="utf-8"?> <parameters> <setParameter name="IIS Web Application Name" value="Default Web Site\ExampleSite" /> <setParameter name="providerPath" value="Default WebSite\TestA-FromParameterB" /> </parameters>
Note:It's not a *parameter/parameterEntry* format,but a *parameters/setParameters* format.
TakeAway
You have to decide early which way you will be deploying – via IIS or via script files.
There are pros/cons to both approaches.