5

I need to update values in web.config in Azure TFS. I am able to get the value for connectionString replaced which is part of the appSettings (for this to work, I needed to enable the setting named XML variable substitution (under IIS Web Deploy).

However, there are other areas within web.config which do not get replaced.

I have tried several different approaches, using different tasks for token replacement, using the "Release" or "Environment" setting for variables, using variable groups. However, none of these worked.

Currently I am using the Replace tokens task (available at https://github.com/qetza/vsts-replacetokens-task#readme )

I have set the Token Prefix and Suffix to __ (to match with what is web.config)

Here is an extract of the web.config file

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="ConnectionString" value="__ConnectionString__"/>
    </appSettings>
    <system.web>
        <pages theme="__Theme__" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
            <controls>
                <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </controls>
        </pages>
    </system.web>
    <system.serviceModel>       
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
        <bindings>
            <customBinding>
                <binding name="TestBinding1">
                    <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" messageVersion="Soap12" writeEncoding="utf-8">
                        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    </textMessageEncoding>
                    <httpsTransport manualAddressing="false" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous" bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard" keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous" realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true" requireClientCertificate="false" />
                </binding>
            </customBinding>
            __basicHttpBindingOptionalBinding__
        </bindings>
        <client>
            <endpoint address="__TestEndPoint__" binding="customBinding" bindingConfiguration="TestBinding1" contract="BSEInspectionsWebServiceForFDA.StateDataTransfer" name="StateDataTransferPort" />
            __endpointOptionalEndpoint__
        </client>
    </system.serviceModel>
</configuration>

I expect only blank lines for basicHttpBindingOptionalBinding and endpointOptionalEndpoint. The Theme needs to be replaced with TestTheme and TestEndPoint needs to be set with the value defined in variables.

SK-USA
  • 91
  • 1
  • 8
  • UPDATE: I have solved this using this method. (I think this is not ideal but it works for now). Added an extension "RegEx Find & Replace". For each variable, I invoked this extension (e.g. __ConnectionString__ is replaced with the variable value for the release). Like wise for __Theme__, __basicHttpBindingOptionalBinding__, __TestEndPoint__ and __endpointOptionalEndpoint__. – SK-USA Jun 03 '20 at 23:16

2 Answers2

1

Add a parameters.xml to your project, as described here: https://learn.microsoft.com/en-us/aspnet/web-forms/overview/deployment/web-deployment-in-the-enterprise/configuring-parameters-for-web-package-deployment

specify parameter there, for example, "myEndpointAddress".

Then in IIS Web Deploy Task use additional arguments to pass the value -setParam:name='myEndPointAddress',value='new_value'

  • 2
    Currently, this answer relies heavily on information contained in the link—which means it will be hard to follow if/when Microsoft changes the URL to that link. To help keep this relevant in the future, can you edit your answer to include the relevant details of how to add `parameters.xml` to a project? – Jeremy Caney Jun 02 '20 at 19:50
0

For replacing __Theme__, __TestEndPoint__, I recommend extension task Magic Chunks.

You can install Magic Chunks task to your organization and add it to your pipeline. It tested your web.config with below example settings for magic chunk task:enter image description here

For replacing basicHttpBindingOptionalBinding , i recommend another extension task RegEx Find & Replace

enter image description here

You can reference your pipeline variables in both the tasks. I added above two tasks to my test pipeline. The values in web.config was replaced successfully.

Update: To extract the web.config from the build artifacts using powershell task to run below scripts:

You need to config $sourceFile and $destFile yourself. $sourceFile should be the absolute path to zip file.

$sourceFile="$(Build.ArtifactStagingDirectory)\AboutSite.zip"
$destFile="$(Build.BinariesDirectory)\web.config"

Add-Type -Assembly System.IO.Compression.FileSystem
$zip = [IO.Compression.ZipFile]::OpenRead($sourceFile)
$zip.Entries | where {$_.Name -like 'web.config'} | foreach {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $destFile, $true)}
$zip.Dispose()
Levi Lu-MSFT
  • 27,483
  • 2
  • 31
  • 43
  • Thank you! By $(myaddress) are you referring to the value of a variable defined in the build? – SK-USA Nov 11 '19 at 16:43
  • My bad- just noticed that you have already mentioned using Pipeline variables in both the tasks. – SK-USA Nov 11 '19 at 19:37
  • I guess I am missing something. I added "Magic Chunks" extension and it seems to be working. However, I do not see the results in the deployment. Giving the steps that I have added - `####[section]Starting: Release `####[section]Starting: Initialize job `####[section]Starting: Download artifact - _ Build - drop `####[section]Starting: Config transform - **\web.config `####[section]Starting: IIS Web App Manage `####[section]Starting: IIS Web App Deploy `####[section]Starting: Finalize Job – SK-USA Nov 11 '19 at 20:35
  • you can go to your build pipeline to check if the artifact is packaged to a single zip file. If it is a zip file, it needs to be unzipped before config transform. Or the web config file can not be detected. – Levi Lu-MSFT Nov 12 '19 at 05:17
  • As of now I have used a workaround where I am copying another web.config (using an inline powershell script). I was wondering if I could do the replacement of the variables after the package is unzipped and deployed so that I don't need to unzip (otherwise the unzip will be run two times). – SK-USA Nov 16 '19 at 12:11
  • @Sk-USA, I think you can use Kudu API to do the replacement after the deployment. Please check my update. – Levi Lu-MSFT Nov 18 '19 at 01:55
  • I am not sure if we are on the same page here. I have been able to replace the web.config file with another file. However, I will try out different approaches and keep you posted. I truly appreciate your help and attention. – SK-USA Nov 18 '19 at 15:33
  • Is it possible for you to share screenshots for Unzip task? I tried unzip using this extension task https://marketplace.visualstudio.com/items?itemName=YodLabs.UnzipTask. I specified "Zip file path": $(System.DefaultWorkingDirectory)\**\Build.WebUI.zip and "Extract Pattern Filter": **/web.config and "Destination folder": $(System.DefaultWorkingDirectory)\_Build I get this error unzipping C:\azagent\A5\_work\r2\a\**\Build.WebUI.zip using pattern **/web.config to folder C:\azagent\A5\_work\r2\a\_Build 2019-11-18T16:36:13.7580216Z ##[error]zip file not found – SK-USA Nov 18 '19 at 16:45
  • My apologies - however, I think this is to do with the edit function in SO - repeating the line below - (I have put this as code line - so should display correctly now) `$(System.DefaultWorkingDirectory) \**\USAPlants.WebUI.zip` `unzipping C:\azagent\A5\_work\r2\a\**\USAPlants.WebUI.zip using pattern **/web.config to folder C:\azagent\A5\_work\r2\a\_USA Plants Build` – SK-USA Nov 19 '19 at 14:54
  • I failed to make unzip task working even if i specified the exact zip file path, i cannot figure out what is the right `extract pattern filter`. I end up writing a powershell script to extract the web.config. I updated my powershell script to above answer. – Levi Lu-MSFT Nov 20 '19 at 08:21
  • Thanks, I will try this out - I keep thinking that Azure is making this far harder than it should be .... – SK-USA Nov 20 '19 at 13:46
  • When you responded initially - you mentioned that you got the web.config replacement to work using MagicChunks - at that time - how did you accomplish that? – SK-USA Nov 20 '19 at 13:53
  • I finally got this working! Here is what I did a. Used a PowerShell script to copy web.config to a temp folder b. Used the RegEx find and Replace extension for replacing each variable (I had to use the extenstion 5 times once for each var) c. Copy web.config from temp folder back to the website. Before this, I tried a. Unzip - I customized your script as my package contains more than web.config file. I got it work in my local however, got an error in the server. b. using MagicChunks, however, I noticed that it inserts a duplicate set of lines in the file. Thank you for everything. – SK-USA Nov 20 '19 at 22:16
  • Here is the error that I got during Unzip Unable to find type [IO.Compression.sourceFile]. Make sure that the assembly that contains this type is loaded. – SK-USA Nov 20 '19 at 22:16