Dogs Chasing Squirrels

A software development blog

Starting and Stopping Azure Web Apps with a DevOps pipeline

0

We’re using Azure web services for our dev and test environments. Since we only use these environments during the day, I wanted to write some automated functions to turn them off at night and turn them back on in the morning. It can be done with Azure Functions, but I thought it would be easier to build into an Azure Pipeline where developers are all doing their work anyway, so if someone needed to work after hours they would know how to get at it.

First is the PowerShell script to start or stop a service, based on this post.

# This controls an app service.
Param(
    # The tenant ID
    [Parameter(Mandatory=$true)][string] $TenantId,
    # The subscription ID
    [Parameter(Mandatory=$true)] [string] $SubscriptionId,
    # The App Registration client ID
    [Parameter(Mandatory=$true)][string] $ClientId,
    # The App Registration client secret
    [Parameter(Mandatory=$true)][string] $ClientSecret,
    # The resource group of the service to control
    [Parameter(Mandatory=$true)][string] $ResourceGroup,
    # The name of the service to control
    [Parameter(Mandatory=$true)][string] $AppService,
    # The switch if we want to start
    [switch] $Start = $false,
    # The switch if we want to start
    [switch] $Stop = $false
)

$StartOrStop = ""
if ( $Start ) {
    $StartOrStop = "start"
}
if ( $Stop ) {
    $StartOrStop = "stop"
}

# Get the authentication token
$Auth = Invoke-RestMethod `
 -Uri "https://login.microsoftonline.com/$TenantId/oauth2/token?api-version=1.0" `
 -Method Post `
 -Body @{"grant_type" = "client_credentials"; `
 "resource" = "https://management.core.windows.net/"; `
 "client_id" = "$ClientId"; `
 "client_secret" = "$ClientSecret"}

$HeaderValue = "Bearer " + $Auth.access_token

# Control the service
Write-Output "Executing $AppService $StartOrStop..."
Invoke-RestMethod `
-Uri "https://management.azure.com/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Web/sites/$AppService/$StartOrStop`?api-version=2018-02-01" `
-Method Post `
-Headers @{Authorization = $HeaderValue}   
Write-Output "Done $Command $AppService"

Then there's the pipeline yaml to run the script. This is the "Start" version. I'll leave "Stop" as an exercise for the reader.

name: $(Date:yyyyMMdd)-$(Rev:r)
jobs:
  - job: "Build"
    pool:
      vmImage: 'windows-2019'
    variables:
      tenantId: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
      subscriptionId: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
      clientId: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
      # Note: clientSecret set in Azure Pipeline
      resourceGroup: 'MY_RESOURCE_GROUP'
      appService: 'MY_APP_SERVICE'
    steps:
      - task: PowerShell@2
        displayName: 'Start $(appService)'
        inputs:
          errorActionPreference: Stop
          targetType: filePath
          filePath: '$(Build.SourcesDirectory)\ControlAppService.ps1'
          arguments: '-Start -AppService $(appService) -TenantId $(tenantId) -SubscriptionId $(subscriptionId) -ClientId $(clientId) -ClientSecret $(clientSecret) -ResourceGroup $(resourceGroup)'

I have the clientSecret set up in the Azure Pipeline’s variables as a secret value.

That’s pretty much it. The pipelines are set to run on a timer: Stop at 7pm; Start at 7am.

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

%d bloggers like this: