Actions

Octopus Deploy

From Ever changing code

Tentacle

Automate Tentacle installation within AWS user data script. Note tf_* variables are injected from Terraform template_file.

  • Part of your script should contain hostname change, then reboot for the next step to use meaning full hostname to register with Octopus Deploy server
  • Creates Schedule task to run on boot that disable itself


$Logfile = "C:\ProgramData\Amazon\EC2-Windows\Launch\Log\UserData.log"
Function LogWrite {
   Param ([string]$logstring)
   $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
   Add-content $Logfile -value "$Stamp $logstring"
}
LogWrite "Start of user_data script **************"

$TentacleRegisterFileContent = @'
$TentaclePath="C:\Program Files\Octopus Deploy\Tentacle"
if (-Not (Test-Path $TentaclePath -pathType container)) { Write-Output "Octopus path not found"; exit 1 }
cd $TentaclePath
.\Tentacle.exe create-instance         --instance $env:computername --config "C:\Octopus\Tentacle.config" --console
.\Tentacle.exe new-certificate         --instance $env:computername --if-blank --console
.\Tentacle.exe configure               --instance $env:computername --reset-trust --console
.\Tentacle.exe configure               --instance $env:computername --home "C:\Octopus" --app "C:\Octopus\Applications" --port "10933" --console
$localthumb=(.\Tentacle.exe show-thumbprint --instance $env:computername --nologo)
.\Tentacle.exe configure               --instance $env:computername --trust $localthumb --console
.\Tentacle.exe configure               --instance $env:computername --trust ${tf_octopus_fingerprint} --console
netsh advfirewall firewall add rule "name=Octopus Deploy Tentacle" dir=in action=allow protocol=TCP localport=10933
$localIP=(Invoke-RestMethod http://169.254.169.254/latest/meta-data/local-ipv4)
.\Tentacle.exe register-with           --instance $env:computername `
   --server "https://octopus.acme.com" --apiKey="${tf_octopus_token}" `
   --role "api" --environment "${tf_octopus_environment}" `
   --comms-style TentaclePassive -h $localIP --force --console
.\Tentacle.exe service                 --instance $env:computername --install --stop --start --console

#Disable scheduled task
#Unregister-ScheduledTask -TaskName "RegisterTentacle" -Confirm:$false
Disable-ScheduledTask -TaskName "RegisterTentacle"
'@

$TentacleRegisterFilePath="C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts"
Set-Content -Path "$TentacleRegisterFilePath\TentacleRegister.ps1" -Value $TentacleRegisterFileContent

$tmpPath="C:\tmp"
If (-Not (Test-Path $tmpPath -pathType container)) { md $tmpPath }
$tentacle_url  = "https://octopus.com/downloads/latest/WindowsX64/OctopusTentacle"
$tentacle_file = "tentacle_install.msi"
(New-Object System.Net.WebClient).DownloadFile("$tentacle_url","$tmpPath\$tentacle_file")
Start-Process msiexec.exe -ArgumentList "/i $tmpPath\$tentacle_file", "/quiet" -Wait

$schAction = New-ScheduledTaskAction `
  -Execute "Powershell.exe" `
  -WorkingDirectory C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts `
  -Argument '-NoProfile -WindowStyle Hidden -NoLogo -NonInteractive -c "powershell .\TentacleRegister.ps1 -verbose >> .\TentacleRegisterScheduleTask.log 2>&1"'

$schTrigger   = New-ScheduledTaskTrigger   -AtStartup
$schPrincipal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest

LogWrite "Octopus Tentacle - register a task"
Register-ScheduledTask -Action $schAction -Trigger $schTrigger -TaskName "RegisterTentacle" -Description "Register OctopusDeploy" -Principal $schPrincipal


Useful commands

get-content -path C:\Octopus\Logs\OctopusTentacle.txt -Wait
.\Tentacle.exe show-configuration
.\Tentacle.exe service --instance $env:computername --stop --start --console #restart, use single action for just eg. stop

#Logs
get-content -path C:\Octopus\Logs\OctopusTentacle.txt -Wait


Register. This will work calling ALB or calling the server behind ALB directly.

$localIP=(Invoke-RestMethod http://169.254.169.254/latest/meta-data/local-ipv4)
.\Tentacle.exe register-with --instance $env:computername `
   --server "https://octopus.acme.com" --apiKey "API-***********" `
   --role "app" --environment "APP-SERVERS-PROD" `
   --comms-style TentaclePassive -h $localIP --force --console


De-register

.\Tentacle.exe deregister-from --instance $env:computername `
   --server "https://octopus.acme.com" `
   --apiKey="API-**********" --console
Detected automation environment: NoneOrUnknown
Deleting machine 'SERVER-1-PROD' from the Octopus Server...
The Octopus Server is still trusted. If you wish to remove trust for this Octopus Server, use 'Tentacle.exe configure --remove-trust=...'
Machine deregistered successfully


Certificate work around when running without a profile eg. Schedule Tasks. It was not needed in my case.

Certificat ework around when running witout a profile eg. Schedule Tasks
.\tentacle.exe new-certificate -e tentacle.crt.base64
.\Tentacle.exe import-certificate --instance $env:computername  -f .\tentacle.crt.base64 --console
Importing the certificate stored in .\tentacle.crt.base64...
Certificate with thumbprint 26********76 imported successfully.

Resources