Switch Azure Staging Deployment Slot

Octopus.AzurePowerShell exported 2018-03-14 by MarkDordoy belongs to ‘Azure’ category.

This template will warm up your deployment slot then swap it with production. This step template should be placed after ""Deploy an Azure Web App” Octopus Deploy template and be used with its sister step “Create Azure RM Deployment Slot”

This should be used for green-blue deployments, as referenced in this document: https://octopus.com/docs/deploying-applications/deploying-to-azure/deploying-a-package-to-an-azure-web-app/using-deployment-slots-with-azure-web-apps

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

ResourceGroupName

ResourceGroupName =

Enter the name of the resource group you are deploying this Web App into

AppName

AppName =

Enter the name of your app

AzureAccount

AzureAccount =

Enter the SPN used to connect to Azure

SlotName

SlotName =

Enter the name you wish to call your deployment slot

SmokeTestResponseCode(Optional)

SmokeTestResponseCode = 200

This is the response code that comes back from your web app. The default value is set to 200, if your app will respond with a different status code such as a 401 then please update the value.

smokeTestTimeoutSecs(Optional)

smokeTestTimeoutSecs = 180

The timeout setting for waking up your web app. The default value is 180 seconds.

Script body

Steps based on this template will execute the following undefined script.

###############################################
# Switch Azure RM Staging Deployment Slot
###############################################
###############################################
##Step1: Get Variables
$ResourceGroupName             = $OctopusParameters["ResourceGroupName"] 
$AppName                       = $OctopusParameters["AppName"] 
$StagingSlotName               = $OctopusParameters["SlotName"]
$SmokeTestResponseCode         = $OctopusParameters["SmokeTestResponseCode"]
$smokeTestTimeoutSecs          = $OctopusParameters["smokeTestTimeoutSecs"]
###############################################
###############################################
$ErrorActionPreference = "Stop"

Function Invoke-RequiredVariablesCheck
{
    if([string]::IsNullOrEmpty($ResourceGroupName))
    {
        Write-Error "ResourceGroupName variable is not set"
    }

    if([string]::IsNullOrEmpty($AppName))
    {
        write-error "AppName variable is not set"
    }

    if([string]::IsNullOrEmpty($stagingSlotName))
    {
        write-error "stagingSlotName variable is not set"
    }

    if([string]::IsNullOrEmpty($smokeTestTimeoutSecs))
    {
        Write-Output "Smoke test timeout not set, will use default of 180 seconds"
        $smokeTestTimeoutSecs = 180
    }

    if([string]::IsNullOrEmpty($SmokeTestResponseCode))
    {
        Write-Output "Smoke test respose code not specfied will detail to 200"
        $SmokeTestResponseCode = "200"
    }

    Write-Verbose "Variables in use are:"
    write-verbose "ResourceGroupName:$ResourceGroupName"
    write-verbose "AppName:$AppName"
    write-verbose "stagingSlotName:$stagingSlotName"
    Write-Verbose "smokeTestTimeoutSecs: $smokeTestTimeoutSecs"
    Write-Verbose "SmokeTestResponseCode: $SmokeTestResponseCode"
}

Function Invoke-SlotWarmup
{
    [cmdletbinding()]
    param
    (
        [parameter(Mandatory=$true)]
        [string]$httpEndpoint,
        [parameter(Mandatory=$true)]
        [int32]$timeout
    )
    try 
    {
        $response = (Invoke-WebRequest -UseBasicParsing -Uri $httpEndpoint -TimeoutSec $timeout).statusCode
    }
    catch 
    {
        $response = $_.Exception.Response.StatusCode.Value__
    }
    return $response
}

