23

I have an Azure website with a production and staging slot with multiple instances.

I run several Azure webjobs on the site, some of which are triggered others that are continuous.

I understand triggered webjobs will only run once on one instance.

My current setup is:

  • Production site has no deployment other than swapping from staging

  • Staging website is setup to continuous deployment from bitbucket

  • Webjobs are deployed from within VS to production slot using "publish to Azure" (since AFAIK there is no support for continuous deployment of webjobs that are schedule based)

  • The VS solution for the website is different from the VS solution containing webjobs

I noticed when I swap production and staging, webjobs are also swapped! I realized this when I had deployed a new webjob to production and subsequently did a website deployment followed by a swap, the newly deployed webjob was no longer in the production slot!

My questions:

  1. is it possible to prevent webjobs from swapping between production and staging (webjobs are really entirely different pieces of code than the website)

  2. What exactly is swapped for webjobs? Binaries? Schedule? Both ?

  3. how do i prevent all webjobs from running on the staging slot? My webjobs do not need to be highly available and i can test them offline easily.

  4. If i VS deploy webjobs to the staging slot and do a swap, then the current staging slot will be missing the deployed webjob and I'll lose it when i do my next website update, so where should i be deploying my webjobs?

There is a related thread but it assumes the webjob is deployed simultaneously with a website which is not what I have currently.

I really like websites and webjobs, but it seems the story related to continuous independent deployment of webjobs and websites is broken.

Would really appreciate advice!

Thanks

Community
  • 1
  • 1
Sandeep Phadke
  • 862
  • 9
  • 23

4 Answers4

39

Azure websites deployment slots are not an easy concept to understand, together with WebJobs it gets a little bit more difficult.

I suggest reading the following post to get a better understanding on deployment slots - http://blog.amitapple.com/post/2014/11/azure-websites-slots/ (including the comments section for useful information)

To get a better understanding on how WebJobs work and deployed see this post - http://blog.amitapple.com/post/74215124623/deploy-azure-webjobs/

It is important to understand that:

  1. When swapping deployment slots you actually swap the content/files of the website between the 2 slots.
  2. WebJobs are part of the website content.

So when you swap the slot you actually swap the website files including the WebJob.

Note it is a bad practice to deploy a WebJob directly and not as part of your website files/repository, this is probably the cause of issues you are having.

To prevent WebJobs from running on the staging slot you can add an app setting called WEBJOBS_STOPPED and set it to 1 (in the azure portal). (source). Make sure this app setting is sticky to the slot otherwise it'll propagate to the production slot.

Amit Apple
  • 9,034
  • 41
  • 50
  • Thanks for your response Amit. I didn't know it was `bad` practice to deploy a WebJob directly, Visual Studio Azure integration actually encourages it with a "publish to Azure" button in a WebJob project in VS. It seems at the very least it should not be making it that easy to follow a `bad practice` Is there some place I can provide that feedback to the team? Git deployment was a huge win for me wrt WebJobs vs. CloudServices. This weakens the story a little bit, since it means a website redeployment is necessary to update a WebJob. – Sandeep Phadke Jun 26 '15 at 20:51
  • "publish to Azure" for a WebJob is the same as for a Website, the problematic practice is to mix together git deployment and "publish to Azure" (msdeploy), it is best to use one deployment method. – Amit Apple Jun 26 '15 at 21:56
  • Got it, do you know if i add all my webjobs to the same VS solution as my website (which is git deployed), when I do a commit for a change in a webjob, is it going to redeploy my website even if the only update is to a webjob? What about other webjobs that have not been updated? I worry about how long the deployment will take if its one monolithic solution with all webjobs and a website. – Sandeep Phadke Jun 30 '15 at 20:47
  • It will build the web app and webjobs but only deploy (copy) files that were changed. – Amit Apple Jun 30 '15 at 21:48
  • @AmitApple, I am using the `WEBJOBS_STOPPED` set to `1`, but it doesn't stop the webjobs, they are still running on stage. Do you know if this actually works? Or does it show as running in the portal but doesn't actually run it? – scojomodena Mar 01 '17 at 05:00
  • @scojomodena for issues, try creating one in the github project github.com/projectkudu/kudu – Amit Apple Mar 01 '17 at 21:24
  • Solution worked for me, i set WEBJOBS_STOPPED and staging webjobs stopped without me doing anything else – BobbyTables Jul 07 '17 at 12:54
  • @AmitApple if the continuous webjob `while(true)` is running in the production slot, and then the swap happens, and the prod webjob is now the staging webjob, when does it stop? When does it decide to honor the `WEBJOBS_STOPPED` configuration setting? – Mike Trionfo Oct 04 '17 at 20:19
  • I'm not updated with any recent changes so my answer might be outdated, I assume the webjob just keeps on running but you can also ask the same question in the kudu project in github https://github.com/projectkudu/kudu – Amit Apple Oct 05 '17 at 18:02
6

The by far easiest solution to this problem is to have a separate Web App for your Web Job. Just place the Worker Web App on the same Azure Service Plan and you will have two separate Web Apps running on the same machine(s).

web-app web-app-worker

Niklas Arbin
  • 652
  • 6
  • 14
  • 1
    this is useful if you don't have any/many app settings. Unfortunately for me, I've got about 60. I wouldn't want to have to remember to keep both app settings in sync – viggity Jan 25 '18 at 19:40
  • 1
    Manually setting app settings is a very risky practice, consider automating them using ARM templates. – Niklas Arbin Jan 30 '18 at 10:23
  • For such case I have to maintain Configuration settings in two places. – hiFI Jul 29 '20 at 06:16
1

Here's Amit's answer to #3 using PowerShell,

Function Disable-AzureSlotJobs($SiteName, $Slot = 'staging')
{
    $site = Get-AzureWebsite -Name $SiteName -Slot $Slot
    $site.AppSettings.WEBJOBS_STOPPED = "1"
    Set-AzureWebsite -Name $SiteName -Slot $Slot -AppSettings $site.AppSettings
    Set-AzureWebsite -Name $SiteName -SlotStickyAppSettingNames @("WEBJOBS_STOPPED")
}

'MySite1', 'MySite2', 'MySite3' | % { Disable-AzureSlotJobs $_ }
makhdumi
  • 1,308
  • 11
  • 35
0

My solution is to delete the webjobs from the slots after deployment, before swapping slots and/or starting the app service in the slot:

az webapp webjob continuous remove --webjob-name fooJob --name fooApp --resource-group fooApps --slot fooSlot

Can be done in Azure DevOps Release by adding Azure CLI task with inline powershell script.

Darth Sonic
  • 105
  • 7