Web Deploy to Azure by convention

Octopus.Script exported 2015-11-03 by GeertvanHorrik belongs to ‘Web Deploy’ category.

Makes it super simple to deploy websites to different regions inside a single process.

This script assumes that you want to deploy websites like these to multiple regions:

  • playground.mydomain.com
  • status.mydomain.com

When you deploy to staging and production to 3 regions, this means that each website requires 3 (regions) * 2 (deployment slots) = 6 scripts. If you want this deployed using ms web deploy, you will need 6 * 5 = 30 variables (for a single website).

With this convention script you only need a few variables, but it requires some convention (mostly done by Azure anyway):

  • [prefix]-[websitename]-[region]
  • [prefix]-[websitename]-[region]-staging

So

  • mydomain-playground-eu-west
  • mydomain-playground-eu-west-staging

The following variables are required:

  • AzurePrefix
  • AzureName
  • AzurePassword-[region]
  • AzurePassword-[region]-staging

The password is required for each region and deployment slot, the rest is fully determined by convention.

Parameters

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

Website Name

WebsiteName

The name of the website (e.g. playground)

If you leave this empty, this field will use the AzureName variable.

Region Name

RegionName

The name of the region (e.g. eu-west)

Is Staging

IsStaging = False

Determines whether this is staging or not.

Prefix

Prefix =

The prefix. If you are smart, your websites look like this:

[prefix]-[websitename]-[region]

This allows you to deploy a lot of subdomains for a complete solution to multiple regions.

If you leave this empty, this field will use the AzurePrefix variable.

Package step name

WebDeployPackageStepName =

Name of the previously-deployed package step that contains the files that you want to deploy.

If you leave this empty, this field will default to ‘Extract package’

Script body

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

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Deployment")
# A collection of functions that can be used by script steps to determine where packages installed
# by previous steps are located on the filesystem.
 
function Find-InstallLocations {
    $result = @()
    $OctopusParameters.Keys | foreach {
        if ($_.EndsWith('].Output.Package.InstallationDirectoryPath')) {
            $result += $OctopusParameters[$_]
        }
    }
    return $result
}
 
function Find-InstallLocation($stepName) {
    $result = $OctopusParameters.Keys | where {
        $_.Equals("Octopus.Action[$stepName].Output.Package.InstallationDirectoryPath",  [System.StringComparison]::OrdinalIgnoreCase)
    } | select -first 1
 
    if ($result) {
        return $OctopusParameters[$result]
    }
 
    throw "No install location found for step: $stepName"
}
 
function Find-SingleInstallLocation {
    $all = @(Find-InstallLocations)
    if ($all.Length -eq 1) {
        return $all[0]
    }
    if ($all.Length -eq 0) {
        throw "No package steps found"
    }
    throw "Multiple package steps have run; please specify a single step"
}

function Test-LastExit($cmd) {
    if ($LastExitCode -ne 0) {
        Write-Host "##octopus[stderr-error]"
        write-error "$cmd failed with exit code: $LastExitCode"
    }
}

# Somehow we can only check for exactly 'True'
$isStagingText = $OctopusParameters['IsStaging'];
$isStaging = $isStagingText -eq "True"

Write-Host "Is staging text: $isStagingText"
Write-Host "Is staging: $isStaging"

$stepName = $OctopusParameters['WebDeployPackageStepName']
if ([string]::IsNullOrEmpty($stepName)) {
	Write-Host "Defaulting to step name Extract package"
	$stepName = "Extract package"
}

if ($isStaging) {
	$stepName = $stepName + " - staging"
}

$stepPath = ""
if (-not [string]::IsNullOrEmpty($stepName)) {
    Write-Host "Finding path to package step: $stepName"
    $stepPath = Find-InstallLocation $stepName
} else {
    $stepPath = Find-SingleInstallLocation
}
Write-Host "Package was installed to: $stepPath"

Write-Host "##octopus[stderr-progress]"
 
Write-Host "Publishing Website"

$prefix = $OctopusParameters['Prefix']
if ([string]::IsNullOrEmpty($prefix)) {
	Write-Host "Prefix is empty, reading prefix from variable set using AzurePrefix"
	$prefix = $OctopusParameters['AzurePrefix']
}

$websiteName = $OctopusParameters['WebsiteName']
if ([string]::IsNullOrEmpty($websiteName)) {
	Write-Host "WebsiteName is empty, reading website name from variable set using AzureName"
	$websiteName = $OctopusParameters['AzureName']
}

$regionName = $OctopusParameters['RegionName']

