Wait for step to complete in parallel deployment

We have 3 deployment targets in 1 deployment.
1 with role CM and 2 with role CD
When we deploy we want to deploy 1 CM in Parallel with 1 CD
When the CD is done deploying, the other CD starts deploying.
So it is deploy CM in Parallel with a rolling deployment of the CD.

Now we have an issue that STEP X of CD has to wait for STEP Y to be completed of CM.

We have to take in mind that when we deploy CD, the first step it does is take it out a Azure Traffic manager.
So the 2 CD’s cant be deployed at the same time.

Is there any way to do this?

Hi,

Thanks for getting in touch.

The deploy to CM in parallel with a rolling deploy to CD is easy enough and it sounds like you’ve figured that part out already.

The STEP X of CD waiting for STEP Y of CM would need to be split out so you would have a parallel section, then a sequential section, then back to the parallel section.

Something like this:

If you are taking CD out of the load balancer in CD STEP A and returning it in CD STEP B then I don’t see a way you are going to be able to do this while keeping one of the CD in the load balancer. You can’t interleave steps for CM in the rolling deployment for CD.

An alternative approach that might work is to let CM be a worker. If STEP X is a script step, you could add the step inside the rolling deployment and have it run “On a worker on behalf of CD”. If the script is idempotent (can safely be run again) the it should be ok. The script would run for each of your CD.

For example:

In that illustration: CD will be removed from the load balancer, a script will run on CM, CD is added back to the load balancer.

I hope that’s a bit of help, please let me know if there is anything I can clarify or if you have any questions.

Cheers,
Shane

Hi Shane, thanks for the response.

Option B is the closest to what we need, but this is still not going to works as we hope.
this is a short representation of our deployment process

  1. Install CM
    1.1 Step 1
    1.2 Step 2 => has to wait for step 1.1 to finish
    1.3 Step 3
  2. Install CD
    2.1 Take out load balancer
    2.2 Step 2
    2.3 Step 3 => has to wait for STEP 1.2 to finish
    2.3 put back into load balancer

Little side note, the install CM, takes arrount 1:45:00 hours
And each CD takes arrount 1 hour.
So we really want to keep them running in parrallel.

Hi,

I can’t think of a way to do that using deployment processes, there currently isn’t a way to model it in Octopus. You would need to implement your own blocking mechanism in step 2.3 to poll for the result of step 1.2.

Cheers,
Shane

I was thinking of using a varibale to store if a specific step has been run.
But apparently this doesn’t reload while the writing step and reading step is running in parrallel.
In this way
In the write step
Set-OctopusVariable -name “HasRun” -value “true”

In the read step
write-host $OctopusParameters[“Octopus.Action[sleep].Output.HasRun”]

Another option can be to create a file at start of deployment
After the required step its deleted
And we have a polling step that checks if that files still exists
Is this an option?

Hi,

Yes, I was thinking an output variable would be useful but as you mentioned the variables are set when the step starts to run and are not refreshed.

You could use a file lock, or perhaps a named semaphore? Either method would require the code to be execute on the same machine, so you could use a “Run on server” or “Run on worker” script. Your PowerShell scripts for a semaphore might look like:

Acquire semaphore at the start of the deployment:

$semaphore = New-Object System.Threading.Semaphore(1, 1, "Step 1.2")

while (!$semaphore.WaitOne(100)) {
    Write-Host "Release lock so it can be acquired"
    $semaphore.Release();
}
Write-Host "Lock acquired!"

Waiting on the semaphore before step 2.3:

$semaphore = New-Object System.Threading.Semaphore(1, 1, "Step 1.2")

while (!$semaphore.WaitOne(5000)) {
    Write-Host "Waiting for step 1.2 to finish"
}
Write-Host "Lock acquired!"

Releasing the semaphore, this should be done after step 1.2 and 2.3:

$semaphore = New-Object System.Threading.Semaphore(1, 1, "Step 1.2")

$semaphore.Release();
$semaphore.Close();

Hope this helps.

Cheers,
Shane

Thanks for the help.
We discussed both proposals and went with the lock file proposal.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.