Automate deploy of Machine Key in a shared config IIS - azure-devops

I'm using Azure DevOps to deploy an ASP.NET application to an IIS servers on-prem. The IIS servers are using a shared configuration so they need a custom Machine Key setup.
I can use XML transform to add add the machineKey entry in the Web.Config
<system.web>
<machineKey decryptionKey="{hex-key value}" validationKey="{hex-key value}"/>
</system.web>
but I don't want to have the actual keys in source control so I'll need to replace those values at deploy time. Substitution is easy enough for appsettings and connection strings but how can I substitute values in the System.Web section of the Web.Config?

How can I substitute values in the System.Web section of the
Web.Config?
What about consider to use one extension Replace token? For why I recommend it is because it can achieve the demand that it can only be replaced during the pipeline running.
Also, its usage is very convenient. Just need to specify the prefix and suffix in the task, and then make apply them in to your web.config file.
Then specify the corresponding variables with same name in Variables tab.
Only this, during the pipeline running, the task could find the corresponding token correctly and replace the value into it.
For detailed steps, you could refer to my previous answer for details: Use replace token task.

Related

Access agent hostname for a build variable

I've got release pipelines defined that have worked. I've got a config transform that will write a API url to a config file (currently with a hardcoded api url).
What I'd like to do is be able to have the config be re-written based on the agent its being deployed on.
eg. if the machine being deployed to is TEST-1, I'd like to write https://TEST-1.somedomain.com/api into a config using that transform step.
The .somedomain.com/api can be static.
I've tried modifying the pipeline variable's value to be https://${{Environment.Name}}.somedomain.com/api, but it just replaces the API_URL in the config with that literal string (does not populate machine name in that variable).
Being that variables are the source of value that is being written to configs during the transform, I'm struggling to see another way to do this.
some gotchas
Using non yaml pipeline definitions (I know I saw people put logic in variable definitions within yaml pipelines)
Can't just use localhost, as the configuration is being read into a javascript rich app that would have js trying to connect to localhost vs trying to connect to the server.
I'm interested in any ways I could solve this problem
${{Environment.Name}} is not valid syntax for either YAML or classic pipelines.
In classic pipelines it would be $(Environment.Name).
In YAML, $(Environment.Name) or ${{ variables['Environment.Name'] }} would work.

Web.config variable update not working with Azure DevOps pipeline (File Transform)

