Azure Windows - Install Octopus Tentacle

Octopus.AzurePowerShell exported 2022-02-09 by harrisonmeister belongs to ‘Azure’ category.

This step template will install the latest tentacle on an Azure hosted, Windows virtual machine. This will also open the firewall for inbound traffic on port 10933 on both the NSG and the the vm.


*note: expects the Azure CLI to be installed on the worker running this task*

Parameters

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

Azure Account

installWinTentacle.AzureAccount =

Azure account with permissions to the virtual machine in which to install the tentacle on

Azure Resource Group

installWinTentacle.azRgName =

The name of the resource group housing the NSG and VM

NSG Name

installWinTentacle.azNsgName =

The name of the azure network security group to create

Azure NSG Rule Priority

installWinTentacle.azNsgRulePriority = 400

the priority to assign to the NSG rule created for the octopus tentacle. Defaults to 400

VM Name

installWinTentacle.azVmName =

The name of the virtual machine to target when

Server Thumbprint

installWinTentacle.octoServerThumb =

The Thumbprint of the octopus server

API Key

installWinTentacle.octoApiKey =

The API key used to configure the tentacle.

Roles

installWinTentacle.octopusRoles =

Roles to assign to this tentacle installation.
Note: Each role should be on it’s own line

Environments

installWinTentacle.octopusEnvironments =

Environments to assign this tentacle installation to.
Note: Each environment should be on its own line

Server Url

instrallTentacle.octoServerUrl = #{if Octopus.Web.ServerUri}#{Octopus.Web.ServerUri}#{else}#{Octopus.Web.BaseUrl}#{/if}

The server url to register the tentacle with. Defaults to the base url

Tentacle Type

installWinTentacle.tentacleType = TentaclePassive

Select between a listing or polling tentacle

Tentacle Host Name

installWinTentacle.tentacleHostName =

The host name to register the listening tentacles with. Octopus deploy server uses this value to reach out to the vm.
Note: Leave blank to automatically use assigned public IP address.

Port Number

installWinTentacle.portNumber = 10933

Port number used when installing and registering the tentacle. This port is also opened when installing a listening tentacle

Script body

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

$nsgName = $OctopusParameters["installWinTentacle.azNsgName"]
$resourceGroup = $OctopusParameters["installWinTentacle.azRgName"]
$nsgRulePriority = $OctopusParameters["installWinTentacle.azNsgRulePriority"]
$vmName = $OctopusParameters["installWinTentacle.azVmName"]
$serverUri = $OctopusParameters["instrallTentacle.octoServerUrl"]
$apiKey = $OctopusParameters["installWinTentacle.octoApiKey"]
$rolesRaw = $OctopusParameters["installWinTentacle.octopusRoles"]
$enviroRaw = $OctopusParameters["installWinTentacle.octopusEnvironments"]
$octoThumb = $OctopusParameters["installWinTentacle.octoServerThumb"]
$comStyle = $OctopusParameters["installWinTentacle.tentacleType"]
$hostname = $OctopusParameters["installWinTentacle.tentacleHostName"]
$portNumber = $OctopusParameters["installWinTentacle.portNumber"]

Write-Host "Parsing Parameters"

if([string]::IsNullOrEmpty($rolesRaw))
{
	throw "At least one role must be defined"
}

if([string]::IsNullOrEmpty($enviroRaw))
{
	throw "At least one environment must be defined"
}

$roles = ""
$rolesRaw -split "`n" | ForEach-Object { $roles += "--role $_ "}
$roles = $roles.TrimEnd(' ')

$environments = ""
$enviroRaw -split "`n" | ForEach-Object { $environments += "--environment $_ "}
$environments = $environments.TrimEnd(' ')

