Azure Linux - 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, Linux virtual machine. This will also open the firewall for inbound traffic on port 10933 on the NSG.


*Note: Expects the Azure CLI and Powershell to be installed on the worker running this task*
*Note: Requires dotnet core to be pre-installed on the target machine*
*Note: Firewall ports will not be opened on the remote machine*

Parameters

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

Azure Account

installLinuxTentacle.AzureAccount =

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

Azure Resource Group

installLinuxTentacle.azRgName =

The name of the resource group housing the NSG and VM

NSG Name

installLinuxTentacle.azNsgName =

The name of the azure network security group to create

Azure NSG Rule Priority

installLinuxTentacle.azNsgRulePriority = 400

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

VM Name

installLinuxTentacle.azVmName =

The name of the virtual machine to target when

Server Thumbprint

installLinuxTentacle.octoServerThumb =

The Thumbprint of the octopus server

API Key

installLinuxTentacle.octoApiKey =

The API key used to configure the tentacle.

Roles

installLinuxTentacle.octopusRoles =

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

Environments

installLinuxTentacle.octopusEnvironments =

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

Server Url

installLinuxTentacle.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

installLinuxTentacle.tentacleType = TentaclePassive

Select between a listening or polling tentacle

Tentacle Host Name

installLinuxTentacle.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

installLinuxTentacle.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["installLinuxTentacle.azNsgName"]
$resourceGroup = $OctopusParameters["installLinuxTentacle.azRgName"]
$nsgRulePriority = $OctopusParameters["installLinuxTentacle.azNsgRulePriority"]
$vmName = $OctopusParameters["installLinuxTentacle.azVmName"]
$serverUri = $OctopusParameters["instrallTentacle.octoServerUrl"]
$apiKey = $OctopusParameters["installLinuxTentacle.octoApiKey"]
$rolesRaw = $OctopusParameters["installLinuxTentacle.octopusRoles"]
$enviroRaw = $OctopusParameters["installLinuxTentacle.octopusEnvironments"]
$octoThumb = $OctopusParameters["installLinuxTentacle.octoServerThumb"]
$comStyle = $OctopusParameters["installLinuxTentacle.tentacleType"]
$hostname = $OctopusParameters["installLinuxTentacle.tentacleHostName"]
$portNumber = $OctopusParameters["installLinuxTentacle.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 += "--env $_ "}
$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
}

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

$remoteScript = @"

printf '%s\n' "Test case x failed" >&2
exit 1

configFilePath="/etc/octopus/default/tentacle-default.config"
appPath="/home/Octopus/Applications"

# try curl
{
    curl -L https://octopus.com/downloads/latest/Linux_x64TarGz/OctopusTentacle --output /tmp/tentacle-linux_x64.tar.gz -fsS
} || {
    wget https://octopus.com/downloads/latest/Linux_x64TarGz/OctopusTentacle -O /tmp/tentacle-linux_x64.tar.gz -fsS
}

if [ ! -d "/opt/octopus" ]; then
  mkdir /opt/octopus
fi

tar xvzf /tmp/tentacle-linux_x64.tar.gz -C /opt/octopus
rm /tmp/tentacle-linux_x64.tar.gz

cd /opt/octopus/tentacle

sudo /opt/octopus/tentacle/Tentacle create-instance --config "`$configFilePath"
sudo chmod a+rwx `$configFilePath
/opt/octopus/tentacle/Tentacle new-certificate --if-blank
/opt/octopus/tentacle/Tentacle configure --port $portNumber --noListen False --reset-trust --app "`$appPath"
/opt/octopus/tentacle/Tentacle configure --trust $octoThumb
echo "Registering the Tentacle $name with server $serverUri in environment $environments with role $roles"
/opt/octopus/tentacle/Tentacle register-with --server "$serverUri" --apiKey "$apikey" --name "$name" $environments $roles --comms-style $comStyle --force
sudo /opt/octopus/tentacle/Tentacle service --install --start

"@

Write-Host "Installing tentacle on remote machine"
$scriptGuid = (new-guid).guid
Set-Content -Value $remoteScript -Path ".\$scriptGuid.ps1"

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

$result

$msg = ($result | convertfrom-json).value[0].message

if($msg -match "(?<=\[stderr\]).+")
{
	throw $msg
}