$publishUrl = "$prefix-$websiteName-$regionName"
if ($isStaging) {
	$publishUrl = $publishUrl + "-staging"
}
$publishUrl = $publishUrl + ".scm.azurewebsites.net:443"

$userName = '$' + "$prefix-$websiteName-$regionName"
if ($isStaging) {
	$userName = $userName + "__staging"
}

$passwordKey = "AzurePassword-$regionName"
if ($isStaging) {
	$passwordKey = $passwordKey + "-staging"
}

Write-Host "Using the following values to publish:"
Write-Host " * Publish url: $publishUrl"
Write-Host " * Website name: $websiteName"
Write-Host " * User name: $userName"
Write-Host " * Password variable: $passwordKey"

$destBaseOptions = new-object Microsoft.Web.Deployment.DeploymentBaseOptions
$destBaseOptions.UserName = $userName
$destBaseOptions.Password =  $OctopusParameters[$passwordKey]
$destBaseOptions.ComputerName = "https://$publishUrl/msdeploy.axd?site=$websiteName"
$destBaseOptions.AuthenticationType = "Basic"

$syncOptions = new-object Microsoft.Web.Deployment.DeploymentSyncOptions
#$syncOptions.WhatIf = $false
$syncOptions.UseChecksum = $true

$deploymentObject = [Microsoft.Web.Deployment.DeploymentManager]::CreateObject("contentPath", $stepPath)
$deploymentObject.SyncTo("contentPath", $websiteName, $destBaseOptions, $syncOptions)

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": "c3ff8c78-c1cd-43ea-aedb-f5ac7dac3352",
  "Name": "Web Deploy to Azure by convention",
  "Description": "Makes it super simple to deploy websites to different regions inside a single process.\n\nThis script assumes that you want to deploy websites like these to multiple regions:\n\n- playground.mydomain.com\n- status.mydomain.com\n\nWhen you deploy to staging and production to 3 regions, this means that each website requires 3 (regions) * 2 (deployment slots) = 6 scripts. If you want this deployed using ms web deploy, you will need 6 * 5 = 30 variables (for a single website).\n\nWith this convention script you only need a few variables, but it requires some convention (mostly done by Azure anyway):\n\n- [prefix]-[websitename]-[region]\n- [prefix]-[websitename]-[region]-staging\n\nSo\n\n- mydomain-playground-eu-west\n- mydomain-playground-eu-west-staging\n\nThe following variables are required:\n\n- AzurePrefix\n- AzureName\n- AzurePassword-[region]\n- AzurePassword-[region]-staging\n\nThe password is required for each region and deployment slot, the rest is fully determined by convention.",
  "Version": 29,
  "ExportedAt": "2015-11-03T00:25:05.516+00:00",
  "ActionType": "Octopus.Script",
  "Author": "GeertvanHorrik",
  "Parameters": [
    {
      "Name": "WebsiteName",
      "Label": "Website Name",
      "HelpText": "The name of the website (e.g. playground)\n\nIf you leave this empty, this field will use the _AzureName_ variable.",
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "RegionName",
      "Label": "Region Name",
      "HelpText": "The name of the region (e.g. eu-west)",
      "DefaultValue": null,
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "IsStaging",
      "Label": "Is Staging",
      "HelpText": "Determines whether this is staging or not.",
      "DefaultValue": "False",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Name": "Prefix",
      "Label": "Prefix",
      "HelpText": "The prefix. If you are smart, your websites look like this:\n\n[prefix]-[websitename]-[region]\n\nThis allows you to deploy a lot of subdomains for a complete solution to multiple regions.\n\nIf you leave this empty, this field will use the _AzurePrefix_ variable.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "WebDeployPackageStepName",
      "Label": "Package step name",
      "HelpText": "Name of the previously-deployed package step that contains the files that you want to deploy.\n\nIf you leave this empty, this field will default to 'Extract package'",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "[System.Reflection.Assembly]::LoadWithPartialName(\"Microsoft.Web.Deployment\")\n# A collection of functions that can be used by script steps to determine where packages installed\n# by previous steps are located on the filesystem.\n \nfunction Find-InstallLocations {\n    $result = @()\n    $OctopusParameters.Keys | foreach {\n        if ($_.EndsWith('].Output.Package.InstallationDirectoryPath')) {\n            $result += $OctopusParameters[$_]\n        }\n    }\n    return $result\n}\n \nfunction Find-InstallLocation($stepName) {\n    $result = $OctopusParameters.Keys | where {\n        $_.Equals(\"Octopus.Action[$stepName].Output.Package.InstallationDirectoryPath\",  [System.StringComparison]::OrdinalIgnoreCase)\n    } | select -first 1\n \n    if ($result) {\n        return $OctopusParameters[$result]\n    }\n \n    throw \"No install location found for step: $stepName\"\n}\n \nfunction Find-SingleInstallLocation {\n    $all = @(Find-InstallLocations)\n    if ($all.Length -eq 1) {\n        return $all[0]\n    }\n    if ($all.Length -eq 0) {\n        throw \"No package steps found\"\n    }\n    throw \"Multiple package steps have run; please specify a single step\"\n}\n\nfunction Test-LastExit($cmd) {\n    if ($LastExitCode -ne 0) {\n        Write-Host \"##octopus[stderr-error]\"\n        write-error \"$cmd failed with exit code: $LastExitCode\"\n    }\n}\n\n# Somehow we can only check for exactly 'True'\n$isStagingText = $OctopusParameters['IsStaging'];\n$isStaging = $isStagingText -eq \"True\"\n\nWrite-Host \"Is staging text: $isStagingText\"\nWrite-Host \"Is staging: $isStaging\"\n\n$stepName = $OctopusParameters['WebDeployPackageStepName']\nif ([string]::IsNullOrEmpty($stepName)) {\n\tWrite-Host \"Defaulting to step name Extract package\"\n\t$stepName = \"Extract package\"\n}\n\nif ($isStaging) {\n\t$stepName = $stepName + \" - staging\"\n}\n\n$stepPath = \"\"\nif (-not [string]::IsNullOrEmpty($stepName)) {\n    Write-Host \"Finding path to package step: $stepName\"\n    $stepPath = Find-InstallLocation $stepName\n} else {\n    $stepPath = Find-SingleInstallLocation\n}\nWrite-Host \"Package was installed to: $stepPath\"\n\nWrite-Host \"##octopus[stderr-progress]\"\n \nWrite-Host \"Publishing Website\"\n\n$prefix = $OctopusParameters['Prefix']\nif ([string]::IsNullOrEmpty($prefix)) {\n\tWrite-Host \"Prefix is empty, reading prefix from variable set using AzurePrefix\"\n\t$prefix = $OctopusParameters['AzurePrefix']\n}\n\n$websiteName = $OctopusParameters['WebsiteName']\nif ([string]::IsNullOrEmpty($websiteName)) {\n\tWrite-Host \"WebsiteName is empty, reading website name from variable set using AzureName\"\n\t$websiteName = $OctopusParameters['AzureName']\n}\n\n$regionName = $OctopusParameters['RegionName']\n\n$publishUrl = \"$prefix-$websiteName-$regionName\"\nif ($isStaging) {\n\t$publishUrl = $publishUrl + \"-staging\"\n}\n$publishUrl = $publishUrl + \".scm.azurewebsites.net:443\"\n\n$userName = '$' + \"$prefix-$websiteName-$regionName\"\nif ($isStaging) {\n\t$userName = $userName + \"__staging\"\n}\n\n$passwordKey = \"AzurePassword-$regionName\"\nif ($isStaging) {\n\t$passwordKey = $passwordKey + \"-staging\"\n}\n\nWrite-Host \"Using the following values to publish:\"\nWrite-Host \" * Publish url: $publishUrl\"\nWrite-Host \" * Website name: $websiteName\"\nWrite-Host \" * User name: $userName\"\nWrite-Host \" * Password variable: $passwordKey\"\n\n$destBaseOptions = new-object Microsoft.Web.Deployment.DeploymentBaseOptions\n$destBaseOptions.UserName = $userName\n$destBaseOptions.Password =  $OctopusParameters[$passwordKey]\n$destBaseOptions.ComputerName = \"https://$publishUrl/msdeploy.axd?site=$websiteName\"\n$destBaseOptions.AuthenticationType = \"Basic\"\n\n$syncOptions = new-object Microsoft.Web.Deployment.DeploymentSyncOptions\n#$syncOptions.WhatIf = $false\n$syncOptions.UseChecksum = $true\n\n$deploymentObject = [Microsoft.Web.Deployment.DeploymentManager]::CreateObject(\"contentPath\", $stepPath)\n$deploymentObject.SyncTo(\"contentPath\", $websiteName, $destBaseOptions, $syncOptions)"
  },
  "Category": "Web Deploy",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/web-deploy-azure-convention.json",
  "Website": "/step-templates/c3ff8c78-c1cd-43ea-aedb-f5ac7dac3352",
  "Logo": "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",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Tuesday, November 3, 2015