I'm trying to use the task "File Transform" within my pipeline to modify a few values inside my web.config file during deployment.
I created the tasks as the following:
And in the pipeline, inside the variables, I set up the key & value that I want to replace in the XML file.
Everything seems to go fine, however, when I check the log, I see this
So, the file was simple skipped and the transformation didn't work.
The variable that I'm trying to modify in the web.config file has the following path inside the XML file
<aspNetCore>
<environmentVariables>
<environmentVariable name="x" value="y" />
</environmentVariables>
</aspNetCore>
</configuration>
I read the documentation multiples times, but it's not clear if I'm doing something wrong.
Please, could you provide some suggestion of what I need to check to make it work?
Thank you
According to the document about XML variable substitution:Variable substitution takes effect only on the applicationSettings, appSettings, connectionStrings, and configSections elements of configuration files. It does not apply to your environmentVariable element. It worked well on my side when I change value in appSettings element.
Please refer to the samples in the document about file transform.
I'm answering my own question.
Based on the comments that I received, the solution that I found was the following:
1- Use Replace Token Task (https://github.com/qetza/vsts-replacetokens-task#readme) in the pipeline AFTER the deployment. I also removed that "File Transform", since it wouldn't work for what I needed.
2- In the configuration, I pointed the root folder to the deployed application, no the Zip file, as instructed by this other question (Azure Dev ops replace tokens per environment in release pipeline)
3- In the web.config file, I used the token prefix and suffix, as suggested "#{token}#
4- Added the variables to the variable groups
After deploying, I checked that it worked fine.

Octopus Web.config transforms for client endpoint address

I have a web project that has uses two service endpoints located in the Web.config file under the client --> endpoint --> address portion
I have found the following per Octopus Variables section but cannot seem to find any reference of how to address the changes using and actual variable like you normally would
I am using the webui for Octopus which would be
http://{server-name}/app#/projects/{project-name}/variables
variable-substitution-syntax
I attempted assigning the variables like so, but the values never updated
the original entries look like the following
<endpoint address="http://services-test.example.com/test.svc/soap" binding="basicHttpBinding" bindingConfiguration="soap" contract="test.service" name="soap" />
Name Address Instance
Endpoint[A].Address test-service-a.example.com 1
Endpoint[B].Address test-service-b.example.com 2
Is this something that is ever possible using Octopus Variables? (I know it can be done using regular Web.config Transforms, as we are doing that already).
If it is possible what is would the correct replacement value for the
endpoint address
be and how would I accomplish this for multiple different endpoint addresses?
Sounds like you are most of the way there. If it's already working with your Web.config transforms then all you need to do is replace the value IN the transform with the variable replacement token.
For example: Web.Release.Config
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.serviceModel>
<client>
<endpoint address="http://#{Server1}/test.svc/soap" name="x1"
xdt:Locator="Match(name)" xdt:Transform="SetAttributes(address)" />
<endpoint address="#{Endpoint2}" name="x2"
xdt:Locator="Match(name)" xdt:Transform="SetAttributes(address)" />
</client>
</system.serviceModel>
</configuration>
Of course there are lots of options here.
For filenames you could stick with default conventions 'Web.Release.config' or go with 'Web.[Environment].config' or go with something custom. We use 'Web.Octopus.Config' so that it wont get picked up by any other process.
More on naming transforms here: https://octopus.com/docs/deploying-applications/configuration-files#Configurationfiles-Namingconfigurationtransformfiles
More on custom transforms (Web.Octopus.com) here: https://octopus.com/docs/deploying-applications/configuration-files#Configurationfiles-AdditionalConfigurationTransforms
For variables, you could define a variable for just the server (name=x1) which is simpler or just put the whole address in a variable with gives Octopus a lot more control (name=x2).
The key part is getting the variable replacement tokens into the config. Octopus runs the variable substitution on config files first, and then runs the transforms. What that means is the first pass will replace the tokens in your Web.Release.Config, and then Octopus will run the transforms against Web.config
Hope that helps.

Different Endpoint Certificates Per Environment in Service Fabric

I have a service fabric application that exposes an SSL endpoint. I would like to use a different certificate based on the environment. I'm trying to do this with parameters in the ApplicationMainfest.xml file in the same way that I specify other things, such as instance counts. However, parameters appear not to be working for this. I'm wondering if this is actually true and if there are certain things that you cannot parameterize. Also, is there any way to specify a different certificate based on the environment?
Here are the relevant pieces from my application manifest:
<Parameter Name="CERTNAME" DefaultValue="MyCert" />
...
<Certificates>
<EndpointCertificate X509FindValue="..." Name="MyCert" />
<EndpointCertificate X509FindValue="..." Name="SVSSL" />
</Certificates>
<Policies>
<EndpointBindingPolicy EndpointRef="ServiceEndpointHttps" CertificateRef="[CERTNAME]" />
</Policies>
On deployment, I get the following error:
Register-ServiceFabricApplicationType : The CertificateRef '[CERTNAME]' in EndpointBindingPolicy is invalid. There is no matching Certificate in the corresponding ApplicationManifest.
Today the certificate value itself is parameterizable but not the Ref. So instead of changing the reference or the name, you would parameterize the X509FindValue and keep the endpointbindingpolicy the same.
As a note, just any time you run into something you want to parameterize but can't figure out how to do it, there are a few options. Consider for example most things in the Service Manifest, like the port that the service listens on (if you have it statically configured). There are some other ways around this:
Create different manifests (service manifests or application manifests) and replacing them when creating the application package for a given environment
Using something during your build/deployment stages (such as the Tokenizer Task in VSTS) to replace a stub value with the actual value given the environment that the package is being crafted for
Move most of the endpoint configuration stuff to settings.xml and replace those values via the normal application parameter/override behavior. This would mean taking on the work of configuring your endpoints yourself, however.

Deploying SSAS cube to environments

We are using BIDS 2008 locally (on our workstations) to develop our OLAP objects/cube. Come the time of promotion to Development we can deploy via BIDS. However when a hands-off deployment is required (eg. to UAT or Live) we are generating an XMLA file. This (the generated XMLA file) of course contains environment specific information (eg server name, database name, etc). If we would like to automate the generation of the XMLA file for deployment to each environment, is there a config type process to parameterise these values (like .NET : web.config : appSettings or SSIS : dtsConfig).
Note we could parse the XMLA file and replace these values depending on the environment (eg. via xmlpoke), but this is a little messy and depends on XML path structure, and hence would rather avoid this approach
This should point you in the right direction: http://blog.kejser.org/2006/11/28/automating-build-of-analysis-services-projects/
Here's more on the deployment utility and command line switches: http://msdn.microsoft.com/en-us/library/ms162758(v=sql.105).aspx
before using Micrsoft.analysisservice.deplyement to generate the XMLA file to deply in an AS istance, we need update the files bellows to change all connection string, deployment option,
project.asdatabase
project.deploymenttargets
project.configsettings
project.deploymentoptions
regards,