remove-item ".\$scriptGuid.ps1"

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": "2d21abec-491a-4d85-9210-2784bc3dfeb8",
  "Name": "Azure Linux - Install Octopus Tentacle",
  "Description": "This step template will install the latest tentacle on an Azure hosted, Linux virtual machine. This will also open the firewall for inbound traffic on port 10933 on the NSG.\n<hr />\n*Note: Expects the Azure CLI and Powershell to be installed on the worker running this task*<br />\n*Note: Requires dotnet core to be pre-installed on the target machine* <br />\n*Note: Firewall ports will not be opened on the remote machine*",
  "Version": 4,
  "ExportedAt": "2022-02-09T15:56:03.173Z",
  "ActionType": "Octopus.AzurePowerShell",
  "Author": "harrisonmeister",
  "Packages": [],
  "Parameters": [
    {
      "Id": "dea51842-271f-48fa-901e-243488049f97",
      "Name": "installLinuxTentacle.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": "installLinuxTentacle.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": "installLinuxTentacle.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": "installLinuxTentacle.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": "installLinuxTentacle.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": "installLinuxTentacle.octoServerThumb",
      "Label": "Server Thumbprint",
      "HelpText": "The Thumbprint of the octopus server",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "a0859551-6c84-45d1-af2b-c57becb4e8ef",
      "Name": "installLinuxTentacle.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": "installLinuxTentacle.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": "installLinuxTentacle.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": "installLinuxTentacle.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": "installLinuxTentacle.tentacleType",
      "Label": "Tentacle Type",
      "HelpText": "Select between a listening or polling tentacle",
      "DefaultValue": "TentaclePassive",
      "DisplaySettings": {
        "Octopus.ControlType": "Select",
        "Octopus.SelectOptions": "TentaclePassive|Listening\nTentacleActive|Polling"
      }
    },
    {
      "Id": "6bb98570-fe3e-4ab7-adfb-79ef7ce5c2ce",
      "Name": "installLinuxTentacle.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": "1ae37ac0-fc37-447c-941f-7b72ed32a647",
      "Name": "installLinuxTentacle.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": "#{installLinuxTentacle.AzureAccount}",
    "Octopus.Action.Script.ScriptBody": "$nsgName = $OctopusParameters[\"installLinuxTentacle.azNsgName\"]\n$resourceGroup = $OctopusParameters[\"installLinuxTentacle.azRgName\"]\n$nsgRulePriority = $OctopusParameters[\"installLinuxTentacle.azNsgRulePriority\"]\n$vmName = $OctopusParameters[\"installLinuxTentacle.azVmName\"]\n$serverUri = $OctopusParameters[\"instrallTentacle.octoServerUrl\"]\n$apiKey = $OctopusParameters[\"installLinuxTentacle.octoApiKey\"]\n$rolesRaw = $OctopusParameters[\"installLinuxTentacle.octopusRoles\"]\n$enviroRaw = $OctopusParameters[\"installLinuxTentacle.octopusEnvironments\"]\n$octoThumb = $OctopusParameters[\"installLinuxTentacle.octoServerThumb\"]\n$comStyle = $OctopusParameters[\"installLinuxTentacle.tentacleType\"]\n$hostname = $OctopusParameters[\"installLinuxTentacle.tentacleHostName\"]\n$portNumber = $OctopusParameters[\"installLinuxTentacle.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 += \"--env $_ \"}\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\nWrite-Verbose \"hostname: $hostname`noListen: $noListen\"\n\n$remoteScript = @\"\n\nprintf '%s\\n' \"Test case x failed\" >&2\nexit 1\n\nconfigFilePath=\"/etc/octopus/default/tentacle-default.config\"\nappPath=\"/home/Octopus/Applications\"\n\n# try curl\n{\n    curl -L https://octopus.com/downloads/latest/Linux_x64TarGz/OctopusTentacle --output /tmp/tentacle-linux_x64.tar.gz -fsS\n} || {\n    wget https://octopus.com/downloads/latest/Linux_x64TarGz/OctopusTentacle -O /tmp/tentacle-linux_x64.tar.gz -fsS\n}\n\nif [ ! -d \"/opt/octopus\" ]; then\n  mkdir /opt/octopus\nfi\n\ntar xvzf /tmp/tentacle-linux_x64.tar.gz -C /opt/octopus\nrm /tmp/tentacle-linux_x64.tar.gz\n\ncd /opt/octopus/tentacle\n\nsudo /opt/octopus/tentacle/Tentacle create-instance --config \"`$configFilePath\"\nsudo chmod a+rwx `$configFilePath\n/opt/octopus/tentacle/Tentacle new-certificate --if-blank\n/opt/octopus/tentacle/Tentacle configure --port $portNumber --noListen False --reset-trust --app \"`$appPath\"\n/opt/octopus/tentacle/Tentacle configure --trust $octoThumb\necho \"Registering the Tentacle $name with server $serverUri in environment $environments with role $roles\"\n/opt/octopus/tentacle/Tentacle register-with --server \"$serverUri\" --apiKey \"$apikey\" --name \"$name\" $environments $roles --comms-style $comStyle --force\nsudo /opt/octopus/tentacle/Tentacle service --install --start\n\n\"@\n\nWrite-Host \"Installing tentacle on remote machine\"\n$scriptGuid = (new-guid).guid\nSet-Content -Value $remoteScript -Path \".\\$scriptGuid.ps1\"\n\n$result = az vm run-command invoke --command-id RunShellScript --name $vmName -g $resourceGroup --scripts \"@script.ps1\"\n\n$result\n\n$msg = ($result | convertfrom-json).value[0].message\n\nif($msg -match \"(?<=\\[stderr\\]).+\")\n{\n\tthrow $msg\n}\n\nremove-item \".\\$scriptGuid.ps1\"\n"
  },
  "Category": "Azure",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/azure-linux-install-octopus-tentacle.json",
  "Website": "/step-templates/2d21abec-491a-4d85-9210-2784bc3dfeb8",
  "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