{"id":14354,"date":"2016-03-28T05:25:25","date_gmt":"2016-03-28T05:25:25","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/?p=14354"},"modified":"2019-02-14T17:36:13","modified_gmt":"2019-02-15T01:36:13","slug":"implement-rollback-with-release-management-for-tfs-2015","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/implement-rollback-with-release-management-for-tfs-2015\/","title":{"rendered":"Implement Rollback with Release Management for TFS 2015"},"content":{"rendered":"<p>When a deployment fails, it is likely to leave an environment in an unhealthy state. A rollback strategy is required to get the\u00a0environment back to a healthy state.\nThere are various options that can be considered as a rollback strategy.<\/p>\n<ol>\n<li><strong>Option#1<\/strong> : Undo the change by redeploying the previous release\nThe first option is to simply redeploy the previously successful release. This might work well for standalone applications.\nWhenever an application depends on some external services or has a database involved, this approach does not work well. \u00a0The dependent services might have upgraded and no longer compatible with the previous release. \u00a0The database might have changed the schema making the previous release no longer healthy.<\/li>\n<li><strong>Option#2<\/strong> : Fix the issue, do another release\nThe second option\u00a0is to simply do nothing. Something went wrong, troubleshoot it and fix it. Once we fix the issue, we can do another release.\nThis however means the environment would\u00a0remain unhealthy for some time, as long as it takes for the fix to be ready and deployed.<\/li>\n<li><strong>Option#3<\/strong> : Understand what failed in the deployment and make a temporary change for the time being\nBoth the above options are both valid approaches but with some limitations. That brings us to a third option. While the fix is getting ready (option 2), make a minimum change to the environment to get it temporarily healthy.<\/li>\n<\/ol>\n<p>We&#8217;re almost talking about option 2 being a major\/minor release and option 3 being a hotfix like change to the application.<\/p>\n<p>Let us look at how to implement option 3 using release management.<\/p>\n<h3>Requirements<\/h3>\n<p>A deployment to an environment might fail when any of the tasks in the deployment workflow fails. In order to get the environment healthy again, we&#8217;ll look to execute a rollback script. The script itself would have the following requirement.<\/p>\n<ul>\n<li>Execute the script\u00a0for the environment even when another task has failed.\nWith release management for Team Services, you can look to achieve this using a powershell task and mark it &#8220;Always Run&#8221;. This way the script shall always get executed, irrespective of the deployment being successful or failed.\nAny of the tasks that are not marked &#8220;always run&#8221; shall be skipped in case a preceding task failed, but the always run task would be executed.<\/li>\n<\/ul>\n<ul>\n<li>Make selective changes to the environment based on the task that failed in the deployment.\nHaving the script executed always is only half the task. In order to avoid undoing anything that&#8217;s not required, we&#8217;ll need to know a bit more. First of all, we&#8217;ll need to detect if there was a failure at all. In case there was a failure, then what task failed.\nCurrently, there isn&#8217;t a way to know about these in the script. We&#8217;ll need to query the release from within the script for these. &#8220;Rollback powershell&#8221; task in the <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms-devlabs.utilitytasks\" target=\"_blank\">Release Management Utility Tasks <\/a>extension makes this possible.<\/li>\n<\/ul>\n<h3>Implementing rollback script<\/h3>\n<p>Rollback powershell task helps you understand the history of the current deployment. An environment variable Release_Tasks is set before the rollback powershell script is run.\nIn the script, you&#8217;ll need\u00a0to parse the value of Release_Tasks and include the rollback logic accordingly.<\/p>\n<p>An example to access the task execution information is as follows.<\/p>\n<p style=\"padding-left: 60px\">try\n{<\/p>\n<p style=\"padding-left: 90px\">$jsonobject = ConvertFrom-Json $env:Release_Tasks<\/p>\n<p style=\"padding-left: 60px\">}\ncatch\n{<\/p>\n<p style=\"padding-left: 90px\">Write-Verbose -Verbose &#8220;Error parsing Release_Tasks environment variable&#8221;\nWrite-Verbose -Verbose $Error<\/p>\n<p style=\"padding-left: 60px\">}<\/p>\n<p style=\"padding-left: 60px\">foreach ($task in $jsonobject | Get-Member -MemberType NoteProperty)\n{<\/p>\n<p style=\"padding-left: 90px\">$taskproperty = $jsonobject.$($task.Name) | ConvertFrom-Json\nWrite-Verbose -Verbose &#8220;Task $($taskproperty.Name) with rank $($task.Name) has status $($taskproperty.Status)&#8221;\n\/\/ Perform rollback action required in case $task.Name has status failed<\/p>\n<p style=\"padding-left: 60px\">}<\/p>\n<h3>Adding rollback task to deployment workflow<\/h3>\n<p>Once you install the <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms-devlabs.utilitytasks\" target=\"_blank\">Release Management Utility Tasks <\/a>extension\u00a0in your account, you&#8217;ll see a new task called &#8220;Rollback powershell&#8221; in the task catalog. For rollback, you&#8217;ll need to add this task to the workflow and mark it &#8220;always run&#8221;.<\/p>\n<h3>End to End Example<\/h3>\n<p>For an illustration here, we are going to take a simple example. The application deployment has two steps namely &#8220;deploy&#8221; i.e. copy static content from artifact to a folder and &#8220;configure&#8221; i.e. make config changes to point to the new location.\nWe&#8217;ll author rollback for cases when deploy fails i.e. copy the original files back.<\/p>\n<p>The environment definition shall be the following. TargetFolderName is a configuration variable indicating the target folder for the application.<\/p>\n<ul>\n<li>Backup &#8212; We&#8217;ll perform a backup of the original files to use for rollback later\n<ul>\n<li>BackupFolderName configuration variable is added to indicate the folder to be used for backup.<\/li>\n<li>PowerShell task is added with an inline script\u00a0to copy files from target folder to backup folder.<\/li>\n<li><img decoding=\"async\" src=\"\" alt=\"\" width=\"660\" height=\"182\" \/><\/li>\n<\/ul>\n<\/li>\n<li>Deploy &#8212; Copy latest files from artifact to the target folder\n<ul>\n<li>Powershell task is added with an inline script to deploy files from artifact to target folder<\/li>\n<li><img decoding=\"async\" src=\"\" alt=\"\" width=\"660\" height=\"153\" \/><\/li>\n<\/ul>\n<\/li>\n<li>Configure &#8212; Make configuration changes to the setup\n<ul>\n<li>Powershell task is added and a configure script is called from the artifacts<\/li>\n<li><img decoding=\"async\" src=\"\" alt=\"\" width=\"660\" height=\"152\" \/><\/li>\n<\/ul>\n<\/li>\n<li>Rollback &#8212; Rollback the files from backup in case Deploy failed. Delete backup before exiting.\n<ul>\n<li>Rollback powershell task is added to perform rollback of files if deploy task fails. Always run is enabled.<\/li>\n<li><img decoding=\"async\" src=\"\" alt=\"\" width=\"660\" height=\"152\" \/><\/li>\n<li>The inline script is as follows.<\/li>\n<li><img decoding=\"async\" src=\"\" alt=\"\" width=\"660\" height=\"329\" \/><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When a deployment fails, it is likely to leave an environment in an unhealthy state. A rollback strategy is required to get the\u00a0environment back to a healthy state. There are various options that can be considered as a rollback strategy. Option#1 : Undo the change by redeploying the previous release The first option is to [&hellip;]<\/p>\n","protected":false},"author":200,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[253,226,1],"tags":[],"class_list":["post-14354","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-devops-server","category-ci","category-devops"],"acf":[],"blog_post_summary":"<p>When a deployment fails, it is likely to leave an environment in an unhealthy state. A rollback strategy is required to get the\u00a0environment back to a healthy state. There are various options that can be considered as a rollback strategy. Option#1 : Undo the change by redeploying the previous release The first option is to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/14354","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/200"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=14354"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/14354\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=14354"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=14354"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=14354"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}