try 
{
    Invoke-RequiredVariablesCheck
    Write-Output "Will attempt to warm up staging slot"
    $slotDetails = Get-AzureRmWebAppSlot -ResourceGroupName $ResourceGroupName -Name $AppName -Slot $StagingSlotName
    
    $hostname = $slotDetails.EnabledHostNames | select-object -First 1

    Write-Output "Performing default smoke test to warm up deployment slot"
    
    $returnStatusCode = Invoke-SlotWarmup -httpEndpoint "https://$hostname" -timeout $smokeTestTimeoutSecs

    if($returnStatusCode -ne $SmokeTestResponseCode)
    {
        Write-Error "Response code to https://$hostname was $returnStatusCode and did not match the expected response code of $SmokeTestResponseCode. Deployment canceled"
    }
    else 
    {
        Write-Output "Staging slot (https://$hostname) warmed up and responding ok"
    }

    Write-Output "Will now switch staging slot to production"
    Switch-AzureRmWebAppSlot -ResourceGroupName $ResourceGroupName -Name $AppName -SourceSlotName $StagingSlotName -DestinationSlotName "Production"
    Write-Output "Deployment slot switch complete"
}
catch 
{
    Write-Error "Error in Switch Azure RM Staging Deployment Slot Script. $_"    
}

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "7c39a530-6d16-4294-8ff5-74663ea13131",
  "Name": "Switch Azure Staging Deployment Slot",
  "Description": "This template will warm up your deployment slot then swap it with production. This step template should be placed after \"\"Deploy an Azure Web App\" Octopus Deploy template and be used with its sister step \"Create Azure RM Deployment Slot\"\n\nThis should be used for green-blue deployments, as referenced in this document: https://octopus.com/docs/deploying-applications/deploying-to-azure/deploying-a-package-to-an-azure-web-app/using-deployment-slots-with-azure-web-apps",
  "Version": 3,
  "ExportedAt": "2018-03-14T16:21:25.214Z",
  "ActionType": "Octopus.AzurePowerShell",
  "Author": "MarkDordoy",
  "Parameters": [
    {
      "Id": "4eb022c3-2d12-4f5b-acb0-80eaec2ce26c",
      "Name": "ResourceGroupName",
      "Label": "ResourceGroupName",
      "HelpText": "Enter the name of the resource group you are deploying this Web App into",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      },
      "Links": {}
    },
    {
      "Id": "e44dbd73-6c0a-4c9f-b190-47396ea2534e",
      "Name": "AppName",
      "Label": "AppName",
      "HelpText": "Enter the name of your app",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      },
      "Links": {}
    },
    {
      "Id": "c66cc42c-88e6-4008-8289-a45913dc36df",
      "Name": "AzureAccount",
      "Label": "AzureAccount",
      "HelpText": "Enter the SPN used to connect to Azure",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      },
      "Links": {}
    },
    {
      "Id": "e9559ca6-751a-4939-888a-cbf76ce5c91d",
      "Name": "SlotName",
      "Label": "SlotName",
      "HelpText": "Enter the name you wish to call your deployment slot",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      },
      "Links": {}
    },
    {
      "Id": "ed1fd1cf-479a-4aa6-beb5-404565a51ca7",
      "Name": "SmokeTestResponseCode",
      "Label": "SmokeTestResponseCode(Optional)",
      "HelpText": "This is the response code that comes back from your web app. The default value is set to 200, if your app will respond with a different status code such as a 401 then please update the value.",
      "DefaultValue": "200",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      },
      "Links": {}
    },
    {
      "Id": "c906639e-f40d-4ab0-903c-d46462d8a8ae",
      "Name": "smokeTestTimeoutSecs",
      "Label": "smokeTestTimeoutSecs(Optional)",
      "HelpText": "The timeout setting for waking up your web app. The default value is 180 seconds.",
      "DefaultValue": "180",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      },
      "Links": {}
    }
  ],
  "Properties": {
    "Octopus.Action.Azure.AccountId": "#{AzureAccount}",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.ScriptBody": "###############################################\n# Switch Azure RM Staging Deployment Slot\n###############################################\n###############################################\n##Step1: Get Variables\n$ResourceGroupName             = $OctopusParameters[\"ResourceGroupName\"] \n$AppName                       = $OctopusParameters[\"AppName\"] \n$StagingSlotName               = $OctopusParameters[\"SlotName\"]\n$SmokeTestResponseCode         = $OctopusParameters[\"SmokeTestResponseCode\"]\n$smokeTestTimeoutSecs          = $OctopusParameters[\"smokeTestTimeoutSecs\"]\n###############################################\n###############################################\n$ErrorActionPreference = \"Stop\"\n\nFunction Invoke-RequiredVariablesCheck\n{\n    if([string]::IsNullOrEmpty($ResourceGroupName))\n    {\n        Write-Error \"ResourceGroupName variable is not set\"\n    }\n\n    if([string]::IsNullOrEmpty($AppName))\n    {\n        write-error \"AppName variable is not set\"\n    }\n\n    if([string]::IsNullOrEmpty($stagingSlotName))\n    {\n        write-error \"stagingSlotName variable is not set\"\n    }\n\n    if([string]::IsNullOrEmpty($smokeTestTimeoutSecs))\n    {\n        Write-Output \"Smoke test timeout not set, will use default of 180 seconds\"\n        $smokeTestTimeoutSecs = 180\n    }\n\n    if([string]::IsNullOrEmpty($SmokeTestResponseCode))\n    {\n        Write-Output \"Smoke test respose code not specfied will detail to 200\"\n        $SmokeTestResponseCode = \"200\"\n    }\n\n    Write-Verbose \"Variables in use are:\"\n    write-verbose \"ResourceGroupName:$ResourceGroupName\"\n    write-verbose \"AppName:$AppName\"\n    write-verbose \"stagingSlotName:$stagingSlotName\"\n    Write-Verbose \"smokeTestTimeoutSecs: $smokeTestTimeoutSecs\"\n    Write-Verbose \"SmokeTestResponseCode: $SmokeTestResponseCode\"\n}\n\nFunction Invoke-SlotWarmup\n{\n    [cmdletbinding()]\n    param\n    (\n        [parameter(Mandatory=$true)]\n        [string]$httpEndpoint,\n        [parameter(Mandatory=$true)]\n        [int32]$timeout\n    )\n    try \n    {\n        $response = (Invoke-WebRequest -UseBasicParsing -Uri $httpEndpoint -TimeoutSec $timeout).statusCode\n    }\n    catch \n    {\n        $response = $_.Exception.Response.StatusCode.Value__\n    }\n    return $response\n}\n\ntry \n{\n    Invoke-RequiredVariablesCheck\n    Write-Output \"Will attempt to warm up staging slot\"\n    $slotDetails = Get-AzureRmWebAppSlot -ResourceGroupName $ResourceGroupName -Name $AppName -Slot $StagingSlotName\n    \n    $hostname = $slotDetails.EnabledHostNames | select-object -First 1\n\n    Write-Output \"Performing default smoke test to warm up deployment slot\"\n    \n    $returnStatusCode = Invoke-SlotWarmup -httpEndpoint \"https://$hostname\" -timeout $smokeTestTimeoutSecs\n\n    if($returnStatusCode -ne $SmokeTestResponseCode)\n    {\n        Write-Error \"Response code to https://$hostname was $returnStatusCode and did not match the expected response code of $SmokeTestResponseCode. Deployment canceled\"\n    }\n    else \n    {\n        Write-Output \"Staging slot (https://$hostname) warmed up and responding ok\"\n    }\n\n    Write-Output \"Will now switch staging slot to production\"\n    Switch-AzureRmWebAppSlot -ResourceGroupName $ResourceGroupName -Name $AppName -SourceSlotName $StagingSlotName -DestinationSlotName \"Production\"\n    Write-Output \"Deployment slot switch complete\"\n}\ncatch \n{\n    Write-Error \"Error in Switch Azure RM Staging Deployment Slot Script. $_\"    \n}",
    "Octopus.Action.Package.FeedId": null,
    "Octopus.Action.Script.ScriptFileName": null,
    "Octopus.Action.Package.PackageId": null
  },
  "Category": "Azure",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/azure-switch-staging-deployment-slot.json",
  "Website": "/step-templates/7c39a530-6d16-4294-8ff5-74663ea13131",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRF////AHjXf7vrv931QJrh7/f8EIDaIIncMJHfYKvmz+b3n8zw3+76j8Ttr9XycLPpUKLkkKvYFAAABGZJREFUeNrsnNmCqjoQRc1MEiD8/9cer7Yt2KBJZQC8ez07sKlKTQlcLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzoUSnt8YxXlFuGHSbIaxvj+fip4btkLn1blkWLaF5v03yLhLOYlVuGYfMOMZzNGxCOzhjTJqFkXnjq3Dr1yyvPI3hGl3Ih3zzHHNKudRstRhX5O58vIcShY67Gq6EPIESlzUWvazaGAOGbvU7ArDu/g8M4o8opDZWvbvPzlL/MMBE8jT9T9W7PbAJlHPTBFRf9yVTEcs63msXz2UHLSgf650G/d5t+wjbxxB2UCMqGrk8/LFSD7uJMeNt5bcJCyQZyAe5Fo9KYfWS2flQrr4b4tpuzaeWjYs49rt9LHf9uZD7+VbyVi9EBNrjYjuq2sxQOrl+p+HuBVu45qvqfq691ttYFQ5KyKbyJgaIY/NGxrlWZwlwGvmvu1oY3PuAv0niTq6tZ78jk//9uc1r1r4lQki7y7sp2Tu4V1y2iLoqFTqi1lIGcpFiebrZNZ1dOkF0cCIlO8jQ47nCkam9Lilz9GhDF1I6XGLzfnhwDIIZVfI7+8SSgfHsijqXENOGJF5QorG4EcW0OrScqX/dDrXpr70Ut/BII+1OfECPuYz/NWxYmgrCsUskxPvyhgmrw+WGZ6lGTuOlIyCYWTFyWjpM5KIZRUIOwjRNYRQ6tZF9BXtk8hWAHPtLNJ727Fq0JSkC1FDRRF0Jalj0d5qVh2KEpM2TuSsCYTCT6ZkdmFYI9LrYp5QayWbo6NXlZwcRD/61pth5Fq5EX423QQxNjhqWvvklkljOLkYjrmphXPZOJOk6Pg7HKMsrtQKcowzZoK3rx1ZUelGMdQA/HaKkjAt2RgqpZeYqbNbH7Hp2ct4nqfSPOfe0ftiSTZJydOV6rG5bQbyLK+nRuCC0343PzDgiOXyQA5c14BTZi98uR/5KJ1SnatLdoO50WWBQZPTq0VgsklU3h932actuo17ayrHrb/3ykiegd3KbqF2wbV6RrlsJ07yLcpsWFTul9RyK6ZScr+tk7oNrFj0o7HQUlj4EiEvJ6rPLKSmlMZCrksl1OnLaRkxc+/HB1naMhNtT/6yM2bDs6azCRHrM3aVPN7aW8irD/10B8njpAMcsl8okXcdKrl4sPsLmQVy/Sj90ucPRc/d/Bxxj+dXSpCayen32D+hLi16MsIV8gfCXrYp6ySsiJKRUF0XXiLpVbFU+fNv4r7mOwhFsX4ZdwpSi1DYs2jb6ebZ9788cblTzMrYhu7sf/17IFdtuviJ2ioHA6pMHkoH4CLUeMBU7iGkxuM/YgcdderF9ibRdc7O982F1HpYhjfWUe+x5a6pjop9iNLfoePvlsdZdTSMwfxSmTY20Q0eHnUNzga1edeNmmqbg18aMVR1L9vwSXHF9TfIWBxpKLs2hj3eQeBC0USvp2HHF3eIkRdhFOd6ER8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/I/4J8AAo/80BciBec4AAAAASUVORK5CYII=",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Wednesday, March 14, 2018