CircleCI deploy kestrel asp net core 6 services to Azure Virtual Machine, stuck on SSH and other methods

Marc Hewitt 1 Reputation point
2022-12-16T21:25:24.017+00:00

I am attempting to setup a continuous integration workflow to deploy our built services to an Azure VM. This is what we will be running for several months before moving onto docker/kubernetes. Just trying to get it working at this point and then improving it as we use it.

I'm looking for guidance on 2 things. Just confirmation that I'm headed down a working path (maybe not sane) with the Az Session, or if there is just a much simplier way that I have not seen yet or an easy ssh method online searching has missed. And guidance on how to get dotnet installed at system level as I think I've just stared at it too long and missing something obvious.

My setup:

I have a setup of Circle CI, an Azure VM (running windows 10 pro), and multiple Asp .NETCORE 6 services. Each service has a launcher.ps1 script that simply takes in the $env variables setup on the VM and executes dotnet on the service.dll

The CI builds, and uploads .zip files just fine to azure blob stroage. VM can download and unzip just fine.
If I run the scripts as "myUser" both remote'd into the VM or SSH'd into the VM I can execute my setup logic but on ending SSH I have the services shut down.

To deploy from CI I am using an SSH method from the CircleCI job, with a path to our C:/StartPath/entryPoint.ps1 script that then setups the server (passing in the major/minor/bn version from the CI job - downloads from storage - unzips - and then calls the launcher.) This all works, services launch, but then SSH ends and kills the services.

CI Command:

(circleci config.yaml run:)  
  
ssh -o StrictHostKeyChecking=no -o BatchMode=yes $targetHost "cd C:\StartPath\ && start powershell .\entrypoint.ps1 -appName $appName -version $versionNumber -containerName $containerName"  

Only thing to note is this utilizes a SSH connection pulled from CircleCI secrets. This uses the VM user "myuser" not system level.

As I understand it, my problem with SSH is everything executed in the SSH session is a child-process of that SSH Session, so at the end everything it started gets told to shut down. I've validated this by putting a sleep at the end of the execution to prevent the SSH from ending and I've got asp net logs showing it was operational until around the timestamp of when the SSH closed. I've read a few similar issue posts online and tried some of the suggested tricks to remove the child-process (jobs / script blocks calling script blocks).

The only method online suggested that I have not successfully gotten to work is New-PSSession and Enter-PSSession. I'm about to try the Azure wrapper variant of this with Enter-AzVm as I assume there's some layer of security, I haven't configured around yet and just need to use Enter-AzVm instead of Enter-PSSession.

I have powershell 5 on CircleCI, powershell 5 & 7 on local, and powershell 5 on VM. I can install a new powershell version just preferring minimizing install footprint

I have dotnet installed with the below logic

# dotnet-install.ps1 is a microsoft script we download  
  
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned -Force  
Unblock-File -Path ./dotnet-install.ps1  
  
./dotnet-install.ps1 -Runtime dotnet -Version 6.0.9 -Architecture x64  
./dotnet-install.ps1 -Runtime aspnetcore -Version 6.0.9 -Architecture x64  
  
setx DOTNET_ROOT $HOME\.dotnet /m  
  
$finalPath = $env:PATH + "$HOME\.dotnet\tools;"  
setx PATH $finalPath /m  

/m is a new addition on pathing it works without in SSH, but I added it while trying to get az vm run-command invoke working as the invoke is running System level where I hope the processes stay up but my launching scripts get an error saying dotnet is not recognized

az vm invoke script

az vm run-command invoke --command-id RunPowerShellScript --name $vmName -g $resourceGroup --scripts "cd $path; powershell .\$entryPointScript -appName $appName -version $versionNumber -container $containerName"  
  

Error: "message": "dotnet : The term 'dotnet' is not recognized as the name of a cmdlet, function, script file, or operable program. \nCheck the spelling of the name, or if a path was included, verify that the path is correct and try again.\nAt {servicelauncherpath}.ps1:9 char:1

I've gone and simplified that line to just dotnet --info and it works fine through the user just can't get the machine to locate dotnet even with /M flag. (and I'm not even 100% sure if this azure cli invoke method will solve my issue of child process ending or if at the end of the invoke it'll close the children)

Azure Virtual Machines
Azure Virtual Machines
An Azure service that is used to provision Windows and Linux virtual machines.
9,013 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Marc Hewitt 1 Reputation point
    2022-12-17T00:00:03.627+00:00

    On SSH side I did find an OpenSSH set of bugs to explain how to solve detaching the children processes so the exit does not kill them, I'll have to give it a go on Monday but if there is an easier way with Azure to get a script to execute a Server setup script that runs long lasting new processes without these children .ps1 dying I would love to hear it.

    Link to that OpenSSH explaniation. You basically use Invoke-CimMethod with a certain create flag
    https://github.com/PowerShell/Win32-OpenSSH/issues/1032


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.