Automating Azure App Service Restarts

As the number of resources deployed into our Greenfield Azure tenant continues to rapidly grow, we always strive to be automated as much as possible. One question that kept coming up from developers was the topic of management like restarting app services. Back in the Brownfield days (or as I like to affectionately call it the wild west days!) contributor access was given out on demand so developers would go in and do things on their own without talking to us first.  (It was only when they didn’t have access then they would come knocking on our door.)

Going forward, one of the major goals of Greenfield was to severely restrict access and run everything through pipelines and templates. There was much grumbling at first, but people are starting to come around and beginning to see the advantages of this approach. Without further ado here’s how we implemented the solution.

This is the template structure in our repo enabling reusable code for various things such as management, builds and deployments. (More details on this as a future blog post.)

# restart-app-service-template.yml
parameters:
  - name: environments
    type: object
    default:
      name: ""
      azureSubscription: ""
      resourceGroup: ""
      webApp: ""
      slot: ""
      jobsEnvironmentName: ""

stages:
  - ${{ each app in parameters.environments }}:
      - stage: ${{ app.name }}
        displayName: ${{ app.name }}
        jobs:
          - deployment: Restart_${{ app.name }}
            environment: ${{ app.jobsEnvironmentName }}
            strategy:
              runOnce:
                deploy:
                  steps:
                    - task: AzureAppServiceManage@0
                      displayName: Restart ${{ app.webApp }}
                      inputs:
                        azureSubscription: ${{ app.azureSubscription }}
                        Action: "Restart Azure App Service"
                        ResourceGroupName: ${{ app.resourceGroup }}
                        WebAppName: ${{ app.webApp }}
                        ${{ if app.Slot }}:
                          SpecifySlotOrASE: true
                          Slot: ${{ app.slot }}

Here’s the code for the calling pipeline in the web app repo.

# restart-web-apps.yml
trigger: none

resources:
  repositories:
  - repository: templates # <ADO repo folder> 
    type: git
    name: 'AzureADDemos/SHARED' # <ADO project>/<repo>
    ref: refs/heads/main

stages:
  - template: templates/Management_Templates/restart-app-service-template.yml@templates
    parameters:
      environments:
        - name: "<app environment name>"
          azureSubscription: "<ADO service connection name>"
          resourceGroup: "<resource group name>"
          webApp: "<app service name>"
          jobsEnvironmentName: "<ADO environment>"
          # slot: testslot # Uncomment to simply restart a slot.

Two things worth pointing out here are lines 14 and 18. If you have multiple app services to manage (i.e., environments, clients), each one could be defined as a separate environment. For example, app_web_dev, app_web_qa, app_web_client1_dev, app_web_client2_uat, etc.

But wait, there’s more! We can also use ADO environments (jobsEnvironmentName) for approving pipeline runs that target special environments like production services.

And there we have it! The use of conditions/expressions make this super dynamic, flexible and reusable (hooray!) for our other projects.

Feel free to leave a comment below.

Thanks for reading!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.