if($comStyle -eq "TentaclePassive")
{
	if([string]::IsNullOrEmpty($hostname))
    {
    	$hostname = az vm show -d -g $resourceGroup -n $vmName --query publicIps -o tsv
        $hostname = $hostname.Trim("`n")
    }
    
    $noListen = "--port $portNumber --noListen `"false`""
    $comStyle += " --publicHostName=`"$hostname`""
    $openFirewall = 'true'
}
else
{
	$noListen = "--noListen `"true`""
    $openFirewall = 'false'
}

if($openFirewall -eq 'true')
{
	Write-Host "Creating NSG Rule"
	az network nsg rule create --name "OctopusTentacle" --nsg-name $nsgName --priority $nsgRulePriority --resource-group $resourceGroup --direction Inbound --destination-port-ranges $portNumber
}

$remoteScript = @"
`$msiLocation = "`$env:TEMP\`$(new-guid).msi"

if(`$env:PROCESSOR_ARCHITECTURE -eq "x86") 
{
    `$downloadPath = "http://octopus.com/downloads/latest/OctopusTentacle"
}
else
{
    `$downloadPath = "http://octopus.com/downloads/latest/OctopusTentacle64"
}

Invoke-WebRequest -Uri `$downloadPath -OutFile `$msiLocation -UseBasicParsing

Start-Process `$msiLocation /quiet -Wait

Remove-Item `$msiLocation

"@

Write-Host "Installing tentacle on remote machine"

Set-Content -Value $remoteScript -Path ".\script.ps1"

$result = az vm run-command invoke --command-id RunPowerShellScript --name $vmName -g $resourceGroup --scripts "@script.ps1"

$result

$msg = (($result | convertfrom-json).value | where {$_.code -eq "componentstatus/stderr/succeeded"}).message

if(![string]::IsNullOrEmpty($msg))
{
	throw $msg
}

Write-Verbose "hostname: $hostname`noListen: $noListen"

$remoteScript = @"

cd "C:\Program Files\Octopus Deploy\Tentacle"

.\Tentacle.exe create-instance --instance "Tentacle" --config "C:\Octopus\Tentacle.config" --console
.\Tentacle.exe new-certificate --instance "Tentacle" --if-blank --console
.\Tentacle.exe configure --instance "Tentacle" --reset-trust --console
.\Tentacle.exe configure --instance "Tentacle" --home "C:\Octopus" --app "C:\Octopus\Applications" $noListen --console
.\Tentacle.exe configure --instance "Tentacle" --trust "$octoThumb" --console
if('$openFirewall' -eq 'true'){
	New-NetFirewallRule -DisplayName "Octopus Tentacle" -Direction Inbound -LocalPort $portNumber -Protocol TCP -Action Allow
}
.\Tentacle.exe register-with --instance "Tentacle" --server "$serverUri" --apiKey=$apiKey $roles $environments --comms-style $comStyle --force --console
.\Tentacle.exe service --instance "Tentacle" --install --start --console

"@

Write-Host "Configuring tentacle on remote machine"

Set-Content -Value $remoteScript -Path ".\script.ps1"

$result = az vm run-command invoke --command-id RunPowerShellScript --name $vmName -g $resourceGroup --scripts "@script.ps1"

$result

$msg = (($result | convertfrom-json).value | where {$_.code -eq "componentstatus/stderr/succeeded"}).message

if(![string]::IsNullOrEmpty($msg))
{
	throw $msg
}

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": "07b23f27-e76a-4b4b-acb1-017006a83269",
  "Name": "Azure Windows - Install Octopus Tentacle",
  "Description": "This step template will install the latest tentacle on an Azure hosted, Windows virtual machine. This will also open the firewall for inbound traffic on port 10933 on both the NSG and the the vm.\n<hr />\n*note: expects the Azure CLI to be installed on the worker running this task*",
  "Version": 4,
  "ExportedAt": "2022-02-09T15:56:03.173Z",
  "ActionType": "Octopus.AzurePowerShell",
  "Author": "harrisonmeister",
  "Packages": [],
  "Parameters": [
    {
      "Id": "dea51842-271f-48fa-901e-243488049f97",
      "Name": "installWinTentacle.AzureAccount",
      "Label": "Azure Account",
      "HelpText": "Azure account with permissions to the virtual machine in which to install the tentacle on",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "AzureAccount"
      }
    },
    {
      "Id": "6a97548c-3b97-4a19-8b9a-45aa58ac62d9",
      "Name": "installWinTentacle.azRgName",
      "Label": "Azure Resource Group",
      "HelpText": "The name of the resource group housing the NSG and VM",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "d9efb017-65c0-4010-b09f-0a6a34fc009f",
      "Name": "installWinTentacle.azNsgName",
      "Label": "NSG Name",
      "HelpText": "The name of the azure network security group to create ",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "36c6d441-9fe8-4ea2-957a-2135aa9d1687",
      "Name": "installWinTentacle.azNsgRulePriority",
      "Label": "Azure NSG Rule Priority",
      "HelpText": "the priority to assign to the NSG rule created for the octopus tentacle. Defaults to 400",
      "DefaultValue": "400",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "e4358aec-2798-412a-bcd2-1c7e41a0728d",
      "Name": "installWinTentacle.azVmName",
      "Label": "VM Name",
      "HelpText": "The name of the virtual machine to target when ",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "8dbe0a29-4e0f-43f8-8ef2-ae23a2884e85",
      "Name": "installWinTentacle.octoServerThumb",
      "Label": "Server Thumbprint",
      "HelpText": "The Thumbprint of the octopus server",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "a0859551-6c84-45d1-af2b-c57becb4e8ef",
      "Name": "installWinTentacle.octoApiKey",
      "Label": "API Key",
      "HelpText": "The API key used to configure the tentacle.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "dd07815d-bfb7-43b9-90f8-21ec5a2d2953",
      "Name": "installWinTentacle.octopusRoles",
      "Label": "Roles",
      "HelpText": "Roles to assign to this tentacle installation. <br />\n*Note: Each role should be on it's own line*",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    },
    {
      "Id": "d3ffb38e-7fcf-4547-be9a-6cd8e46f8e5e",
      "Name": "installWinTentacle.octopusEnvironments",
      "Label": "Environments",
      "HelpText": "Environments to assign this tentacle installation to.<br />\n*Note: Each environment should be on its own line*",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    },
    {
      "Id": "15150827-7bd3-4146-a798-66344851f602",
      "Name": "instrallTentacle.octoServerUrl",
      "Label": "Server Url",
      "HelpText": "The server url to register the tentacle with.  Defaults to the base url",
      "DefaultValue": "#{if Octopus.Web.ServerUri}#{Octopus.Web.ServerUri}#{else}#{Octopus.Web.BaseUrl}#{/if}",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "9bcd6bb5-2db3-453f-b4f6-6a78f3c39b59",
      "Name": "installWinTentacle.tentacleType",
      "Label": "Tentacle Type",
      "HelpText": "Select between a listing or polling tentacle",
      "DefaultValue": "TentaclePassive",
      "DisplaySettings": {
        "Octopus.ControlType": "Select",
        "Octopus.SelectOptions": "TentaclePassive|Listening\nTentacleActive|Polling"
      }
    },
    {
      "Id": "6bb98570-fe3e-4ab7-adfb-79ef7ce5c2ce",
      "Name": "installWinTentacle.tentacleHostName",
      "Label": "Tentacle Host Name",
      "HelpText": "The host name to register the listening tentacles with. Octopus deploy server uses this value to reach out to the vm.<br />\n*Note: Leave blank to automatically use assigned public IP address.*",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "7cbbafc4-5eed-41bd-ad9d-c1e67567a469",
      "Name": "installWinTentacle.portNumber",
      "Label": "Port Number",
      "HelpText": "Port number used when installing and registering the tentacle.  This port is also opened when installing a listening tentacle",
      "DefaultValue": "10933",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Azure.AccountId": "#{installWinTentacle.AzureAccount}",
    "Octopus.Action.Script.ScriptBody": "$nsgName = $OctopusParameters[\"installWinTentacle.azNsgName\"]\n$resourceGroup = $OctopusParameters[\"installWinTentacle.azRgName\"]\n$nsgRulePriority = $OctopusParameters[\"installWinTentacle.azNsgRulePriority\"]\n$vmName = $OctopusParameters[\"installWinTentacle.azVmName\"]\n$serverUri = $OctopusParameters[\"instrallTentacle.octoServerUrl\"]\n$apiKey = $OctopusParameters[\"installWinTentacle.octoApiKey\"]\n$rolesRaw = $OctopusParameters[\"installWinTentacle.octopusRoles\"]\n$enviroRaw = $OctopusParameters[\"installWinTentacle.octopusEnvironments\"]\n$octoThumb = $OctopusParameters[\"installWinTentacle.octoServerThumb\"]\n$comStyle = $OctopusParameters[\"installWinTentacle.tentacleType\"]\n$hostname = $OctopusParameters[\"installWinTentacle.tentacleHostName\"]\n$portNumber = $OctopusParameters[\"installWinTentacle.portNumber\"]\n\nWrite-Host \"Parsing Parameters\"\n\nif([string]::IsNullOrEmpty($rolesRaw))\n{\n\tthrow \"At least one role must be defined\"\n}\n\nif([string]::IsNullOrEmpty($enviroRaw))\n{\n\tthrow \"At least one environment must be defined\"\n}\n\n$roles = \"\"\n$rolesRaw -split \"`n\" | ForEach-Object { $roles += \"--role $_ \"}\n$roles = $roles.TrimEnd(' ')\n\n$environments = \"\"\n$enviroRaw -split \"`n\" | ForEach-Object { $environments += \"--environment $_ \"}\n$environments = $environments.TrimEnd(' ')\n\nif($comStyle -eq \"TentaclePassive\")\n{\n\tif([string]::IsNullOrEmpty($hostname))\n    {\n    \t$hostname = az vm show -d -g $resourceGroup -n $vmName --query publicIps -o tsv\n        $hostname = $hostname.Trim(\"`n\")\n    }\n    \n    $noListen = \"--port $portNumber --noListen `\"false`\"\"\n    $comStyle += \" --publicHostName=`\"$hostname`\"\"\n    $openFirewall = 'true'\n}\nelse\n{\n\t$noListen = \"--noListen `\"true`\"\"\n    $openFirewall = 'false'\n}\n\nif($openFirewall -eq 'true')\n{\n\tWrite-Host \"Creating NSG Rule\"\n\taz network nsg rule create --name \"OctopusTentacle\" --nsg-name $nsgName --priority $nsgRulePriority --resource-group $resourceGroup --direction Inbound --destination-port-ranges $portNumber\n}\n\n$remoteScript = @\"\n`$msiLocation = \"`$env:TEMP\\`$(new-guid).msi\"\n\nif(`$env:PROCESSOR_ARCHITECTURE -eq \"x86\") \n{\n    `$downloadPath = \"http://octopus.com/downloads/latest/OctopusTentacle\"\n}\nelse\n{\n    `$downloadPath = \"http://octopus.com/downloads/latest/OctopusTentacle64\"\n}\n\nInvoke-WebRequest -Uri `$downloadPath -OutFile `$msiLocation -UseBasicParsing\n\nStart-Process `$msiLocation /quiet -Wait\n\nRemove-Item `$msiLocation\n\n\"@\n\nWrite-Host \"Installing tentacle on remote machine\"\n\nSet-Content -Value $remoteScript -Path \".\\script.ps1\"\n\n$result = az vm run-command invoke --command-id RunPowerShellScript --name $vmName -g $resourceGroup --scripts \"@script.ps1\"\n\n$result\n\n$msg = (($result | convertfrom-json).value | where {$_.code -eq \"componentstatus/stderr/succeeded\"}).message\n\nif(![string]::IsNullOrEmpty($msg))\n{\n\tthrow $msg\n}\n\nWrite-Verbose \"hostname: $hostname`noListen: $noListen\"\n\n$remoteScript = @\"\n\ncd \"C:\\Program Files\\Octopus Deploy\\Tentacle\"\n\n.\\Tentacle.exe create-instance --instance \"Tentacle\" --config \"C:\\Octopus\\Tentacle.config\" --console\n.\\Tentacle.exe new-certificate --instance \"Tentacle\" --if-blank --console\n.\\Tentacle.exe configure --instance \"Tentacle\" --reset-trust --console\n.\\Tentacle.exe configure --instance \"Tentacle\" --home \"C:\\Octopus\" --app \"C:\\Octopus\\Applications\" $noListen --console\n.\\Tentacle.exe configure --instance \"Tentacle\" --trust \"$octoThumb\" --console\nif('$openFirewall' -eq 'true'){\n\tNew-NetFirewallRule -DisplayName \"Octopus Tentacle\" -Direction Inbound -LocalPort $portNumber -Protocol TCP -Action Allow\n}\n.\\Tentacle.exe register-with --instance \"Tentacle\" --server \"$serverUri\" --apiKey=$apiKey $roles $environments --comms-style $comStyle --force --console\n.\\Tentacle.exe service --instance \"Tentacle\" --install --start --console\n\n\"@\n\nWrite-Host \"Configuring tentacle on remote machine\"\n\nSet-Content -Value $remoteScript -Path \".\\script.ps1\"\n\n$result = az vm run-command invoke --command-id RunPowerShellScript --name $vmName -g $resourceGroup --scripts \"@script.ps1\"\n\n$result\n\n$msg = (($result | convertfrom-json).value | where {$_.code -eq \"componentstatus/stderr/succeeded\"}).message\n\nif(![string]::IsNullOrEmpty($msg))\n{\n\tthrow $msg\n}\n"
  },
  "Category": "Azure",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/azure-install-windows-tentacle.json",
  "Website": "/step-templates/07b23f27-e76a-4b4b-acb1-017006a83269",
  "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, February 9, 2022