Showing posts with label deployment. Show all posts
Showing posts with label deployment. Show all posts

Friday, June 1, 2018

Patching Sitecore web.config on Azure using VSTS WebApp deploy

With Sitecore, it's a best practice to not copy the web.config to your project, but use transformations. This is a really nice idea, but when deploying Sitecore using the ARM templates to Azure and apply your solution on top of it, you cannot edit the web.config. With the solution below I want to show how to apply config transformations on Azure using the VSTS Web App Service Deploy task. The method is kinda easy once you know how to do it.

First, add the code from configtransfrom to your App_Data\tools folder, the binaries and postdeployment command are stored here. Secondly add a web.azure.config to the project, with the build action set to Content. Lastly, update the release definition and add the postdeployment task to the Web App Service Deploy.



The line in the postdeploy.cmd that does the magic is:
"%WEBROOT_PATH%\App_Data\tools\configtransform\SlowCheetah.Xdt.exe" "%WEBROOT_PATH%\web.config" "%WEBROOT_PATH%\web.azure.config" "%WEBROOT_PATH%\web.config"

To see all other available environment variables run 'set' from the kudu console.

Offcourse the source is available on Github: https://github.com/luuksommers/sitecore-azure-configtransform

Happy transforming!
Luuk

Friday, April 6, 2018

Transforming Unicorn files in a release pipeline using YmlTransform



When you use an automated deployment to different environments that also need changes in unicorn files (without having to update the sitecore configuration manually) you can use YmlTransform. This is an easy tool that uses an input Json file to update unicorn files before copying them to the server. Together with the ReplaceTokens task this is a very powerfull solution.

Our deployment process looks like this before we publish the web application to Azure.

First you'll need to create a Json file containing the fields you want to replace, it currently supports shared and language fields. In our case we call it unicorn.ymltransform with the following content:
[
    {
        "FieldId": "379de7bc-88f2-42ae-8d4a-50dd0b8796ea",
        "Languages": "",
        "Path": "/sitecore/content/Home/Item1",
        "Type": "Shared",
        "Value": "#{ApiUrl1}#"
    },
    {
        "FieldId": "379de7bc-88f2-42ae-8d4a-50dd0b8796ea",
        "Languages": "*",
        "Path": "/sitecore/content/Home/Item2",
        "Type": "Shared",
        "Value": "#{ApiUrl2}#"
    },
    {
        "FieldId": "86ee9731-e7fb-47c9-bab6-5cb282c3a920",
        "Languages": "*",
        "Path": "/sitecore/content/Home/Item3",
        "Type": "Shared",
        "Value": "#{OtherSetting}#"
    }
]

When you parse this file through the ReplaceTokens and run it over your *.ymltransform files, the unicorn files will be transformed using the actual value from the VSTS variables (which could also be loaded from a keyfault).

In the next step you can run a command with the following settings to transform the actual unicorn files:
ymltransform.exe -p "App_Data/unicorn" -r -t "unicorn.ymltransform" 

The output of this command:
2018-04-06T06:28:47.6709328Z Updating file D:\a\r1\a\TestProject\drop\artifacts\Website\App_Data/unicorn\Project\serialization\Content\Home\Item1.yml section Shared id 379de7bc-88f2-42ae-8d4a-50dd0b8796ea to https://apiurl1.com
2018-04-06T06:28:47.6711423Z Transformed: D:\a\r1\a\TestProject\drop\artifacts\Website\App_Data/unicorn\Project\serialization\Content\Home\Item1.yml
2018-04-06T06:28:47.7732198Z Updating file D:\a\r1\a\TestProject\drop\artifacts\Website\App_Data/unicorn\Project\serialization\Content\Home\Item2.yml section Shared id 379de7bc-88f2-42ae-8d4a-50dd0b8796ea to https://apiurl2.com
2018-04-06T06:28:47.7735015Z Transformed: D:\a\r1\a\TestProject\drop\artifacts\Website\App_Data/unicorn\Project\serialization\Content\Home\Item2.yml
2018-04-06T06:28:47.9817169Z Updating file D:\a\r1\a\TestProject\drop\artifacts\Website\App_Data/unicorn\Project\serialization\Content\Home\Item3.yml section Shared id 86ee9731-e7fb-47c9-bab6-5cb282c3a920 to HelloWorld
2018-04-06T06:28:47.9819775Z Transformed: D:\a\r1\a\TestProject\drop\artifacts\Website\App_Data/unicorn\Project\serialization\Content\Home\Item3.yml

Now the yml files contain the correct information for your environment, you can upload the yml files and run a unicorn sync (automatically).

The full sourcecode is available on Github:
https://github.com/luuksommers/ymltransform 

Happy transforming!
Luuk

Friday, March 23, 2018

Using the Sitecore bootloader to add Redis to an Sitecore 8.2 XP0 installation

The Sitecore bootloader is a nifty little-underdocumented thing that can be used to easily extend a Sitecore installation. When you'll install EXM using the web deploy packages, you'll notice that it has to add some connection strings to the ConnectionStrings.config, but you cannot modify that file without restarting the application. So I was wondering, how does that work.
It appears that the bootloader scans directories and can apply xdt transforms to all configs. Just by placing a file called ConnectionStrings.config.xdt on the Azure WebApp in the following folder: App_Data\Transforms\Redis\Xdts\App_Config, the bootloader will try to match the filename without xdt and run the transformation. So the path after Xdts should match the folder structure from your site root.
The Redis package does exactly the same: I've created a WebDeploy package containing this file, so we can deploy Redis to Sitecore without any modifications to the Sitecore installation beforehand.

The content of the xdt file:
<?xml version="1.0"?>
<connectionStrings xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
 <add name="redis.sessions" connectionString="Redis Connection String" xdt:Transform="Insert" />
</connectionStrings>

By adding a parameter to the web deploy package called 'Redis ConnectionString' we can now push the Redis connection string to the web deployment package.
{
  "name": "[concat(variables('singleWebAppNameTidy'), '/', 'MSDeploy')]",
  "type": "Microsoft.Web/sites/extensions",
  "location": "[parameters('location')]",
  "apiVersion": "[variables('webApiVersion')]",
  "properties": {
    "addOnPackages": [
      {
        "packageUri": "[parameters('redisMsDeployPackageUrl')]",
        "setParameters": {
          "Application Path": "[variables('singleWebAppNameTidy')]",
          "Redis Connection String": "[concat(reference(resourceId('Microsoft.Cache/Redis', 
                   variables('redisCacheNameTidy')), variables('redisApiVersion')).hostName, ':', reference(resourceId('Microsoft.Cache/Redis', 
                   variables('redisCacheNameTidy')), variables('redisApiVersion')).sslPort, ',password=', listKeys(resourceId('Microsoft.Cache/Redis', 
                   variables('redisCacheNameTidy')), variables('redisApiVersion')).primaryKey, ',ssl=True,abortConnect=False')]"
        }
      }
    ]
  }
}

During the first hit of the site, the bootloader will scan the App_Data\Transforms directory. The bootloader then runs an installer in a separated process on the Web App to apply the transformation.

Supporting code:
https://github.com/luuksommers/sitecore-xp0-redis

Happy caching!
Luuk